1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_SSE5_ASHIFT 154)
186 (UNSPEC_SSE5_LSHIFT 155)
188 (UNSPEC_CVTPH2PS 157)
189 (UNSPEC_CVTPS2PH 158)
193 [(UNSPECV_BLOCKAGE 0)
194 (UNSPECV_STACK_PROBE 1)
203 (UNSPECV_CMPXCHG_1 10)
204 (UNSPECV_CMPXCHG_2 11)
207 (UNSPECV_PROLOGUE_USE 14)
210 ;; Constants to represent pcomtrue/pcomfalse variants
220 ;; Registers by name.
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first. This allows for better optimization. For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
245 ;; Processor type. This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248 nocona,core2,generic32,generic64,amdfam10"
249 (const (symbol_ref "ix86_tune")))
251 ;; A basic instruction type. Refinements due to arguments to be
252 ;; provided in other attributes.
255 alu,alu1,negnot,imov,imovx,lea,
256 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257 icmp,test,ibr,setcc,icmov,
258 push,pop,call,callv,leave,
260 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
264 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265 (const_string "other"))
267 ;; Main data type used by the insn
269 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270 (const_string "unknown"))
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275 (const_string "i387")
276 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
280 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
282 (eq_attr "type" "other")
283 (const_string "unknown")]
284 (const_string "integer")))
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
291 (eq_attr "unit" "i387,sse,mmx")
293 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
295 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296 (eq_attr "type" "imov,test")
297 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298 (eq_attr "type" "call")
299 (if_then_else (match_operand 0 "constant_call_address_operand" "")
302 (eq_attr "type" "callv")
303 (if_then_else (match_operand 1 "constant_call_address_operand" "")
306 ;; We don't know the size before shorten_branches. Expect
307 ;; the instruction to fit for better scheduling.
308 (eq_attr "type" "ibr")
311 (symbol_ref "/* Update immediate_length and other attributes! */
312 gcc_unreachable (),1")))
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316 (cond [(eq_attr "type" "str,other,multi,fxch")
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
325 (symbol_ref "ix86_attr_length_address_default (insn)")))
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329 (if_then_else (ior (eq_attr "mode" "HI")
330 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
343 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344 (eq_attr "unit" "sse,mmx"))
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350 (cond [(and (eq_attr "mode" "DI")
351 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
353 (and (eq_attr "mode" "QI")
354 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
357 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368 (cond [(eq_attr "type" "str,leave")
370 (eq_attr "unit" "i387")
372 (and (eq_attr "type" "incdec")
373 (ior (match_operand:SI 1 "register_operand" "")
374 (match_operand:HI 1 "register_operand" "")))
376 (and (eq_attr "type" "push")
377 (not (match_operand 1 "memory_operand" "")))
379 (and (eq_attr "type" "pop")
380 (not (match_operand 0 "memory_operand" "")))
382 (and (eq_attr "type" "imov")
383 (ior (and (match_operand 0 "register_operand" "")
384 (match_operand 1 "immediate_operand" ""))
385 (ior (and (match_operand 0 "ax_reg_operand" "")
386 (match_operand 1 "memory_displacement_only_operand" ""))
387 (and (match_operand 0 "memory_displacement_only_operand" "")
388 (match_operand 1 "ax_reg_operand" "")))))
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
403 (define_attr "length" ""
404 (cond [(eq_attr "type" "other,multi,fistp,frndint")
406 (eq_attr "type" "fcmp")
408 (eq_attr "unit" "i387")
410 (plus (attr "prefix_data16")
411 (attr "length_address")))]
412 (plus (plus (attr "modrm")
413 (plus (attr "prefix_0f")
414 (plus (attr "prefix_rex")
415 (plus (attr "prefix_extra")
417 (plus (attr "prefix_rep")
418 (plus (attr "prefix_data16")
419 (plus (attr "length_immediate")
420 (attr "length_address")))))))
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
426 (define_attr "memory" "none,load,store,both,unknown"
427 (cond [(eq_attr "type" "other,multi,str")
428 (const_string "unknown")
429 (eq_attr "type" "lea,fcmov,fpspc")
430 (const_string "none")
431 (eq_attr "type" "fistp,leave")
432 (const_string "both")
433 (eq_attr "type" "frndint")
434 (const_string "load")
435 (eq_attr "type" "push")
436 (if_then_else (match_operand 1 "memory_operand" "")
437 (const_string "both")
438 (const_string "store"))
439 (eq_attr "type" "pop")
440 (if_then_else (match_operand 0 "memory_operand" "")
441 (const_string "both")
442 (const_string "load"))
443 (eq_attr "type" "setcc")
444 (if_then_else (match_operand 0 "memory_operand" "")
445 (const_string "store")
446 (const_string "none"))
447 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448 (if_then_else (ior (match_operand 0 "memory_operand" "")
449 (match_operand 1 "memory_operand" ""))
450 (const_string "load")
451 (const_string "none"))
452 (eq_attr "type" "ibr")
453 (if_then_else (match_operand 0 "memory_operand" "")
454 (const_string "load")
455 (const_string "none"))
456 (eq_attr "type" "call")
457 (if_then_else (match_operand 0 "constant_call_address_operand" "")
458 (const_string "none")
459 (const_string "load"))
460 (eq_attr "type" "callv")
461 (if_then_else (match_operand 1 "constant_call_address_operand" "")
462 (const_string "none")
463 (const_string "load"))
464 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465 (match_operand 1 "memory_operand" ""))
466 (const_string "both")
467 (and (match_operand 0 "memory_operand" "")
468 (match_operand 1 "memory_operand" ""))
469 (const_string "both")
470 (match_operand 0 "memory_operand" "")
471 (const_string "store")
472 (match_operand 1 "memory_operand" "")
473 (const_string "load")
475 "!alu1,negnot,ishift1,
476 imov,imovx,icmp,test,bitmanip,
478 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480 (match_operand 2 "memory_operand" ""))
481 (const_string "load")
482 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483 (match_operand 3 "memory_operand" ""))
484 (const_string "load")
486 (const_string "none")))
488 ;; Indicates if an instruction has both an immediate and a displacement.
490 (define_attr "imm_disp" "false,true,unknown"
491 (cond [(eq_attr "type" "other,multi")
492 (const_string "unknown")
493 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494 (and (match_operand 0 "memory_displacement_operand" "")
495 (match_operand 1 "immediate_operand" "")))
496 (const_string "true")
497 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498 (and (match_operand 0 "memory_displacement_operand" "")
499 (match_operand 2 "immediate_operand" "")))
500 (const_string "true")
502 (const_string "false")))
504 ;; Indicates if an FP operation has an integer source.
506 (define_attr "fp_int_src" "false,true"
507 (const_string "false"))
509 ;; Defines rounding mode of an FP operation.
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512 (const_string "any"))
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516 [(set_attr "length" "128")
517 (set_attr "type" "multi")])
519 (define_code_iterator plusminus [plus minus])
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541 [(QI "general_operand")
542 (HI "general_operand")
543 (SI "general_operand")
544 (DI "x86_64_general_operand")])
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
568 ;; Scheduling descriptions
570 (include "pentium.md")
573 (include "athlon.md")
577 ;; Operand and operator predicates and constraints
579 (include "predicates.md")
580 (include "constraints.md")
583 ;; Compare instructions.
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
589 (define_expand "cmpti"
590 [(set (reg:CC FLAGS_REG)
591 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592 (match_operand:TI 1 "x86_64_general_operand" "")))]
595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
596 operands[0] = force_reg (TImode, operands[0]);
597 ix86_compare_op0 = operands[0];
598 ix86_compare_op1 = operands[1];
602 (define_expand "cmpdi"
603 [(set (reg:CC FLAGS_REG)
604 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605 (match_operand:DI 1 "x86_64_general_operand" "")))]
608 if (MEM_P (operands[0]) && MEM_P (operands[1]))
609 operands[0] = force_reg (DImode, operands[0]);
610 ix86_compare_op0 = operands[0];
611 ix86_compare_op1 = operands[1];
615 (define_expand "cmpsi"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618 (match_operand:SI 1 "general_operand" "")))]
621 if (MEM_P (operands[0]) && MEM_P (operands[1]))
622 operands[0] = force_reg (SImode, operands[0]);
623 ix86_compare_op0 = operands[0];
624 ix86_compare_op1 = operands[1];
628 (define_expand "cmphi"
629 [(set (reg:CC FLAGS_REG)
630 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631 (match_operand:HI 1 "general_operand" "")))]
634 if (MEM_P (operands[0]) && MEM_P (operands[1]))
635 operands[0] = force_reg (HImode, operands[0]);
636 ix86_compare_op0 = operands[0];
637 ix86_compare_op1 = operands[1];
641 (define_expand "cmpqi"
642 [(set (reg:CC FLAGS_REG)
643 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644 (match_operand:QI 1 "general_operand" "")))]
647 if (MEM_P (operands[0]) && MEM_P (operands[1]))
648 operands[0] = force_reg (QImode, operands[0]);
649 ix86_compare_op0 = operands[0];
650 ix86_compare_op1 = operands[1];
654 (define_insn "cmpdi_ccno_1_rex64"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657 (match_operand:DI 1 "const0_operand" "n,n")))]
658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
661 cmp{q}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "test,icmp")
663 (set_attr "length_immediate" "0,1")
664 (set_attr "mode" "DI")])
666 (define_insn "*cmpdi_minus_1_rex64"
667 [(set (reg FLAGS_REG)
668 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672 "cmp{q}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "DI")])
676 (define_expand "cmpdi_1_rex64"
677 [(set (reg:CC FLAGS_REG)
678 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679 (match_operand:DI 1 "general_operand" "")))]
683 (define_insn "cmpdi_1_insn_rex64"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{q}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "DI")])
693 (define_insn "*cmpsi_ccno_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696 (match_operand:SI 1 "const0_operand" "n,n")))]
697 "ix86_match_ccmode (insn, CCNOmode)"
700 cmp{l}\t{%1, %0|%0, %1}"
701 [(set_attr "type" "test,icmp")
702 (set_attr "length_immediate" "0,1")
703 (set_attr "mode" "SI")])
705 (define_insn "*cmpsi_minus_1"
706 [(set (reg FLAGS_REG)
707 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708 (match_operand:SI 1 "general_operand" "ri,mr"))
710 "ix86_match_ccmode (insn, CCGOCmode)"
711 "cmp{l}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "icmp")
713 (set_attr "mode" "SI")])
715 (define_expand "cmpsi_1"
716 [(set (reg:CC FLAGS_REG)
717 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718 (match_operand:SI 1 "general_operand" "")))]
722 (define_insn "*cmpsi_1_insn"
723 [(set (reg FLAGS_REG)
724 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725 (match_operand:SI 1 "general_operand" "ri,mr")))]
726 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727 && ix86_match_ccmode (insn, CCmode)"
728 "cmp{l}\t{%1, %0|%0, %1}"
729 [(set_attr "type" "icmp")
730 (set_attr "mode" "SI")])
732 (define_insn "*cmphi_ccno_1"
733 [(set (reg FLAGS_REG)
734 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735 (match_operand:HI 1 "const0_operand" "n,n")))]
736 "ix86_match_ccmode (insn, CCNOmode)"
739 cmp{w}\t{%1, %0|%0, %1}"
740 [(set_attr "type" "test,icmp")
741 (set_attr "length_immediate" "0,1")
742 (set_attr "mode" "HI")])
744 (define_insn "*cmphi_minus_1"
745 [(set (reg FLAGS_REG)
746 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747 (match_operand:HI 1 "general_operand" "ri,mr"))
749 "ix86_match_ccmode (insn, CCGOCmode)"
750 "cmp{w}\t{%1, %0|%0, %1}"
751 [(set_attr "type" "icmp")
752 (set_attr "mode" "HI")])
754 (define_insn "*cmphi_1"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757 (match_operand:HI 1 "general_operand" "ri,mr")))]
758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759 && ix86_match_ccmode (insn, CCmode)"
760 "cmp{w}\t{%1, %0|%0, %1}"
761 [(set_attr "type" "icmp")
762 (set_attr "mode" "HI")])
764 (define_insn "*cmpqi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767 (match_operand:QI 1 "const0_operand" "n,n")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
771 cmp{b}\t{$0, %0|%0, 0}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "QI")])
776 (define_insn "*cmpqi_1"
777 [(set (reg FLAGS_REG)
778 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779 (match_operand:QI 1 "general_operand" "qi,mq")))]
780 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781 && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
786 (define_insn "*cmpqi_minus_1"
787 [(set (reg FLAGS_REG)
788 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789 (match_operand:QI 1 "general_operand" "qi,mq"))
791 "ix86_match_ccmode (insn, CCGOCmode)"
792 "cmp{b}\t{%1, %0|%0, %1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_1"
797 [(set (reg FLAGS_REG)
799 (match_operand:QI 0 "general_operand" "Qm")
802 (match_operand 1 "ext_register_operand" "Q")
805 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806 "cmp{b}\t{%h1, %0|%0, %h1}"
807 [(set_attr "type" "icmp")
808 (set_attr "mode" "QI")])
810 (define_insn "*cmpqi_ext_1_rex64"
811 [(set (reg FLAGS_REG)
813 (match_operand:QI 0 "register_operand" "Q")
816 (match_operand 1 "ext_register_operand" "Q")
819 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820 "cmp{b}\t{%h1, %0|%0, %h1}"
821 [(set_attr "type" "icmp")
822 (set_attr "mode" "QI")])
824 (define_insn "*cmpqi_ext_2"
825 [(set (reg FLAGS_REG)
829 (match_operand 0 "ext_register_operand" "Q")
832 (match_operand:QI 1 "const0_operand" "n")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
835 [(set_attr "type" "test")
836 (set_attr "length_immediate" "0")
837 (set_attr "mode" "QI")])
839 (define_expand "cmpqi_ext_3"
840 [(set (reg:CC FLAGS_REG)
844 (match_operand 0 "ext_register_operand" "")
847 (match_operand:QI 1 "general_operand" "")))]
851 (define_insn "cmpqi_ext_3_insn"
852 [(set (reg FLAGS_REG)
856 (match_operand 0 "ext_register_operand" "Q")
859 (match_operand:QI 1 "general_operand" "Qmn")))]
860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861 "cmp{b}\t{%1, %h0|%h0, %1}"
862 [(set_attr "type" "icmp")
863 (set_attr "mode" "QI")])
865 (define_insn "cmpqi_ext_3_insn_rex64"
866 [(set (reg FLAGS_REG)
870 (match_operand 0 "ext_register_operand" "Q")
873 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875 "cmp{b}\t{%1, %h0|%h0, %1}"
876 [(set_attr "type" "icmp")
877 (set_attr "mode" "QI")])
879 (define_insn "*cmpqi_ext_4"
880 [(set (reg FLAGS_REG)
884 (match_operand 0 "ext_register_operand" "Q")
889 (match_operand 1 "ext_register_operand" "Q")
892 "ix86_match_ccmode (insn, CCmode)"
893 "cmp{b}\t{%h1, %h0|%h0, %h1}"
894 [(set_attr "type" "icmp")
895 (set_attr "mode" "QI")])
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares. Which is what
900 ;; the old patterns did, but with many more of them.
902 (define_expand "cmpxf"
903 [(set (reg:CC FLAGS_REG)
904 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905 (match_operand:XF 1 "nonmemory_operand" "")))]
908 ix86_compare_op0 = operands[0];
909 ix86_compare_op1 = operands[1];
913 (define_expand "cmp<mode>"
914 [(set (reg:CC FLAGS_REG)
915 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
919 ix86_compare_op0 = operands[0];
920 ix86_compare_op1 = operands[1];
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
927 ;; CCFPmode compare with exceptions
928 ;; CCFPUmode compare with no exceptions
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
933 (define_insn "*cmpfp_0"
934 [(set (match_operand:HI 0 "register_operand" "=a")
937 (match_operand 1 "register_operand" "f")
938 (match_operand 2 "const0_operand" "X"))]
940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942 "* return output_fp_compare (insn, operands, 0, 0);"
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
946 (cond [(match_operand:SF 1 "" "")
948 (match_operand:DF 1 "" "")
951 (const_string "XF")))])
953 (define_insn_and_split "*cmpfp_0_cc"
954 [(set (reg:CCFP FLAGS_REG)
956 (match_operand 1 "register_operand" "f")
957 (match_operand 2 "const0_operand" "X")))
958 (clobber (match_operand:HI 0 "register_operand" "=a"))]
959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960 && TARGET_SAHF && !TARGET_CMOVE
961 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
963 "&& reload_completed"
966 [(compare:CCFP (match_dup 1)(match_dup 2))]
968 (set (reg:CC FLAGS_REG)
969 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
971 [(set_attr "type" "multi")
972 (set_attr "unit" "i387")
974 (cond [(match_operand:SF 1 "" "")
976 (match_operand:DF 1 "" "")
979 (const_string "XF")))])
981 (define_insn "*cmpfp_xf"
982 [(set (match_operand:HI 0 "register_operand" "=a")
985 (match_operand:XF 1 "register_operand" "f")
986 (match_operand:XF 2 "register_operand" "f"))]
989 "* return output_fp_compare (insn, operands, 0, 0);"
990 [(set_attr "type" "multi")
991 (set_attr "unit" "i387")
992 (set_attr "mode" "XF")])
994 (define_insn_and_split "*cmpfp_xf_cc"
995 [(set (reg:CCFP FLAGS_REG)
997 (match_operand:XF 1 "register_operand" "f")
998 (match_operand:XF 2 "register_operand" "f")))
999 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1001 && TARGET_SAHF && !TARGET_CMOVE"
1003 "&& reload_completed"
1006 [(compare:CCFP (match_dup 1)(match_dup 2))]
1008 (set (reg:CC FLAGS_REG)
1009 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1011 [(set_attr "type" "multi")
1012 (set_attr "unit" "i387")
1013 (set_attr "mode" "XF")])
1015 (define_insn "*cmpfp_<mode>"
1016 [(set (match_operand:HI 0 "register_operand" "=a")
1019 (match_operand:MODEF 1 "register_operand" "f")
1020 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1023 "* return output_fp_compare (insn, operands, 0, 0);"
1024 [(set_attr "type" "multi")
1025 (set_attr "unit" "i387")
1026 (set_attr "mode" "<MODE>")])
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029 [(set (reg:CCFP FLAGS_REG)
1031 (match_operand:MODEF 1 "register_operand" "f")
1032 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1035 && TARGET_SAHF && !TARGET_CMOVE"
1037 "&& reload_completed"
1040 [(compare:CCFP (match_dup 1)(match_dup 2))]
1042 (set (reg:CC FLAGS_REG)
1043 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1045 [(set_attr "type" "multi")
1046 (set_attr "unit" "i387")
1047 (set_attr "mode" "<MODE>")])
1049 (define_insn "*cmpfp_u"
1050 [(set (match_operand:HI 0 "register_operand" "=a")
1053 (match_operand 1 "register_operand" "f")
1054 (match_operand 2 "register_operand" "f"))]
1056 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058 "* return output_fp_compare (insn, operands, 0, 1);"
1059 [(set_attr "type" "multi")
1060 (set_attr "unit" "i387")
1062 (cond [(match_operand:SF 1 "" "")
1064 (match_operand:DF 1 "" "")
1067 (const_string "XF")))])
1069 (define_insn_and_split "*cmpfp_u_cc"
1070 [(set (reg:CCFPU FLAGS_REG)
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "register_operand" "f")))
1074 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && TARGET_SAHF && !TARGET_CMOVE
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1079 "&& reload_completed"
1082 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1084 (set (reg:CC FLAGS_REG)
1085 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1087 [(set_attr "type" "multi")
1088 (set_attr "unit" "i387")
1090 (cond [(match_operand:SF 1 "" "")
1092 (match_operand:DF 1 "" "")
1095 (const_string "XF")))])
1097 (define_insn "*cmpfp_<mode>"
1098 [(set (match_operand:HI 0 "register_operand" "=a")
1101 (match_operand 1 "register_operand" "f")
1102 (match_operator 3 "float_operator"
1103 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1105 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106 && TARGET_USE_<MODE>MODE_FIOP
1107 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108 "* return output_fp_compare (insn, operands, 0, 0);"
1109 [(set_attr "type" "multi")
1110 (set_attr "unit" "i387")
1111 (set_attr "fp_int_src" "true")
1112 (set_attr "mode" "<MODE>")])
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115 [(set (reg:CCFP FLAGS_REG)
1117 (match_operand 1 "register_operand" "f")
1118 (match_operator 3 "float_operator"
1119 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && TARGET_SAHF && !TARGET_CMOVE
1123 && TARGET_USE_<MODE>MODE_FIOP
1124 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1126 "&& reload_completed"
1131 (match_op_dup 3 [(match_dup 2)]))]
1133 (set (reg:CC FLAGS_REG)
1134 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1136 [(set_attr "type" "multi")
1137 (set_attr "unit" "i387")
1138 (set_attr "fp_int_src" "true")
1139 (set_attr "mode" "<MODE>")])
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1144 (define_insn "x86_fnstsw_1"
1145 [(set (match_operand:HI 0 "register_operand" "=a")
1146 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1149 [(set_attr "length" "2")
1150 (set_attr "mode" "SI")
1151 (set_attr "unit" "i387")])
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1156 (define_insn "x86_sahf_1"
1157 [(set (reg:CC FLAGS_REG)
1158 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1162 #ifdef HAVE_AS_IX86_SAHF
1165 return ".byte\t0x9e";
1168 [(set_attr "length" "1")
1169 (set_attr "athlon_decode" "vector")
1170 (set_attr "amdfam10_decode" "direct")
1171 (set_attr "mode" "SI")])
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176 [(set (reg:CCFP FLAGS_REG)
1177 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179 "TARGET_MIX_SSE_I387
1180 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182 "* return output_fp_compare (insn, operands, 1, 0);"
1183 [(set_attr "type" "fcmp,ssecomi")
1185 (if_then_else (match_operand:SF 1 "" "")
1187 (const_string "DF")))
1188 (set_attr "athlon_decode" "vector")
1189 (set_attr "amdfam10_decode" "direct")])
1191 (define_insn "*cmpfp_i_sse"
1192 [(set (reg:CCFP FLAGS_REG)
1193 (compare:CCFP (match_operand 0 "register_operand" "x")
1194 (match_operand 1 "nonimmediate_operand" "xm")))]
1196 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198 "* return output_fp_compare (insn, operands, 1, 0);"
1199 [(set_attr "type" "ssecomi")
1201 (if_then_else (match_operand:SF 1 "" "")
1203 (const_string "DF")))
1204 (set_attr "athlon_decode" "vector")
1205 (set_attr "amdfam10_decode" "direct")])
1207 (define_insn "*cmpfp_i_i387"
1208 [(set (reg:CCFP FLAGS_REG)
1209 (compare:CCFP (match_operand 0 "register_operand" "f")
1210 (match_operand 1 "register_operand" "f")))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1213 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215 "* return output_fp_compare (insn, operands, 1, 0);"
1216 [(set_attr "type" "fcmp")
1218 (cond [(match_operand:SF 1 "" "")
1220 (match_operand:DF 1 "" "")
1223 (const_string "XF")))
1224 (set_attr "athlon_decode" "vector")
1225 (set_attr "amdfam10_decode" "direct")])
1227 (define_insn "*cmpfp_iu_mixed"
1228 [(set (reg:CCFPU FLAGS_REG)
1229 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231 "TARGET_MIX_SSE_I387
1232 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 1);"
1235 [(set_attr "type" "fcmp,ssecomi")
1237 (if_then_else (match_operand:SF 1 "" "")
1239 (const_string "DF")))
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")])
1243 (define_insn "*cmpfp_iu_sse"
1244 [(set (reg:CCFPU FLAGS_REG)
1245 (compare:CCFPU (match_operand 0 "register_operand" "x")
1246 (match_operand 1 "nonimmediate_operand" "xm")))]
1248 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250 "* return output_fp_compare (insn, operands, 1, 1);"
1251 [(set_attr "type" "ssecomi")
1253 (if_then_else (match_operand:SF 1 "" "")
1255 (const_string "DF")))
1256 (set_attr "athlon_decode" "vector")
1257 (set_attr "amdfam10_decode" "direct")])
1259 (define_insn "*cmpfp_iu_387"
1260 [(set (reg:CCFPU FLAGS_REG)
1261 (compare:CCFPU (match_operand 0 "register_operand" "f")
1262 (match_operand 1 "register_operand" "f")))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1265 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267 "* return output_fp_compare (insn, operands, 1, 1);"
1268 [(set_attr "type" "fcmp")
1270 (cond [(match_operand:SF 1 "" "")
1272 (match_operand:DF 1 "" "")
1275 (const_string "XF")))
1276 (set_attr "athlon_decode" "vector")
1277 (set_attr "amdfam10_decode" "direct")])
1279 ;; Move instructions.
1281 ;; General case of fullword move.
1283 (define_expand "movsi"
1284 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285 (match_operand:SI 1 "general_operand" ""))]
1287 "ix86_expand_move (SImode, operands); DONE;")
1289 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1298 (define_insn "*pushsi2"
1299 [(set (match_operand:SI 0 "push_operand" "=<")
1300 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1303 [(set_attr "type" "push")
1304 (set_attr "mode" "SI")])
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308 [(set (match_operand:SI 0 "push_operand" "=X")
1309 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1312 [(set_attr "type" "push")
1313 (set_attr "mode" "SI")])
1315 (define_insn "*pushsi2_prologue"
1316 [(set (match_operand:SI 0 "push_operand" "=<")
1317 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318 (clobber (mem:BLK (scratch)))]
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1324 (define_insn "*popsi1_epilogue"
1325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326 (mem:SI (reg:SI SP_REG)))
1327 (set (reg:SI SP_REG)
1328 (plus:SI (reg:SI SP_REG) (const_int 4)))
1329 (clobber (mem:BLK (scratch)))]
1332 [(set_attr "type" "pop")
1333 (set_attr "mode" "SI")])
1335 (define_insn "popsi1"
1336 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337 (mem:SI (reg:SI SP_REG)))
1338 (set (reg:SI SP_REG)
1339 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1342 [(set_attr "type" "pop")
1343 (set_attr "mode" "SI")])
1345 (define_insn "*movsi_xor"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (match_operand:SI 1 "const0_operand" "i"))
1348 (clobber (reg:CC FLAGS_REG))]
1349 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1351 [(set_attr "type" "alu1")
1352 (set_attr "mode" "SI")
1353 (set_attr "length_immediate" "0")])
1355 (define_insn "*movsi_or"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (match_operand:SI 1 "immediate_operand" "i"))
1358 (clobber (reg:CC FLAGS_REG))]
1360 && operands[1] == constm1_rtx
1361 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1363 operands[1] = constm1_rtx;
1364 return "or{l}\t{%1, %0|%0, %1}";
1366 [(set_attr "type" "alu1")
1367 (set_attr "mode" "SI")
1368 (set_attr "length_immediate" "1")])
1370 (define_insn "*movsi_1"
1371 [(set (match_operand:SI 0 "nonimmediate_operand"
1372 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373 (match_operand:SI 1 "general_operand"
1374 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1375 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1377 switch (get_attr_type (insn))
1380 if (get_attr_mode (insn) == MODE_TI)
1381 return "pxor\t%0, %0";
1382 return "xorps\t%0, %0";
1385 switch (get_attr_mode (insn))
1388 return "movdqa\t{%1, %0|%0, %1}";
1390 return "movaps\t{%1, %0|%0, %1}";
1392 return "movd\t{%1, %0|%0, %1}";
1394 return "movss\t{%1, %0|%0, %1}";
1400 return "pxor\t%0, %0";
1403 if (get_attr_mode (insn) == MODE_DI)
1404 return "movq\t{%1, %0|%0, %1}";
1405 return "movd\t{%1, %0|%0, %1}";
1408 return "lea{l}\t{%1, %0|%0, %1}";
1411 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412 return "mov{l}\t{%1, %0|%0, %1}";
1416 (cond [(eq_attr "alternative" "2")
1417 (const_string "mmxadd")
1418 (eq_attr "alternative" "3,4,5")
1419 (const_string "mmxmov")
1420 (eq_attr "alternative" "6")
1421 (const_string "sselog1")
1422 (eq_attr "alternative" "7,8,9,10,11")
1423 (const_string "ssemov")
1424 (match_operand:DI 1 "pic_32bit_operand" "")
1425 (const_string "lea")
1427 (const_string "imov")))
1429 (cond [(eq_attr "alternative" "2,3")
1431 (eq_attr "alternative" "6,7")
1433 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434 (const_string "V4SF")
1435 (const_string "TI"))
1436 (and (eq_attr "alternative" "8,9,10,11")
1437 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1440 (const_string "SI")))])
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1450 movabs{l}\t{%1, %P0|%P0, %1}
1451 mov{l}\t{%1, %a0|%a0, %1}"
1452 [(set_attr "type" "imov")
1453 (set_attr "modrm" "0,*")
1454 (set_attr "length_address" "8,0")
1455 (set_attr "length_immediate" "0,*")
1456 (set_attr "memory" "store")
1457 (set_attr "mode" "SI")])
1459 (define_insn "*movabssi_2_rex64"
1460 [(set (match_operand:SI 0 "register_operand" "=a,r")
1461 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1464 movabs{l}\t{%P1, %0|%0, %P1}
1465 mov{l}\t{%a1, %0|%0, %a1}"
1466 [(set_attr "type" "imov")
1467 (set_attr "modrm" "0,*")
1468 (set_attr "length_address" "8,0")
1469 (set_attr "length_immediate" "0")
1470 (set_attr "memory" "load")
1471 (set_attr "mode" "SI")])
1473 (define_insn "*swapsi"
1474 [(set (match_operand:SI 0 "register_operand" "+r")
1475 (match_operand:SI 1 "register_operand" "+r"))
1480 [(set_attr "type" "imov")
1481 (set_attr "mode" "SI")
1482 (set_attr "pent_pair" "np")
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "double")])
1486 (define_expand "movhi"
1487 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488 (match_operand:HI 1 "general_operand" ""))]
1490 "ix86_expand_move (HImode, operands); DONE;")
1492 (define_insn "*pushhi2"
1493 [(set (match_operand:HI 0 "push_operand" "=X")
1494 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1497 [(set_attr "type" "push")
1498 (set_attr "mode" "SI")])
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502 [(set (match_operand:HI 0 "push_operand" "=X")
1503 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1506 [(set_attr "type" "push")
1507 (set_attr "mode" "DI")])
1509 (define_insn "*movhi_1"
1510 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1514 switch (get_attr_type (insn))
1517 /* movzwl is faster than movw on p2 due to partial word stalls,
1518 though not as fast as an aligned movl. */
1519 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1521 if (get_attr_mode (insn) == MODE_SI)
1522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1524 return "mov{w}\t{%1, %0|%0, %1}";
1528 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529 (const_string "imov")
1530 (and (eq_attr "alternative" "0")
1531 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (eq (symbol_ref "TARGET_HIMODE_MATH")
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "1,2")
1537 (match_operand:HI 1 "aligned_operand" ""))
1538 (const_string "imov")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1541 (eq_attr "alternative" "0,2"))
1542 (const_string "imovx")
1544 (const_string "imov")))
1546 (cond [(eq_attr "type" "imovx")
1548 (and (eq_attr "alternative" "1,2")
1549 (match_operand:HI 1 "aligned_operand" ""))
1551 (and (eq_attr "alternative" "0")
1552 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1554 (eq (symbol_ref "TARGET_HIMODE_MATH")
1558 (const_string "HI")))])
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1568 movabs{w}\t{%1, %P0|%P0, %1}
1569 mov{w}\t{%1, %a0|%a0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "modrm" "0,*")
1572 (set_attr "length_address" "8,0")
1573 (set_attr "length_immediate" "0,*")
1574 (set_attr "memory" "store")
1575 (set_attr "mode" "HI")])
1577 (define_insn "*movabshi_2_rex64"
1578 [(set (match_operand:HI 0 "register_operand" "=a,r")
1579 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1582 movabs{w}\t{%P1, %0|%0, %P1}
1583 mov{w}\t{%a1, %0|%0, %a1}"
1584 [(set_attr "type" "imov")
1585 (set_attr "modrm" "0,*")
1586 (set_attr "length_address" "8,0")
1587 (set_attr "length_immediate" "0")
1588 (set_attr "memory" "load")
1589 (set_attr "mode" "HI")])
1591 (define_insn "*swaphi_1"
1592 [(set (match_operand:HI 0 "register_operand" "+r")
1593 (match_operand:HI 1 "register_operand" "+r"))
1596 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "SI")
1600 (set_attr "pent_pair" "np")
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "double")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606 [(set (match_operand:HI 0 "register_operand" "+r")
1607 (match_operand:HI 1 "register_operand" "+r"))
1610 "TARGET_PARTIAL_REG_STALL"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "HI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstricthi"
1618 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619 (match_operand:HI 1 "general_operand" ""))]
1620 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1622 /* Don't generate memory->memory moves, go through a register */
1623 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624 operands[1] = force_reg (HImode, operands[1]);
1627 (define_insn "*movstricthi_1"
1628 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629 (match_operand:HI 1 "general_operand" "rn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{w}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "HI")])
1636 (define_insn "*movstricthi_xor"
1637 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638 (match_operand:HI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1641 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1643 [(set_attr "type" "alu1")
1644 (set_attr "mode" "HI")
1645 (set_attr "length_immediate" "0")])
1647 (define_expand "movqi"
1648 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649 (match_operand:QI 1 "general_operand" ""))]
1651 "ix86_expand_move (QImode, operands); DONE;")
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte". But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1657 (define_insn "*pushqi2"
1658 [(set (match_operand:QI 0 "push_operand" "=X")
1659 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1662 [(set_attr "type" "push")
1663 (set_attr "mode" "SI")])
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667 [(set (match_operand:QI 0 "push_operand" "=X")
1668 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "DI")])
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there. Then we use movzx.
1684 (define_insn "*movqi_1"
1685 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1687 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1689 switch (get_attr_type (insn))
1692 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1695 if (get_attr_mode (insn) == MODE_SI)
1696 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1698 return "mov{b}\t{%1, %0|%0, %1}";
1702 (cond [(and (eq_attr "alternative" "5")
1703 (not (match_operand:QI 1 "aligned_operand" "")))
1704 (const_string "imovx")
1705 (ne (symbol_ref "optimize_size") (const_int 0))
1706 (const_string "imov")
1707 (and (eq_attr "alternative" "3")
1708 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1710 (eq (symbol_ref "TARGET_QIMODE_MATH")
1712 (const_string "imov")
1713 (eq_attr "alternative" "3,5")
1714 (const_string "imovx")
1715 (and (ne (symbol_ref "TARGET_MOVX")
1717 (eq_attr "alternative" "2"))
1718 (const_string "imovx")
1720 (const_string "imov")))
1722 (cond [(eq_attr "alternative" "3,4,5")
1724 (eq_attr "alternative" "6")
1726 (eq_attr "type" "imovx")
1728 (and (eq_attr "type" "imov")
1729 (and (eq_attr "alternative" "0,1")
1730 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1732 (and (eq (symbol_ref "optimize_size")
1734 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1737 ;; Avoid partial register stalls when not using QImode arithmetic
1738 (and (eq_attr "type" "imov")
1739 (and (eq_attr "alternative" "0,1")
1740 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1742 (eq (symbol_ref "TARGET_QIMODE_MATH")
1746 (const_string "QI")))])
1748 (define_expand "reload_outqi"
1749 [(parallel [(match_operand:QI 0 "" "=m")
1750 (match_operand:QI 1 "register_operand" "r")
1751 (match_operand:QI 2 "register_operand" "=&q")])]
1755 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1757 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758 if (! q_regs_operand (op1, QImode))
1760 emit_insn (gen_movqi (op2, op1));
1763 emit_insn (gen_movqi (op0, op1));
1767 (define_insn "*swapqi_1"
1768 [(set (match_operand:QI 0 "register_operand" "+r")
1769 (match_operand:QI 1 "register_operand" "+r"))
1772 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "SI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")
1778 (set_attr "amdfam10_decode" "vector")])
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782 [(set (match_operand:QI 0 "register_operand" "+q")
1783 (match_operand:QI 1 "register_operand" "+q"))
1786 "TARGET_PARTIAL_REG_STALL"
1788 [(set_attr "type" "imov")
1789 (set_attr "mode" "QI")
1790 (set_attr "pent_pair" "np")
1791 (set_attr "athlon_decode" "vector")])
1793 (define_expand "movstrictqi"
1794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795 (match_operand:QI 1 "general_operand" ""))]
1796 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1798 /* Don't generate memory->memory moves, go through a register. */
1799 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800 operands[1] = force_reg (QImode, operands[1]);
1803 (define_insn "*movstrictqi_1"
1804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805 (match_operand:QI 1 "general_operand" "*qn,m"))]
1806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 "mov{b}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "imov")
1810 (set_attr "mode" "QI")])
1812 (define_insn "*movstrictqi_xor"
1813 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814 (match_operand:QI 1 "const0_operand" "i"))
1815 (clobber (reg:CC FLAGS_REG))]
1816 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "QI")
1820 (set_attr "length_immediate" "0")])
1822 (define_insn "*movsi_extv_1"
1823 [(set (match_operand:SI 0 "register_operand" "=R")
1824 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1828 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829 [(set_attr "type" "imovx")
1830 (set_attr "mode" "SI")])
1832 (define_insn "*movhi_extv_1"
1833 [(set (match_operand:HI 0 "register_operand" "=R")
1834 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1838 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839 [(set_attr "type" "imovx")
1840 (set_attr "mode" "SI")])
1842 (define_insn "*movqi_extv_1"
1843 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1849 switch (get_attr_type (insn))
1852 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1854 return "mov{b}\t{%h1, %0|%0, %h1}";
1858 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860 (ne (symbol_ref "TARGET_MOVX")
1862 (const_string "imovx")
1863 (const_string "imov")))
1865 (if_then_else (eq_attr "type" "imovx")
1867 (const_string "QI")))])
1869 (define_insn "*movqi_extv_1_rex64"
1870 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1876 switch (get_attr_type (insn))
1879 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1881 return "mov{b}\t{%h1, %0|%0, %h1}";
1885 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887 (ne (symbol_ref "TARGET_MOVX")
1889 (const_string "imovx")
1890 (const_string "imov")))
1892 (if_then_else (eq_attr "type" "imovx")
1894 (const_string "QI")))])
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1904 movabs{b}\t{%1, %P0|%P0, %1}
1905 mov{b}\t{%1, %a0|%a0, %1}"
1906 [(set_attr "type" "imov")
1907 (set_attr "modrm" "0,*")
1908 (set_attr "length_address" "8,0")
1909 (set_attr "length_immediate" "0,*")
1910 (set_attr "memory" "store")
1911 (set_attr "mode" "QI")])
1913 (define_insn "*movabsqi_2_rex64"
1914 [(set (match_operand:QI 0 "register_operand" "=a,r")
1915 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1918 movabs{b}\t{%P1, %0|%0, %P1}
1919 mov{b}\t{%a1, %0|%0, %a1}"
1920 [(set_attr "type" "imov")
1921 (set_attr "modrm" "0,*")
1922 (set_attr "length_address" "8,0")
1923 (set_attr "length_immediate" "0")
1924 (set_attr "memory" "load")
1925 (set_attr "mode" "QI")])
1927 (define_insn "*movdi_extzv_1"
1928 [(set (match_operand:DI 0 "register_operand" "=R")
1929 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1933 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934 [(set_attr "type" "imovx")
1935 (set_attr "mode" "DI")])
1937 (define_insn "*movsi_extzv_1"
1938 [(set (match_operand:SI 0 "register_operand" "=R")
1939 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1943 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944 [(set_attr "type" "imovx")
1945 (set_attr "mode" "SI")])
1947 (define_insn "*movqi_extzv_2"
1948 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1954 switch (get_attr_type (insn))
1957 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1959 return "mov{b}\t{%h1, %0|%0, %h1}";
1963 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965 (ne (symbol_ref "TARGET_MOVX")
1967 (const_string "imovx")
1968 (const_string "imov")))
1970 (if_then_else (eq_attr "type" "imovx")
1972 (const_string "QI")))])
1974 (define_insn "*movqi_extzv_2_rex64"
1975 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1981 switch (get_attr_type (insn))
1984 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1986 return "mov{b}\t{%h1, %0|%0, %h1}";
1990 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991 (ne (symbol_ref "TARGET_MOVX")
1993 (const_string "imovx")
1994 (const_string "imov")))
1996 (if_then_else (eq_attr "type" "imovx")
1998 (const_string "QI")))])
2000 (define_insn "movsi_insv_1"
2001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2004 (match_operand:SI 1 "general_operand" "Qmn"))]
2006 "mov{b}\t{%b1, %h0|%h0, %b1}"
2007 [(set_attr "type" "imov")
2008 (set_attr "mode" "QI")])
2010 (define_insn "*movsi_insv_1_rex64"
2011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2014 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2016 "mov{b}\t{%b1, %h0|%h0, %b1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "mode" "QI")])
2020 (define_insn "movdi_insv_1_rex64"
2021 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2024 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2026 "mov{b}\t{%b1, %h0|%h0, %b1}"
2027 [(set_attr "type" "imov")
2028 (set_attr "mode" "QI")])
2030 (define_insn "*movqi_insv_2"
2031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2034 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2037 "mov{b}\t{%h1, %h0|%h0, %h1}"
2038 [(set_attr "type" "imov")
2039 (set_attr "mode" "QI")])
2041 (define_expand "movdi"
2042 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043 (match_operand:DI 1 "general_operand" ""))]
2045 "ix86_expand_move (DImode, operands); DONE;")
2047 (define_insn "*pushdi"
2048 [(set (match_operand:DI 0 "push_operand" "=<")
2049 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2053 (define_insn "*pushdi2_rex64"
2054 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2060 [(set_attr "type" "push,multi")
2061 (set_attr "mode" "DI")])
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it. In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2068 [(match_scratch:DI 2 "r")
2069 (set (match_operand:DI 0 "push_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode)"
2073 [(set (match_dup 2) (match_dup 1))
2074 (set (match_dup 0) (match_dup 2))]
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 [(set (match_operand:DI 0 "push_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085 [(set (match_dup 0) (match_dup 1))
2086 (set (match_dup 2) (match_dup 3))]
2087 "split_di (operands + 1, 1, operands + 2, operands + 3);
2088 operands[1] = gen_lowpart (DImode, operands[2]);
2089 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2094 [(set (match_operand:DI 0 "push_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? epilogue_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 0) (match_dup 1))
2101 (set (match_dup 2) (match_dup 3))]
2102 "split_di (operands + 1, 1, operands + 2, operands + 3);
2103 operands[1] = gen_lowpart (DImode, operands[2]);
2104 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2108 (define_insn "*pushdi2_prologue_rex64"
2109 [(set (match_operand:DI 0 "push_operand" "=<")
2110 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111 (clobber (mem:BLK (scratch)))]
2114 [(set_attr "type" "push")
2115 (set_attr "mode" "DI")])
2117 (define_insn "*popdi1_epilogue_rex64"
2118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119 (mem:DI (reg:DI SP_REG)))
2120 (set (reg:DI SP_REG)
2121 (plus:DI (reg:DI SP_REG) (const_int 8)))
2122 (clobber (mem:BLK (scratch)))]
2125 [(set_attr "type" "pop")
2126 (set_attr "mode" "DI")])
2128 (define_insn "popdi1"
2129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130 (mem:DI (reg:DI SP_REG)))
2131 (set (reg:DI SP_REG)
2132 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2135 [(set_attr "type" "pop")
2136 (set_attr "mode" "DI")])
2138 (define_insn "*movdi_xor_rex64"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2140 (match_operand:DI 1 "const0_operand" "i"))
2141 (clobber (reg:CC FLAGS_REG))]
2142 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143 && reload_completed"
2145 [(set_attr "type" "alu1")
2146 (set_attr "mode" "SI")
2147 (set_attr "length_immediate" "0")])
2149 (define_insn "*movdi_or_rex64"
2150 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (match_operand:DI 1 "const_int_operand" "i"))
2152 (clobber (reg:CC FLAGS_REG))]
2153 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2155 && operands[1] == constm1_rtx"
2157 operands[1] = constm1_rtx;
2158 return "or{q}\t{%1, %0|%0, %1}";
2160 [(set_attr "type" "alu1")
2161 (set_attr "mode" "DI")
2162 (set_attr "length_immediate" "1")])
2164 (define_insn "*movdi_2"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2174 movq\t{%1, %0|%0, %1}
2175 movq\t{%1, %0|%0, %1}
2177 movq\t{%1, %0|%0, %1}
2178 movdqa\t{%1, %0|%0, %1}
2179 movq\t{%1, %0|%0, %1}
2181 movlps\t{%1, %0|%0, %1}
2182 movaps\t{%1, %0|%0, %1}
2183 movlps\t{%1, %0|%0, %1}"
2184 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2188 [(set (match_operand:DI 0 "push_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2190 "!TARGET_64BIT && reload_completed
2191 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2193 "ix86_split_long_move (operands); DONE;")
2195 ;; %%% This multiword shite has got to go.
2197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198 (match_operand:DI 1 "general_operand" ""))]
2199 "!TARGET_64BIT && reload_completed
2200 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2203 "ix86_split_long_move (operands); DONE;")
2205 (define_insn "*movdi_1_rex64"
2206 [(set (match_operand:DI 0 "nonimmediate_operand"
2207 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208 (match_operand:DI 1 "general_operand"
2209 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2210 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2212 switch (get_attr_type (insn))
2215 if (SSE_REG_P (operands[0]))
2216 return "movq2dq\t{%1, %0|%0, %1}";
2218 return "movdq2q\t{%1, %0|%0, %1}";
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "movdqa\t{%1, %0|%0, %1}";
2226 /* Moves from and into integer register is done using movd
2227 opcode with REX prefix. */
2228 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229 return "movd\t{%1, %0|%0, %1}";
2230 return "movq\t{%1, %0|%0, %1}";
2234 return "pxor\t%0, %0";
2240 return "lea{q}\t{%a1, %0|%0, %a1}";
2243 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244 if (get_attr_mode (insn) == MODE_SI)
2245 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246 else if (which_alternative == 2)
2247 return "movabs{q}\t{%1, %0|%0, %1}";
2249 return "mov{q}\t{%1, %0|%0, %1}";
2253 (cond [(eq_attr "alternative" "5")
2254 (const_string "mmxadd")
2255 (eq_attr "alternative" "6,7,8,9,10")
2256 (const_string "mmxmov")
2257 (eq_attr "alternative" "11")
2258 (const_string "sselog1")
2259 (eq_attr "alternative" "12,13,14,15,16")
2260 (const_string "ssemov")
2261 (eq_attr "alternative" "17,18")
2262 (const_string "ssecvt")
2263 (eq_attr "alternative" "4")
2264 (const_string "multi")
2265 (match_operand:DI 1 "pic_32bit_operand" "")
2266 (const_string "lea")
2268 (const_string "imov")))
2269 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2281 movabs{q}\t{%1, %P0|%P0, %1}
2282 mov{q}\t{%1, %a0|%a0, %1}"
2283 [(set_attr "type" "imov")
2284 (set_attr "modrm" "0,*")
2285 (set_attr "length_address" "8,0")
2286 (set_attr "length_immediate" "0,*")
2287 (set_attr "memory" "store")
2288 (set_attr "mode" "DI")])
2290 (define_insn "*movabsdi_2_rex64"
2291 [(set (match_operand:DI 0 "register_operand" "=a,r")
2292 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2295 movabs{q}\t{%P1, %0|%0, %P1}
2296 mov{q}\t{%a1, %0|%0, %a1}"
2297 [(set_attr "type" "imov")
2298 (set_attr "modrm" "0,*")
2299 (set_attr "length_address" "8,0")
2300 (set_attr "length_immediate" "0")
2301 (set_attr "memory" "load")
2302 (set_attr "mode" "DI")])
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it. In case this
2306 ;; fails, move by 32bit parts.
2308 [(match_scratch:DI 2 "r")
2309 (set (match_operand:DI 0 "memory_operand" "")
2310 (match_operand:DI 1 "immediate_operand" ""))]
2311 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312 && !x86_64_immediate_operand (operands[1], DImode)"
2313 [(set (match_dup 2) (match_dup 1))
2314 (set (match_dup 0) (match_dup 2))]
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2321 [(set (match_operand:DI 0 "memory_operand" "")
2322 (match_operand:DI 1 "immediate_operand" ""))]
2323 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325 [(set (match_dup 2) (match_dup 3))
2326 (set (match_dup 4) (match_dup 5))]
2327 "split_di (operands, 2, operands + 2, operands + 4);")
2330 [(set (match_operand:DI 0 "memory_operand" "")
2331 (match_operand:DI 1 "immediate_operand" ""))]
2332 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333 ? epilogue_completed : reload_completed)
2334 && !symbolic_operand (operands[1], DImode)
2335 && !x86_64_immediate_operand (operands[1], DImode)"
2336 [(set (match_dup 2) (match_dup 3))
2337 (set (match_dup 4) (match_dup 5))]
2338 "split_di (operands, 2, operands + 2, operands + 4);")
2340 (define_insn "*swapdi_rex64"
2341 [(set (match_operand:DI 0 "register_operand" "+r")
2342 (match_operand:DI 1 "register_operand" "+r"))
2347 [(set_attr "type" "imov")
2348 (set_attr "mode" "DI")
2349 (set_attr "pent_pair" "np")
2350 (set_attr "athlon_decode" "vector")
2351 (set_attr "amdfam10_decode" "double")])
2353 (define_expand "movti"
2354 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355 (match_operand:TI 1 "nonimmediate_operand" ""))]
2356 "TARGET_SSE || TARGET_64BIT"
2359 ix86_expand_move (TImode, operands);
2360 else if (push_operand (operands[0], TImode))
2361 ix86_expand_push (TImode, operands[1]);
2363 ix86_expand_vector_move (TImode, operands);
2367 (define_insn "*movti_internal"
2368 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370 "TARGET_SSE && !TARGET_64BIT
2371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2373 switch (which_alternative)
2376 if (get_attr_mode (insn) == MODE_V4SF)
2377 return "xorps\t%0, %0";
2379 return "pxor\t%0, %0";
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "movaps\t{%1, %0|%0, %1}";
2385 return "movdqa\t{%1, %0|%0, %1}";
2390 [(set_attr "type" "sselog1,ssemov,ssemov")
2392 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393 (ne (symbol_ref "optimize_size") (const_int 0)))
2394 (const_string "V4SF")
2395 (and (eq_attr "alternative" "2")
2396 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2398 (const_string "V4SF")]
2399 (const_string "TI")))])
2401 (define_insn "*movti_rex64"
2402 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2407 switch (which_alternative)
2413 if (get_attr_mode (insn) == MODE_V4SF)
2414 return "xorps\t%0, %0";
2416 return "pxor\t%0, %0";
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "movaps\t{%1, %0|%0, %1}";
2422 return "movdqa\t{%1, %0|%0, %1}";
2427 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2429 (cond [(eq_attr "alternative" "2,3")
2431 (ne (symbol_ref "optimize_size")
2433 (const_string "V4SF")
2434 (const_string "TI"))
2435 (eq_attr "alternative" "4")
2437 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2439 (ne (symbol_ref "optimize_size")
2441 (const_string "V4SF")
2442 (const_string "TI"))]
2443 (const_string "DI")))])
2446 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447 (match_operand:TI 1 "general_operand" ""))]
2448 "reload_completed && !SSE_REG_P (operands[0])
2449 && !SSE_REG_P (operands[1])"
2451 "ix86_split_long_move (operands); DONE;")
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern. Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459 (match_operand:CDI 1 "general_operand" ""))]
2462 if (push_operand (operands[0], CDImode))
2463 emit_move_complex_push (CDImode, operands[0], operands[1]);
2465 emit_move_complex_parts (operands[0], operands[1]);
2469 (define_expand "movsf"
2470 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471 (match_operand:SF 1 "general_operand" ""))]
2473 "ix86_expand_move (SFmode, operands); DONE;")
2475 (define_insn "*pushsf"
2476 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2480 /* Anything else should be already split before reg-stack. */
2481 gcc_assert (which_alternative == 1);
2482 return "push{l}\t%1";
2484 [(set_attr "type" "multi,push,multi")
2485 (set_attr "unit" "i387,*,*")
2486 (set_attr "mode" "SF,SI,SF")])
2488 (define_insn "*pushsf_rex64"
2489 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2493 /* Anything else should be already split before reg-stack. */
2494 gcc_assert (which_alternative == 1);
2495 return "push{q}\t%q1";
2497 [(set_attr "type" "multi,push,multi")
2498 (set_attr "unit" "i387,*,*")
2499 (set_attr "mode" "SF,DI,SF")])
2502 [(set (match_operand:SF 0 "push_operand" "")
2503 (match_operand:SF 1 "memory_operand" ""))]
2505 && MEM_P (operands[1])
2506 && (operands[2] = find_constant_src (insn))"
2511 ;; %%% Kill this when call knows how to work this out.
2513 [(set (match_operand:SF 0 "push_operand" "")
2514 (match_operand:SF 1 "any_fp_register_operand" ""))]
2516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2520 [(set (match_operand:SF 0 "push_operand" "")
2521 (match_operand:SF 1 "any_fp_register_operand" ""))]
2523 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2526 (define_insn "*movsf_1"
2527 [(set (match_operand:SF 0 "nonimmediate_operand"
2528 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529 (match_operand:SF 1 "general_operand"
2530 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532 && (reload_in_progress || reload_completed
2533 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534 || (!TARGET_SSE_MATH && optimize_size
2535 && standard_80387_constant_p (operands[1]))
2536 || GET_CODE (operands[1]) != CONST_DOUBLE
2537 || memory_operand (operands[0], SFmode))"
2539 switch (which_alternative)
2543 return output_387_reg_move (insn, operands);
2546 return standard_80387_constant_opcode (operands[1]);
2550 return "mov{l}\t{%1, %0|%0, %1}";
2552 if (get_attr_mode (insn) == MODE_TI)
2553 return "pxor\t%0, %0";
2555 return "xorps\t%0, %0";
2557 if (get_attr_mode (insn) == MODE_V4SF)
2558 return "movaps\t{%1, %0|%0, %1}";
2560 return "movss\t{%1, %0|%0, %1}";
2562 return "movss\t{%1, %0|%0, %1}";
2565 case 12: case 13: case 14: case 15:
2566 return "movd\t{%1, %0|%0, %1}";
2569 return "movq\t{%1, %0|%0, %1}";
2575 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2577 (cond [(eq_attr "alternative" "3,4,9,10")
2579 (eq_attr "alternative" "5")
2581 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2583 (ne (symbol_ref "TARGET_SSE2")
2585 (eq (symbol_ref "optimize_size")
2588 (const_string "V4SF"))
2589 /* For architectures resolving dependencies on
2590 whole SSE registers use APS move to break dependency
2591 chains, otherwise use short move to avoid extra work.
2593 Do the same for architectures resolving dependencies on
2594 the parts. While in DF mode it is better to always handle
2595 just register parts, the SF mode is different due to lack
2596 of instructions to load just part of the register. It is
2597 better to maintain the whole registers in single format
2598 to avoid problems on using packed logical operations. */
2599 (eq_attr "alternative" "6")
2601 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2603 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2605 (const_string "V4SF")
2606 (const_string "SF"))
2607 (eq_attr "alternative" "11")
2608 (const_string "DI")]
2609 (const_string "SF")))])
2611 (define_insn "*swapsf"
2612 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613 (match_operand:SF 1 "fp_register_operand" "+f"))
2616 "reload_completed || TARGET_80387"
2618 if (STACK_TOP_P (operands[0]))
2623 [(set_attr "type" "fxch")
2624 (set_attr "mode" "SF")])
2626 (define_expand "movdf"
2627 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628 (match_operand:DF 1 "general_operand" ""))]
2630 "ix86_expand_move (DFmode, operands); DONE;")
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter. Allow this
2635 ;; pattern for optimize_size too.
2637 (define_insn "*pushdf_nointeger"
2638 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2642 /* This insn should be already split before reg-stack. */
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "i387,*,*,*")
2647 (set_attr "mode" "DF,SI,SI,DF")])
2649 (define_insn "*pushdf_integer"
2650 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2654 /* This insn should be already split before reg-stack. */
2657 [(set_attr "type" "multi")
2658 (set_attr "unit" "i387,*,*")
2659 (set_attr "mode" "DF,SI,DF")])
2661 ;; %%% Kill this when call knows how to work this out.
2663 [(set (match_operand:DF 0 "push_operand" "")
2664 (match_operand:DF 1 "any_fp_register_operand" ""))]
2665 "!TARGET_64BIT && reload_completed"
2666 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2671 [(set (match_operand:DF 0 "push_operand" "")
2672 (match_operand:DF 1 "any_fp_register_operand" ""))]
2673 "TARGET_64BIT && reload_completed"
2674 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2679 [(set (match_operand:DF 0 "push_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2683 "ix86_split_long_move (operands); DONE;")
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2689 (define_insn "*movdf_nointeger"
2690 [(set (match_operand:DF 0 "nonimmediate_operand"
2691 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2692 (match_operand:DF 1 "general_operand"
2693 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696 && (reload_in_progress || reload_completed
2697 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699 && !memory_operand (operands[0], DFmode)
2700 && standard_80387_constant_p (operands[1]))
2701 || GET_CODE (operands[1]) != CONST_DOUBLE
2703 || !TARGET_MEMORY_MISMATCH_STALL
2704 || reload_in_progress || reload_completed)
2705 && memory_operand (operands[0], DFmode)))"
2707 switch (which_alternative)
2711 return output_387_reg_move (insn, operands);
2714 return standard_80387_constant_opcode (operands[1]);
2720 switch (get_attr_mode (insn))
2723 return "xorps\t%0, %0";
2725 return "xorpd\t%0, %0";
2727 return "pxor\t%0, %0";
2734 switch (get_attr_mode (insn))
2737 return "movaps\t{%1, %0|%0, %1}";
2739 return "movapd\t{%1, %0|%0, %1}";
2741 return "movdqa\t{%1, %0|%0, %1}";
2743 return "movq\t{%1, %0|%0, %1}";
2745 return "movsd\t{%1, %0|%0, %1}";
2747 return "movlpd\t{%1, %0|%0, %1}";
2749 return "movlps\t{%1, %0|%0, %1}";
2758 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2760 (cond [(eq_attr "alternative" "0,1,2")
2762 (eq_attr "alternative" "3,4")
2765 /* For SSE1, we have many fewer alternatives. */
2766 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2767 (cond [(eq_attr "alternative" "5,6")
2768 (const_string "V4SF")
2770 (const_string "V2SF"))
2772 /* xorps is one byte shorter. */
2773 (eq_attr "alternative" "5")
2774 (cond [(ne (symbol_ref "optimize_size")
2776 (const_string "V4SF")
2777 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2781 (const_string "V2DF"))
2783 /* For architectures resolving dependencies on
2784 whole SSE registers use APD move to break dependency
2785 chains, otherwise use short move to avoid extra work.
2787 movaps encodes one byte shorter. */
2788 (eq_attr "alternative" "6")
2790 [(ne (symbol_ref "optimize_size")
2792 (const_string "V4SF")
2793 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2795 (const_string "V2DF")
2797 (const_string "DF"))
2798 /* For architectures resolving dependencies on register
2799 parts we may avoid extra work to zero out upper part
2801 (eq_attr "alternative" "7")
2803 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2805 (const_string "V1DF")
2806 (const_string "DF"))
2808 (const_string "DF")))])
2810 (define_insn "*movdf_integer_rex64"
2811 [(set (match_operand:DF 0 "nonimmediate_operand"
2812 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2813 (match_operand:DF 1 "general_operand"
2814 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2815 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2816 && (reload_in_progress || reload_completed
2817 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2818 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2819 && standard_80387_constant_p (operands[1]))
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || memory_operand (operands[0], DFmode))"
2823 switch (which_alternative)
2827 return output_387_reg_move (insn, operands);
2830 return standard_80387_constant_opcode (operands[1]);
2837 switch (get_attr_mode (insn))
2840 return "xorps\t%0, %0";
2842 return "xorpd\t%0, %0";
2844 return "pxor\t%0, %0";
2851 switch (get_attr_mode (insn))
2854 return "movaps\t{%1, %0|%0, %1}";
2856 return "movapd\t{%1, %0|%0, %1}";
2858 return "movdqa\t{%1, %0|%0, %1}";
2860 return "movq\t{%1, %0|%0, %1}";
2862 return "movsd\t{%1, %0|%0, %1}";
2864 return "movlpd\t{%1, %0|%0, %1}";
2866 return "movlps\t{%1, %0|%0, %1}";
2873 return "movd\t{%1, %0|%0, %1}";
2879 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2881 (cond [(eq_attr "alternative" "0,1,2")
2883 (eq_attr "alternative" "3,4,9,10")
2886 /* For SSE1, we have many fewer alternatives. */
2887 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2888 (cond [(eq_attr "alternative" "5,6")
2889 (const_string "V4SF")
2891 (const_string "V2SF"))
2893 /* xorps is one byte shorter. */
2894 (eq_attr "alternative" "5")
2895 (cond [(ne (symbol_ref "optimize_size")
2897 (const_string "V4SF")
2898 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2902 (const_string "V2DF"))
2904 /* For architectures resolving dependencies on
2905 whole SSE registers use APD move to break dependency
2906 chains, otherwise use short move to avoid extra work.
2908 movaps encodes one byte shorter. */
2909 (eq_attr "alternative" "6")
2911 [(ne (symbol_ref "optimize_size")
2913 (const_string "V4SF")
2914 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2916 (const_string "V2DF")
2918 (const_string "DF"))
2919 /* For architectures resolving dependencies on register
2920 parts we may avoid extra work to zero out upper part
2922 (eq_attr "alternative" "7")
2924 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2926 (const_string "V1DF")
2927 (const_string "DF"))
2929 (const_string "DF")))])
2931 (define_insn "*movdf_integer"
2932 [(set (match_operand:DF 0 "nonimmediate_operand"
2933 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2934 (match_operand:DF 1 "general_operand"
2935 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2936 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2937 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2938 && (reload_in_progress || reload_completed
2939 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2940 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2941 && standard_80387_constant_p (operands[1]))
2942 || GET_CODE (operands[1]) != CONST_DOUBLE
2943 || memory_operand (operands[0], DFmode))"
2945 switch (which_alternative)
2949 return output_387_reg_move (insn, operands);
2952 return standard_80387_constant_opcode (operands[1]);
2959 switch (get_attr_mode (insn))
2962 return "xorps\t%0, %0";
2964 return "xorpd\t%0, %0";
2966 return "pxor\t%0, %0";
2973 switch (get_attr_mode (insn))
2976 return "movaps\t{%1, %0|%0, %1}";
2978 return "movapd\t{%1, %0|%0, %1}";
2980 return "movdqa\t{%1, %0|%0, %1}";
2982 return "movq\t{%1, %0|%0, %1}";
2984 return "movsd\t{%1, %0|%0, %1}";
2986 return "movlpd\t{%1, %0|%0, %1}";
2988 return "movlps\t{%1, %0|%0, %1}";
2997 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2999 (cond [(eq_attr "alternative" "0,1,2")
3001 (eq_attr "alternative" "3,4")
3004 /* For SSE1, we have many fewer alternatives. */
3005 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3006 (cond [(eq_attr "alternative" "5,6")
3007 (const_string "V4SF")
3009 (const_string "V2SF"))
3011 /* xorps is one byte shorter. */
3012 (eq_attr "alternative" "5")
3013 (cond [(ne (symbol_ref "optimize_size")
3015 (const_string "V4SF")
3016 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3020 (const_string "V2DF"))
3022 /* For architectures resolving dependencies on
3023 whole SSE registers use APD move to break dependency
3024 chains, otherwise use short move to avoid extra work.
3026 movaps encodes one byte shorter. */
3027 (eq_attr "alternative" "6")
3029 [(ne (symbol_ref "optimize_size")
3031 (const_string "V4SF")
3032 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034 (const_string "V2DF")
3036 (const_string "DF"))
3037 /* For architectures resolving dependencies on register
3038 parts we may avoid extra work to zero out upper part
3040 (eq_attr "alternative" "7")
3042 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3045 (const_string "DF"))
3047 (const_string "DF")))])
3050 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3051 (match_operand:DF 1 "general_operand" ""))]
3053 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3054 && ! (ANY_FP_REG_P (operands[0]) ||
3055 (GET_CODE (operands[0]) == SUBREG
3056 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3057 && ! (ANY_FP_REG_P (operands[1]) ||
3058 (GET_CODE (operands[1]) == SUBREG
3059 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3061 "ix86_split_long_move (operands); DONE;")
3063 (define_insn "*swapdf"
3064 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3065 (match_operand:DF 1 "fp_register_operand" "+f"))
3068 "reload_completed || TARGET_80387"
3070 if (STACK_TOP_P (operands[0]))
3075 [(set_attr "type" "fxch")
3076 (set_attr "mode" "DF")])
3078 (define_expand "movxf"
3079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3080 (match_operand:XF 1 "general_operand" ""))]
3082 "ix86_expand_move (XFmode, operands); DONE;")
3084 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3085 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3086 ;; Pushing using integer instructions is longer except for constants
3087 ;; and direct memory references.
3088 ;; (assuming that any given constant is pushed only once, but this ought to be
3089 ;; handled elsewhere).
3091 (define_insn "*pushxf_nointeger"
3092 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3093 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3096 /* This insn should be already split before reg-stack. */
3099 [(set_attr "type" "multi")
3100 (set_attr "unit" "i387,*,*")
3101 (set_attr "mode" "XF,SI,SI")])
3103 (define_insn "*pushxf_integer"
3104 [(set (match_operand:XF 0 "push_operand" "=<,<")
3105 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3108 /* This insn should be already split before reg-stack. */
3111 [(set_attr "type" "multi")
3112 (set_attr "unit" "i387,*")
3113 (set_attr "mode" "XF,SI")])
3116 [(set (match_operand 0 "push_operand" "")
3117 (match_operand 1 "general_operand" ""))]
3119 && (GET_MODE (operands[0]) == XFmode
3120 || GET_MODE (operands[0]) == DFmode)
3121 && !ANY_FP_REG_P (operands[1])"
3123 "ix86_split_long_move (operands); DONE;")
3126 [(set (match_operand:XF 0 "push_operand" "")
3127 (match_operand:XF 1 "any_fp_register_operand" ""))]
3129 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3130 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3131 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3134 [(set (match_operand:XF 0 "push_operand" "")
3135 (match_operand:XF 1 "any_fp_register_operand" ""))]
3137 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3138 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3139 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3141 ;; Do not use integer registers when optimizing for size
3142 (define_insn "*movxf_nointeger"
3143 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3144 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3146 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3147 && (reload_in_progress || reload_completed
3148 || (optimize_size && standard_80387_constant_p (operands[1]))
3149 || GET_CODE (operands[1]) != CONST_DOUBLE
3150 || memory_operand (operands[0], XFmode))"
3152 switch (which_alternative)
3156 return output_387_reg_move (insn, operands);
3159 return standard_80387_constant_opcode (operands[1]);
3167 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3168 (set_attr "mode" "XF,XF,XF,SI,SI")])
3170 (define_insn "*movxf_integer"
3171 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3172 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3175 && (reload_in_progress || reload_completed
3176 || (optimize_size && standard_80387_constant_p (operands[1]))
3177 || GET_CODE (operands[1]) != CONST_DOUBLE
3178 || memory_operand (operands[0], XFmode))"
3180 switch (which_alternative)
3184 return output_387_reg_move (insn, operands);
3187 return standard_80387_constant_opcode (operands[1]);
3196 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3197 (set_attr "mode" "XF,XF,XF,SI,SI")])
3199 (define_expand "movtf"
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "nonimmediate_operand" ""))]
3204 ix86_expand_move (TFmode, operands);
3208 (define_insn "*movtf_internal"
3209 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3210 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3212 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3214 switch (which_alternative)
3218 if (get_attr_mode (insn) == MODE_V4SF)
3219 return "movaps\t{%1, %0|%0, %1}";
3221 return "movdqa\t{%1, %0|%0, %1}";
3223 if (get_attr_mode (insn) == MODE_V4SF)
3224 return "xorps\t%0, %0";
3226 return "pxor\t%0, %0";
3234 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3236 (cond [(eq_attr "alternative" "0,2")
3238 (ne (symbol_ref "optimize_size")
3240 (const_string "V4SF")
3241 (const_string "TI"))
3242 (eq_attr "alternative" "1")
3244 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3246 (ne (symbol_ref "optimize_size")
3248 (const_string "V4SF")
3249 (const_string "TI"))]
3250 (const_string "DI")))])
3253 [(set (match_operand 0 "nonimmediate_operand" "")
3254 (match_operand 1 "general_operand" ""))]
3256 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3257 && GET_MODE (operands[0]) == XFmode
3258 && ! (ANY_FP_REG_P (operands[0]) ||
3259 (GET_CODE (operands[0]) == SUBREG
3260 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3261 && ! (ANY_FP_REG_P (operands[1]) ||
3262 (GET_CODE (operands[1]) == SUBREG
3263 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3265 "ix86_split_long_move (operands); DONE;")
3268 [(set (match_operand 0 "register_operand" "")
3269 (match_operand 1 "memory_operand" ""))]
3271 && MEM_P (operands[1])
3272 && (GET_MODE (operands[0]) == TFmode
3273 || GET_MODE (operands[0]) == XFmode
3274 || GET_MODE (operands[0]) == SFmode
3275 || GET_MODE (operands[0]) == DFmode)
3276 && (operands[2] = find_constant_src (insn))"
3277 [(set (match_dup 0) (match_dup 2))]
3279 rtx c = operands[2];
3280 rtx r = operands[0];
3282 if (GET_CODE (r) == SUBREG)
3287 if (!standard_sse_constant_p (c))
3290 else if (FP_REG_P (r))
3292 if (!standard_80387_constant_p (c))
3295 else if (MMX_REG_P (r))
3300 [(set (match_operand 0 "register_operand" "")
3301 (float_extend (match_operand 1 "memory_operand" "")))]
3303 && MEM_P (operands[1])
3304 && (GET_MODE (operands[0]) == TFmode
3305 || GET_MODE (operands[0]) == XFmode
3306 || GET_MODE (operands[0]) == SFmode
3307 || GET_MODE (operands[0]) == DFmode)
3308 && (operands[2] = find_constant_src (insn))"
3309 [(set (match_dup 0) (match_dup 2))]
3311 rtx c = operands[2];
3312 rtx r = operands[0];
3314 if (GET_CODE (r) == SUBREG)
3319 if (!standard_sse_constant_p (c))
3322 else if (FP_REG_P (r))
3324 if (!standard_80387_constant_p (c))
3327 else if (MMX_REG_P (r))
3331 (define_insn "swapxf"
3332 [(set (match_operand:XF 0 "register_operand" "+f")
3333 (match_operand:XF 1 "register_operand" "+f"))
3338 if (STACK_TOP_P (operands[0]))
3343 [(set_attr "type" "fxch")
3344 (set_attr "mode" "XF")])
3346 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3348 [(set (match_operand:X87MODEF 0 "register_operand" "")
3349 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3350 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3351 && (standard_80387_constant_p (operands[1]) == 8
3352 || standard_80387_constant_p (operands[1]) == 9)"
3353 [(set (match_dup 0)(match_dup 1))
3355 (neg:X87MODEF (match_dup 0)))]
3359 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3360 if (real_isnegzero (&r))
3361 operands[1] = CONST0_RTX (<MODE>mode);
3363 operands[1] = CONST1_RTX (<MODE>mode);
3367 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3368 (match_operand:TF 1 "general_operand" ""))]
3370 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3372 "ix86_split_long_move (operands); DONE;")
3374 ;; Zero extension instructions
3376 (define_expand "zero_extendhisi2"
3377 [(set (match_operand:SI 0 "register_operand" "")
3378 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3381 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3383 operands[1] = force_reg (HImode, operands[1]);
3384 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3389 (define_insn "zero_extendhisi2_and"
3390 [(set (match_operand:SI 0 "register_operand" "=r")
3391 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3392 (clobber (reg:CC FLAGS_REG))]
3393 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3395 [(set_attr "type" "alu1")
3396 (set_attr "mode" "SI")])
3399 [(set (match_operand:SI 0 "register_operand" "")
3400 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3401 (clobber (reg:CC FLAGS_REG))]
3402 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3403 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3404 (clobber (reg:CC FLAGS_REG))])]
3407 (define_insn "*zero_extendhisi2_movzwl"
3408 [(set (match_operand:SI 0 "register_operand" "=r")
3409 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3410 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3411 "movz{wl|x}\t{%1, %0|%0, %1}"
3412 [(set_attr "type" "imovx")
3413 (set_attr "mode" "SI")])
3415 (define_expand "zero_extendqihi2"
3417 [(set (match_operand:HI 0 "register_operand" "")
3418 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3419 (clobber (reg:CC FLAGS_REG))])]
3423 (define_insn "*zero_extendqihi2_and"
3424 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3425 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3426 (clobber (reg:CC FLAGS_REG))]
3427 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3429 [(set_attr "type" "alu1")
3430 (set_attr "mode" "HI")])
3432 (define_insn "*zero_extendqihi2_movzbw_and"
3433 [(set (match_operand:HI 0 "register_operand" "=r,r")
3434 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3435 (clobber (reg:CC FLAGS_REG))]
3436 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3438 [(set_attr "type" "imovx,alu1")
3439 (set_attr "mode" "HI")])
3441 ; zero extend to SImode here to avoid partial register stalls
3442 (define_insn "*zero_extendqihi2_movzbl"
3443 [(set (match_operand:HI 0 "register_operand" "=r")
3444 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3446 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3447 [(set_attr "type" "imovx")
3448 (set_attr "mode" "SI")])
3450 ;; For the movzbw case strip only the clobber
3452 [(set (match_operand:HI 0 "register_operand" "")
3453 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3456 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3457 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3458 [(set (match_operand:HI 0 "register_operand" "")
3459 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3461 ;; When source and destination does not overlap, clear destination
3462 ;; first and then do the movb
3464 [(set (match_operand:HI 0 "register_operand" "")
3465 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3466 (clobber (reg:CC FLAGS_REG))]
3468 && ANY_QI_REG_P (operands[0])
3469 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3470 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3471 [(set (match_dup 0) (const_int 0))
3472 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3473 "operands[2] = gen_lowpart (QImode, operands[0]);")
3475 ;; Rest is handled by single and.
3477 [(set (match_operand:HI 0 "register_operand" "")
3478 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3479 (clobber (reg:CC FLAGS_REG))]
3481 && true_regnum (operands[0]) == true_regnum (operands[1])"
3482 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3483 (clobber (reg:CC FLAGS_REG))])]
3486 (define_expand "zero_extendqisi2"
3488 [(set (match_operand:SI 0 "register_operand" "")
3489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3490 (clobber (reg:CC FLAGS_REG))])]
3494 (define_insn "*zero_extendqisi2_and"
3495 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3496 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3500 [(set_attr "type" "alu1")
3501 (set_attr "mode" "SI")])
3503 (define_insn "*zero_extendqisi2_movzbw_and"
3504 [(set (match_operand:SI 0 "register_operand" "=r,r")
3505 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3506 (clobber (reg:CC FLAGS_REG))]
3507 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3509 [(set_attr "type" "imovx,alu1")
3510 (set_attr "mode" "SI")])
3512 (define_insn "*zero_extendqisi2_movzbw"
3513 [(set (match_operand:SI 0 "register_operand" "=r")
3514 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3515 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3516 "movz{bl|x}\t{%1, %0|%0, %1}"
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")])
3520 ;; For the movzbl case strip only the clobber
3522 [(set (match_operand:SI 0 "register_operand" "")
3523 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3524 (clobber (reg:CC FLAGS_REG))]
3526 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3527 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3529 (zero_extend:SI (match_dup 1)))])
3531 ;; When source and destination does not overlap, clear destination
3532 ;; first and then do the movb
3534 [(set (match_operand:SI 0 "register_operand" "")
3535 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3538 && ANY_QI_REG_P (operands[0])
3539 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3540 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3541 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3542 [(set (match_dup 0) (const_int 0))
3543 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3544 "operands[2] = gen_lowpart (QImode, operands[0]);")
3546 ;; Rest is handled by single and.
3548 [(set (match_operand:SI 0 "register_operand" "")
3549 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3550 (clobber (reg:CC FLAGS_REG))]
3552 && true_regnum (operands[0]) == true_regnum (operands[1])"
3553 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3554 (clobber (reg:CC FLAGS_REG))])]
3557 ;; %%% Kill me once multi-word ops are sane.
3558 (define_expand "zero_extendsidi2"
3559 [(set (match_operand:DI 0 "register_operand" "")
3560 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3565 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3570 (define_insn "zero_extendsidi2_32"
3571 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3573 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3574 (clobber (reg:CC FLAGS_REG))]
3580 movd\t{%1, %0|%0, %1}
3581 movd\t{%1, %0|%0, %1}
3582 movd\t{%1, %0|%0, %1}
3583 movd\t{%1, %0|%0, %1}"
3584 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3585 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3587 (define_insn "zero_extendsidi2_rex64"
3588 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3590 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3593 mov\t{%k1, %k0|%k0, %k1}
3595 movd\t{%1, %0|%0, %1}
3596 movd\t{%1, %0|%0, %1}
3597 movd\t{%1, %0|%0, %1}
3598 movd\t{%1, %0|%0, %1}"
3599 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3600 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3603 [(set (match_operand:DI 0 "memory_operand" "")
3604 (zero_extend:DI (match_dup 0)))]
3606 [(set (match_dup 4) (const_int 0))]
3607 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3613 "!TARGET_64BIT && reload_completed
3614 && true_regnum (operands[0]) == true_regnum (operands[1])"
3615 [(set (match_dup 4) (const_int 0))]
3616 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3619 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3620 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3621 (clobber (reg:CC FLAGS_REG))]
3622 "!TARGET_64BIT && reload_completed
3623 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3624 [(set (match_dup 3) (match_dup 1))
3625 (set (match_dup 4) (const_int 0))]
3626 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3628 (define_insn "zero_extendhidi2"
3629 [(set (match_operand:DI 0 "register_operand" "=r")
3630 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3632 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "DI")])
3636 (define_insn "zero_extendqidi2"
3637 [(set (match_operand:DI 0 "register_operand" "=r")
3638 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3640 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3641 [(set_attr "type" "imovx")
3642 (set_attr "mode" "DI")])
3644 ;; Sign extension instructions
3646 (define_expand "extendsidi2"
3647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3648 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3649 (clobber (reg:CC FLAGS_REG))
3650 (clobber (match_scratch:SI 2 ""))])]
3655 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3660 (define_insn "*extendsidi2_1"
3661 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3662 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3663 (clobber (reg:CC FLAGS_REG))
3664 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3668 (define_insn "extendsidi2_rex64"
3669 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3670 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3674 movs{lq|x}\t{%1,%0|%0, %1}"
3675 [(set_attr "type" "imovx")
3676 (set_attr "mode" "DI")
3677 (set_attr "prefix_0f" "0")
3678 (set_attr "modrm" "0,1")])
3680 (define_insn "extendhidi2"
3681 [(set (match_operand:DI 0 "register_operand" "=r")
3682 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3684 "movs{wq|x}\t{%1,%0|%0, %1}"
3685 [(set_attr "type" "imovx")
3686 (set_attr "mode" "DI")])
3688 (define_insn "extendqidi2"
3689 [(set (match_operand:DI 0 "register_operand" "=r")
3690 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3692 "movs{bq|x}\t{%1,%0|%0, %1}"
3693 [(set_attr "type" "imovx")
3694 (set_attr "mode" "DI")])
3696 ;; Extend to memory case when source register does die.
3698 [(set (match_operand:DI 0 "memory_operand" "")
3699 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3700 (clobber (reg:CC FLAGS_REG))
3701 (clobber (match_operand:SI 2 "register_operand" ""))]
3703 && dead_or_set_p (insn, operands[1])
3704 && !reg_mentioned_p (operands[1], operands[0]))"
3705 [(set (match_dup 3) (match_dup 1))
3706 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3707 (clobber (reg:CC FLAGS_REG))])
3708 (set (match_dup 4) (match_dup 1))]
3709 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3711 ;; Extend to memory case when source register does not die.
3713 [(set (match_operand:DI 0 "memory_operand" "")
3714 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3715 (clobber (reg:CC FLAGS_REG))
3716 (clobber (match_operand:SI 2 "register_operand" ""))]
3720 split_di (&operands[0], 1, &operands[3], &operands[4]);
3722 emit_move_insn (operands[3], operands[1]);
3724 /* Generate a cltd if possible and doing so it profitable. */
3725 if ((optimize_size || TARGET_USE_CLTD)
3726 && true_regnum (operands[1]) == AX_REG
3727 && true_regnum (operands[2]) == DX_REG)
3729 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3733 emit_move_insn (operands[2], operands[1]);
3734 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3736 emit_move_insn (operands[4], operands[2]);
3740 ;; Extend to register case. Optimize case where source and destination
3741 ;; registers match and cases where we can use cltd.
3743 [(set (match_operand:DI 0 "register_operand" "")
3744 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3745 (clobber (reg:CC FLAGS_REG))
3746 (clobber (match_scratch:SI 2 ""))]
3750 split_di (&operands[0], 1, &operands[3], &operands[4]);
3752 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3753 emit_move_insn (operands[3], operands[1]);
3755 /* Generate a cltd if possible and doing so it profitable. */
3756 if ((optimize_size || TARGET_USE_CLTD)
3757 && true_regnum (operands[3]) == AX_REG)
3759 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3763 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3764 emit_move_insn (operands[4], operands[1]);
3766 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3770 (define_insn "extendhisi2"
3771 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3772 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3775 switch (get_attr_prefix_0f (insn))
3778 return "{cwtl|cwde}";
3780 return "movs{wl|x}\t{%1,%0|%0, %1}";
3783 [(set_attr "type" "imovx")
3784 (set_attr "mode" "SI")
3785 (set (attr "prefix_0f")
3786 ;; movsx is short decodable while cwtl is vector decoded.
3787 (if_then_else (and (eq_attr "cpu" "!k6")
3788 (eq_attr "alternative" "0"))
3790 (const_string "1")))
3792 (if_then_else (eq_attr "prefix_0f" "0")
3794 (const_string "1")))])
3796 (define_insn "*extendhisi2_zext"
3797 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3799 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3802 switch (get_attr_prefix_0f (insn))
3805 return "{cwtl|cwde}";
3807 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3810 [(set_attr "type" "imovx")
3811 (set_attr "mode" "SI")
3812 (set (attr "prefix_0f")
3813 ;; movsx is short decodable while cwtl is vector decoded.
3814 (if_then_else (and (eq_attr "cpu" "!k6")
3815 (eq_attr "alternative" "0"))
3817 (const_string "1")))
3819 (if_then_else (eq_attr "prefix_0f" "0")
3821 (const_string "1")))])
3823 (define_insn "extendqihi2"
3824 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3825 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3828 switch (get_attr_prefix_0f (insn))
3831 return "{cbtw|cbw}";
3833 return "movs{bw|x}\t{%1,%0|%0, %1}";
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "HI")
3838 (set (attr "prefix_0f")
3839 ;; movsx is short decodable while cwtl is vector decoded.
3840 (if_then_else (and (eq_attr "cpu" "!k6")
3841 (eq_attr "alternative" "0"))
3843 (const_string "1")))
3845 (if_then_else (eq_attr "prefix_0f" "0")
3847 (const_string "1")))])
3849 (define_insn "extendqisi2"
3850 [(set (match_operand:SI 0 "register_operand" "=r")
3851 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3853 "movs{bl|x}\t{%1,%0|%0, %1}"
3854 [(set_attr "type" "imovx")
3855 (set_attr "mode" "SI")])
3857 (define_insn "*extendqisi2_zext"
3858 [(set (match_operand:DI 0 "register_operand" "=r")
3860 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3862 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3863 [(set_attr "type" "imovx")
3864 (set_attr "mode" "SI")])
3866 ;; Conversions between float and double.
3868 ;; These are all no-ops in the model used for the 80387. So just
3871 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3872 (define_insn "*dummy_extendsfdf2"
3873 [(set (match_operand:DF 0 "push_operand" "=<")
3874 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3879 [(set (match_operand:DF 0 "push_operand" "")
3880 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3882 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3883 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3886 [(set (match_operand:DF 0 "push_operand" "")
3887 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3889 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3890 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3892 (define_insn "*dummy_extendsfxf2"
3893 [(set (match_operand:XF 0 "push_operand" "=<")
3894 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3899 [(set (match_operand:XF 0 "push_operand" "")
3900 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3902 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3903 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3904 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3907 [(set (match_operand:XF 0 "push_operand" "")
3908 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3910 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3911 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3912 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3915 [(set (match_operand:XF 0 "push_operand" "")
3916 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3918 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3919 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3920 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3923 [(set (match_operand:XF 0 "push_operand" "")
3924 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3926 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3927 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3928 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3930 (define_expand "extendsfdf2"
3931 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3933 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3935 /* ??? Needed for compress_float_constant since all fp constants
3936 are LEGITIMATE_CONSTANT_P. */
3937 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3939 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3940 && standard_80387_constant_p (operands[1]) > 0)
3942 operands[1] = simplify_const_unary_operation
3943 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3944 emit_move_insn_1 (operands[0], operands[1]);
3947 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3951 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3953 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3955 We do the conversion post reload to avoid producing of 128bit spills
3956 that might lead to ICE on 32bit target. The sequence unlikely combine
3959 [(set (match_operand:DF 0 "register_operand" "")
3961 (match_operand:SF 1 "nonimmediate_operand" "")))]
3962 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3963 && reload_completed && SSE_REG_P (operands[0])"
3968 (parallel [(const_int 0) (const_int 1)]))))]
3970 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3971 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3972 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3973 Try to avoid move when unpacking can be done in source. */
3974 if (REG_P (operands[1]))
3976 /* If it is unsafe to overwrite upper half of source, we need
3977 to move to destination and unpack there. */
3978 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3979 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3980 && true_regnum (operands[0]) != true_regnum (operands[1]))
3982 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3983 emit_move_insn (tmp, operands[1]);
3986 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3987 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3990 emit_insn (gen_vec_setv4sf_0 (operands[3],
3991 CONST0_RTX (V4SFmode), operands[1]));
3994 (define_insn "*extendsfdf2_mixed"
3995 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3997 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3998 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4000 switch (which_alternative)
4004 return output_387_reg_move (insn, operands);
4007 return "cvtss2sd\t{%1, %0|%0, %1}";
4013 [(set_attr "type" "fmov,fmov,ssecvt")
4014 (set_attr "mode" "SF,XF,DF")])
4016 (define_insn "*extendsfdf2_sse"
4017 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4018 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4019 "TARGET_SSE2 && TARGET_SSE_MATH"
4020 "cvtss2sd\t{%1, %0|%0, %1}"
4021 [(set_attr "type" "ssecvt")
4022 (set_attr "mode" "DF")])
4024 (define_insn "*extendsfdf2_i387"
4025 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4026 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4028 "* return output_387_reg_move (insn, operands);"
4029 [(set_attr "type" "fmov")
4030 (set_attr "mode" "SF,XF")])
4032 (define_expand "extend<mode>xf2"
4033 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4034 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4037 /* ??? Needed for compress_float_constant since all fp constants
4038 are LEGITIMATE_CONSTANT_P. */
4039 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4041 if (standard_80387_constant_p (operands[1]) > 0)
4043 operands[1] = simplify_const_unary_operation
4044 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4045 emit_move_insn_1 (operands[0], operands[1]);
4048 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4052 (define_insn "*extend<mode>xf2_i387"
4053 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4055 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4057 "* return output_387_reg_move (insn, operands);"
4058 [(set_attr "type" "fmov")
4059 (set_attr "mode" "<MODE>,XF")])
4061 ;; %%% This seems bad bad news.
4062 ;; This cannot output into an f-reg because there is no way to be sure
4063 ;; of truncating in that case. Otherwise this is just like a simple move
4064 ;; insn. So we pretend we can output to a reg in order to get better
4065 ;; register preferencing, but we really use a stack slot.
4067 ;; Conversion from DFmode to SFmode.
4069 (define_expand "truncdfsf2"
4070 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4072 (match_operand:DF 1 "nonimmediate_operand" "")))]
4073 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4075 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4077 else if (flag_unsafe_math_optimizations)
4081 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4082 rtx temp = assign_386_stack_local (SFmode, slot);
4083 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4088 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4090 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4092 We do the conversion post reload to avoid producing of 128bit spills
4093 that might lead to ICE on 32bit target. The sequence unlikely combine
4096 [(set (match_operand:SF 0 "register_operand" "")
4098 (match_operand:DF 1 "nonimmediate_operand" "")))]
4099 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4100 && reload_completed && SSE_REG_P (operands[0])"
4103 (float_truncate:V2SF
4107 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4108 operands[3] = CONST0_RTX (V2SFmode);
4109 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4110 /* Use movsd for loading from memory, unpcklpd for registers.
4111 Try to avoid move when unpacking can be done in source, or SSE3
4112 movddup is available. */
4113 if (REG_P (operands[1]))
4116 && true_regnum (operands[0]) != true_regnum (operands[1])
4117 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4118 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4120 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4121 emit_move_insn (tmp, operands[1]);
4124 else if (!TARGET_SSE3)
4125 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4126 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4129 emit_insn (gen_sse2_loadlpd (operands[4],
4130 CONST0_RTX (V2DFmode), operands[1]));
4133 (define_expand "truncdfsf2_with_temp"
4134 [(parallel [(set (match_operand:SF 0 "" "")
4135 (float_truncate:SF (match_operand:DF 1 "" "")))
4136 (clobber (match_operand:SF 2 "" ""))])]
4139 (define_insn "*truncdfsf_fast_mixed"
4140 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4142 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4143 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4145 switch (which_alternative)
4149 return output_387_reg_move (insn, operands);
4151 return "cvtsd2ss\t{%1, %0|%0, %1}";
4156 [(set_attr "type" "fmov,fmov,ssecvt")
4157 (set_attr "mode" "SF")])
4159 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4160 ;; because nothing we do here is unsafe.
4161 (define_insn "*truncdfsf_fast_sse"
4162 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4164 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4165 "TARGET_SSE2 && TARGET_SSE_MATH"
4166 "cvtsd2ss\t{%1, %0|%0, %1}"
4167 [(set_attr "type" "ssecvt")
4168 (set_attr "mode" "SF")])
4170 (define_insn "*truncdfsf_fast_i387"
4171 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4173 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4174 "TARGET_80387 && flag_unsafe_math_optimizations"
4175 "* return output_387_reg_move (insn, operands);"
4176 [(set_attr "type" "fmov")
4177 (set_attr "mode" "SF")])
4179 (define_insn "*truncdfsf_mixed"
4180 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4182 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4183 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4184 "TARGET_MIX_SSE_I387"
4186 switch (which_alternative)
4189 return output_387_reg_move (insn, operands);
4194 return "cvtsd2ss\t{%1, %0|%0, %1}";
4199 [(set_attr "type" "fmov,multi,ssecvt")
4200 (set_attr "unit" "*,i387,*")
4201 (set_attr "mode" "SF")])
4203 (define_insn "*truncdfsf_i387"
4204 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4206 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4207 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4210 switch (which_alternative)
4213 return output_387_reg_move (insn, operands);
4221 [(set_attr "type" "fmov,multi")
4222 (set_attr "unit" "*,i387")
4223 (set_attr "mode" "SF")])
4225 (define_insn "*truncdfsf2_i387_1"
4226 [(set (match_operand:SF 0 "memory_operand" "=m")
4228 (match_operand:DF 1 "register_operand" "f")))]
4230 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4231 && !TARGET_MIX_SSE_I387"
4232 "* return output_387_reg_move (insn, operands);"
4233 [(set_attr "type" "fmov")
4234 (set_attr "mode" "SF")])
4237 [(set (match_operand:SF 0 "register_operand" "")
4239 (match_operand:DF 1 "fp_register_operand" "")))
4240 (clobber (match_operand 2 "" ""))]
4242 [(set (match_dup 2) (match_dup 1))
4243 (set (match_dup 0) (match_dup 2))]
4245 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4248 ;; Conversion from XFmode to {SF,DF}mode
4250 (define_expand "truncxf<mode>2"
4251 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4252 (float_truncate:MODEF
4253 (match_operand:XF 1 "register_operand" "")))
4254 (clobber (match_dup 2))])]
4257 if (flag_unsafe_math_optimizations)
4259 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4260 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4261 if (reg != operands[0])
4262 emit_move_insn (operands[0], reg);
4267 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4268 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4272 (define_insn "*truncxfsf2_mixed"
4273 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4275 (match_operand:XF 1 "register_operand" "f,f")))
4276 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4279 gcc_assert (!which_alternative);
4280 return output_387_reg_move (insn, operands);
4282 [(set_attr "type" "fmov,multi")
4283 (set_attr "unit" "*,i387")
4284 (set_attr "mode" "SF")])
4286 (define_insn "*truncxfdf2_mixed"
4287 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4289 (match_operand:XF 1 "register_operand" "f,f")))
4290 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4293 gcc_assert (!which_alternative);
4294 return output_387_reg_move (insn, operands);
4296 [(set_attr "type" "fmov,multi")
4297 (set_attr "unit" "*,i387")
4298 (set_attr "mode" "DF")])
4300 (define_insn "truncxf<mode>2_i387_noop"
4301 [(set (match_operand:MODEF 0 "register_operand" "=f")
4302 (float_truncate:MODEF
4303 (match_operand:XF 1 "register_operand" "f")))]
4304 "TARGET_80387 && flag_unsafe_math_optimizations"
4305 "* return output_387_reg_move (insn, operands);"
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "<MODE>")])
4309 (define_insn "*truncxf<mode>2_i387"
4310 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4311 (float_truncate:MODEF
4312 (match_operand:XF 1 "register_operand" "f")))]
4314 "* return output_387_reg_move (insn, operands);"
4315 [(set_attr "type" "fmov")
4316 (set_attr "mode" "<MODE>")])
4319 [(set (match_operand:MODEF 0 "register_operand" "")
4320 (float_truncate:MODEF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4323 "TARGET_80387 && reload_completed"
4324 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4325 (set (match_dup 0) (match_dup 2))]
4329 [(set (match_operand:MODEF 0 "memory_operand" "")
4330 (float_truncate:MODEF
4331 (match_operand:XF 1 "register_operand" "")))
4332 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4334 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4337 ;; Signed conversion to DImode.
4339 (define_expand "fix_truncxfdi2"
4340 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4341 (fix:DI (match_operand:XF 1 "register_operand" "")))
4342 (clobber (reg:CC FLAGS_REG))])]
4347 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4352 (define_expand "fix_trunc<mode>di2"
4353 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4354 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4355 (clobber (reg:CC FLAGS_REG))])]
4356 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4359 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4361 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4364 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4366 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4367 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4368 if (out != operands[0])
4369 emit_move_insn (operands[0], out);
4374 ;; Signed conversion to SImode.
4376 (define_expand "fix_truncxfsi2"
4377 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4378 (fix:SI (match_operand:XF 1 "register_operand" "")))
4379 (clobber (reg:CC FLAGS_REG))])]
4384 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4389 (define_expand "fix_trunc<mode>si2"
4390 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4391 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4392 (clobber (reg:CC FLAGS_REG))])]
4393 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4396 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4398 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4401 if (SSE_FLOAT_MODE_P (<MODE>mode))
4403 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4404 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4405 if (out != operands[0])
4406 emit_move_insn (operands[0], out);
4411 ;; Signed conversion to HImode.
4413 (define_expand "fix_trunc<mode>hi2"
4414 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4415 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4416 (clobber (reg:CC FLAGS_REG))])]
4418 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4422 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4427 ;; Unsigned conversion to SImode.
4429 (define_expand "fixuns_trunc<mode>si2"
4431 [(set (match_operand:SI 0 "register_operand" "")
4433 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4435 (clobber (match_scratch:<ssevecmode> 3 ""))
4436 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4437 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4439 enum machine_mode mode = <MODE>mode;
4440 enum machine_mode vecmode = <ssevecmode>mode;
4441 REAL_VALUE_TYPE TWO31r;
4444 real_ldexp (&TWO31r, &dconst1, 31);
4445 two31 = const_double_from_real_value (TWO31r, mode);
4446 two31 = ix86_build_const_vector (mode, true, two31);
4447 operands[2] = force_reg (vecmode, two31);
4450 (define_insn_and_split "*fixuns_trunc<mode>_1"
4451 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4453 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4454 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4455 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4456 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4457 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4459 "&& reload_completed"
4462 ix86_split_convert_uns_si_sse (operands);
4466 ;; Unsigned conversion to HImode.
4467 ;; Without these patterns, we'll try the unsigned SI conversion which
4468 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4470 (define_expand "fixuns_trunc<mode>hi2"
4472 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4473 (set (match_operand:HI 0 "nonimmediate_operand" "")
4474 (subreg:HI (match_dup 2) 0))]
4475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4476 "operands[2] = gen_reg_rtx (SImode);")
4478 ;; When SSE is available, it is always faster to use it!
4479 (define_insn "fix_trunc<mode>di_sse"
4480 [(set (match_operand:DI 0 "register_operand" "=r,r")
4481 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4482 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4483 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4484 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4485 [(set_attr "type" "sseicvt")
4486 (set_attr "mode" "<MODE>")
4487 (set_attr "athlon_decode" "double,vector")
4488 (set_attr "amdfam10_decode" "double,double")])
4490 (define_insn "fix_trunc<mode>si_sse"
4491 [(set (match_operand:SI 0 "register_operand" "=r,r")
4492 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4493 "SSE_FLOAT_MODE_P (<MODE>mode)
4494 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4495 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "sseicvt")
4497 (set_attr "mode" "<MODE>")
4498 (set_attr "athlon_decode" "double,vector")
4499 (set_attr "amdfam10_decode" "double,double")])
4501 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4503 [(set (match_operand:MODEF 0 "register_operand" "")
4504 (match_operand:MODEF 1 "memory_operand" ""))
4505 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4506 (fix:SSEMODEI24 (match_dup 0)))]
4507 "TARGET_SHORTEN_X87_SSE
4508 && peep2_reg_dead_p (2, operands[0])"
4509 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4512 ;; Avoid vector decoded forms of the instruction.
4514 [(match_scratch:DF 2 "Y2")
4515 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4516 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4517 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4518 [(set (match_dup 2) (match_dup 1))
4519 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4523 [(match_scratch:SF 2 "x")
4524 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4525 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4526 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4531 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4532 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4533 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4534 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && (TARGET_64BIT || <MODE>mode != DImode))
4539 && !(reload_completed || reload_in_progress)"
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4548 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4549 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4555 [(set_attr "type" "fisttp")
4556 (set_attr "mode" "<MODE>")])
4558 (define_insn "fix_trunc<mode>_i387_fisttp"
4559 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4560 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4561 (clobber (match_scratch:XF 2 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && (TARGET_64BIT || <MODE>mode != DImode))
4566 && TARGET_SSE_MATH)"
4567 "* return output_fix_trunc (insn, operands, 1);"
4568 [(set_attr "type" "fisttp")
4569 (set_attr "mode" "<MODE>")])
4571 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4572 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4573 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4574 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4575 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4576 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && (TARGET_64BIT || <MODE>mode != DImode))
4580 && TARGET_SSE_MATH)"
4582 [(set_attr "type" "fisttp")
4583 (set_attr "mode" "<MODE>")])
4586 [(set (match_operand:X87MODEI 0 "register_operand" "")
4587 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4588 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4589 (clobber (match_scratch 3 ""))]
4591 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4592 (clobber (match_dup 3))])
4593 (set (match_dup 0) (match_dup 2))]
4597 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4598 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4599 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4600 (clobber (match_scratch 3 ""))]
4602 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4603 (clobber (match_dup 3))])]
4606 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4607 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4608 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4609 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4610 ;; function in i386.c.
4611 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4612 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4613 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4614 (clobber (reg:CC FLAGS_REG))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && (TARGET_64BIT || <MODE>mode != DImode))
4619 && !(reload_completed || reload_in_progress)"
4624 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4626 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4627 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4628 if (memory_operand (operands[0], VOIDmode))
4629 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4630 operands[2], operands[3]));
4633 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4634 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4635 operands[2], operands[3],
4640 [(set_attr "type" "fistp")
4641 (set_attr "i387_cw" "trunc")
4642 (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_truncdi_i387"
4645 [(set (match_operand:DI 0 "memory_operand" "=m")
4646 (fix:DI (match_operand 1 "register_operand" "f")))
4647 (use (match_operand:HI 2 "memory_operand" "m"))
4648 (use (match_operand:HI 3 "memory_operand" "m"))
4649 (clobber (match_scratch:XF 4 "=&1f"))]
4650 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4653 "* return output_fix_trunc (insn, operands, 0);"
4654 [(set_attr "type" "fistp")
4655 (set_attr "i387_cw" "trunc")
4656 (set_attr "mode" "DI")])
4658 (define_insn "fix_truncdi_i387_with_temp"
4659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4660 (fix:DI (match_operand 1 "register_operand" "f,f")))
4661 (use (match_operand:HI 2 "memory_operand" "m,m"))
4662 (use (match_operand:HI 3 "memory_operand" "m,m"))
4663 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4664 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4665 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4669 [(set_attr "type" "fistp")
4670 (set_attr "i387_cw" "trunc")
4671 (set_attr "mode" "DI")])
4674 [(set (match_operand:DI 0 "register_operand" "")
4675 (fix:DI (match_operand 1 "register_operand" "")))
4676 (use (match_operand:HI 2 "memory_operand" ""))
4677 (use (match_operand:HI 3 "memory_operand" ""))
4678 (clobber (match_operand:DI 4 "memory_operand" ""))
4679 (clobber (match_scratch 5 ""))]
4681 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4684 (clobber (match_dup 5))])
4685 (set (match_dup 0) (match_dup 4))]
4689 [(set (match_operand:DI 0 "memory_operand" "")
4690 (fix:DI (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:DI 4 "memory_operand" ""))
4694 (clobber (match_scratch 5 ""))]
4696 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4699 (clobber (match_dup 5))])]
4702 (define_insn "fix_trunc<mode>_i387"
4703 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4704 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4705 (use (match_operand:HI 2 "memory_operand" "m"))
4706 (use (match_operand:HI 3 "memory_operand" "m"))]
4707 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4710 "* return output_fix_trunc (insn, operands, 0);"
4711 [(set_attr "type" "fistp")
4712 (set_attr "i387_cw" "trunc")
4713 (set_attr "mode" "<MODE>")])
4715 (define_insn "fix_trunc<mode>_i387_with_temp"
4716 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4717 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4718 (use (match_operand:HI 2 "memory_operand" "m,m"))
4719 (use (match_operand:HI 3 "memory_operand" "m,m"))
4720 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4721 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4723 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4725 [(set_attr "type" "fistp")
4726 (set_attr "i387_cw" "trunc")
4727 (set_attr "mode" "<MODE>")])
4730 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4731 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4732 (use (match_operand:HI 2 "memory_operand" ""))
4733 (use (match_operand:HI 3 "memory_operand" ""))
4734 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4736 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4738 (use (match_dup 3))])
4739 (set (match_dup 0) (match_dup 4))]
4743 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4744 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4745 (use (match_operand:HI 2 "memory_operand" ""))
4746 (use (match_operand:HI 3 "memory_operand" ""))
4747 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4749 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4751 (use (match_dup 3))])]
4754 (define_insn "x86_fnstcw_1"
4755 [(set (match_operand:HI 0 "memory_operand" "=m")
4756 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4759 [(set_attr "length" "2")
4760 (set_attr "mode" "HI")
4761 (set_attr "unit" "i387")])
4763 (define_insn "x86_fldcw_1"
4764 [(set (reg:HI FPCR_REG)
4765 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4768 [(set_attr "length" "2")
4769 (set_attr "mode" "HI")
4770 (set_attr "unit" "i387")
4771 (set_attr "athlon_decode" "vector")
4772 (set_attr "amdfam10_decode" "vector")])
4774 ;; Conversion between fixed point and floating point.
4776 ;; Even though we only accept memory inputs, the backend _really_
4777 ;; wants to be able to do this between registers.
4779 (define_expand "floathi<mode>2"
4780 [(set (match_operand:MODEF 0 "register_operand" "")
4781 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4782 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4784 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4787 (gen_floatsi<mode>2 (operands[0],
4788 convert_to_mode (SImode, operands[1], 0)));
4793 (define_insn "*floathi<mode>2_i387"
4794 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4796 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4799 || TARGET_MIX_SSE_I387)"
4803 [(set_attr "type" "fmov,multi")
4804 (set_attr "mode" "<MODE>")
4805 (set_attr "unit" "*,i387")
4806 (set_attr "fp_int_src" "true")])
4808 (define_expand "floatsi<mode>2"
4809 [(set (match_operand:MODEF 0 "register_operand" "")
4810 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4811 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4813 /* When we use vector converts, we can't have input in memory. */
4814 if (GET_MODE (operands[0]) == DFmode
4815 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4816 && SSE_FLOAT_MODE_P (DFmode))
4817 operands[1] = force_reg (SImode, operands[1]);
4818 else if (GET_MODE (operands[0]) == SFmode
4819 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4820 && SSE_FLOAT_MODE_P (SFmode))
4822 /* When !flag_trapping_math, we handle SImode->SFmode vector
4823 conversions same way as SImode->DFmode.
4825 For flat_trapping_math we can't safely use vector conversion without
4826 clearing upper half, otherwise precision exception might occur.
4827 However we can still generate the common sequence converting value
4828 from general register to XMM register as:
4834 because we know that movd clears the upper half.
4836 Sadly in this case we can't rely on reload moving the value to XMM
4837 register, since we need to know if upper half is OK, so we need
4838 to do reloading by hand. We force operand to memory unless target
4839 supports inter unit moves. */
4840 if (!flag_trapping_math)
4841 operands[1] = force_reg (SImode, operands[1]);
4842 else if (!MEM_P (operands[1]))
4844 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4845 rtx tmp = assign_386_stack_local (SImode, slot);
4846 emit_move_insn (tmp, operands[1]);
4850 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4851 !TARGET_INTER_UNIT_CONVERSIONS
4852 It is necessary for the patterns to not accept nonmemory operands
4853 as we would optimize out later. */
4854 else if (!TARGET_INTER_UNIT_CONVERSIONS
4855 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4857 && !MEM_P (operands[1]))
4859 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4860 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4861 emit_move_insn (tmp, operands[1]);
4866 (define_insn "*floatsisf2_mixed_vector"
4867 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4868 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4869 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4870 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4872 cvtdq2ps\t{%1, %0|%0, %1}
4875 [(set_attr "type" "sseicvt,fmov,multi")
4876 (set_attr "mode" "SF")
4877 (set_attr "unit" "*,i387,*")
4878 (set_attr "athlon_decode" "double,*,*")
4879 (set_attr "amdfam10_decode" "double,*,*")
4880 (set_attr "fp_int_src" "false,true,true")])
4882 (define_insn "*floatsisf2_mixed"
4883 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4884 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4885 "TARGET_MIX_SSE_I387
4886 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4891 cvtsi2ss\t{%1, %0|%0, %1}
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "unit" "*,i387,*,*")
4896 (set_attr "athlon_decode" "*,*,vector,double")
4897 (set_attr "amdfam10_decode" "*,*,vector,double")
4898 (set_attr "fp_int_src" "true")])
4900 (define_insn "*floatsisf2_mixed_memory"
4901 [(set (match_operand:SF 0 "register_operand" "=f,x")
4902 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4903 "TARGET_MIX_SSE_I387
4904 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4907 cvtsi2ss\t{%1, %0|%0, %1}"
4908 [(set_attr "type" "fmov,sseicvt")
4909 (set_attr "mode" "SF")
4910 (set_attr "athlon_decode" "*,double")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsisf2_sse_vector_nointernunit"
4915 [(set (match_operand:SF 0 "register_operand" "=x")
4916 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4917 "TARGET_SSE_MATH && flag_trapping_math
4918 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4919 && !TARGET_INTER_UNIT_MOVES"
4921 [(set_attr "type" "multi")])
4923 (define_insn "*floatsisf2_sse_vector_internunit"
4924 [(set (match_operand:SF 0 "register_operand" "=x,x")
4925 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4926 "TARGET_SSE_MATH && flag_trapping_math
4927 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4928 && TARGET_INTER_UNIT_MOVES"
4930 [(set_attr "type" "multi")])
4933 [(set (match_operand:SF 0 "register_operand" "")
4934 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4936 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4937 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4938 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4940 (float:V4SF (match_dup 2)))]
4942 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4943 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4944 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4948 [(set (match_operand:SF 0 "register_operand" "")
4949 (float:SF (match_operand:SI 1 "register_operand" "")))]
4951 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4952 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4953 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4955 (float:V4SF (match_dup 2)))]
4957 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4958 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4961 (define_insn "*floatsisf2_sse_vector"
4962 [(set (match_operand:SF 0 "register_operand" "=x")
4963 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4964 "TARGET_SSE_MATH && !flag_trapping_math
4965 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4966 && !TARGET_INTER_UNIT_MOVES"
4967 "cvtdq2ps\t{%1, %0|%0, %1}"
4968 [(set_attr "type" "sseicvt")
4969 (set_attr "mode" "SF")
4970 (set_attr "athlon_decode" "double")
4971 (set_attr "amdfam10_decode" "double")
4972 (set_attr "fp_int_src" "true")])
4974 (define_insn "*floatsisf2_sse"
4975 [(set (match_operand:SF 0 "register_operand" "=x,x")
4976 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4978 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4980 "cvtsi2ss\t{%1, %0|%0, %1}"
4981 [(set_attr "type" "sseicvt")
4982 (set_attr "mode" "SF")
4983 (set_attr "athlon_decode" "vector,double")
4984 (set_attr "amdfam10_decode" "vector,double")
4985 (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsisf2_sse_memory"
4988 [(set (match_operand:SF 0 "register_operand" "=x")
4989 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4991 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4992 "cvtsi2ss\t{%1, %0|%0, %1}"
4993 [(set_attr "type" "sseicvt")
4994 (set_attr "mode" "SF")
4995 (set_attr "athlon_decode" "double")
4996 (set_attr "amdfam10_decode" "double")
4997 (set_attr "fp_int_src" "true")])
4999 (define_insn "*floatsidf2_mixed_vector"
5000 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5001 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5002 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5003 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5005 cvtdq2pd\t{%1, %0|%0, %1}
5008 [(set_attr "type" "sseicvt,fmov,multi")
5009 (set_attr "mode" "V2DF,DF,DF")
5010 (set_attr "unit" "*,*,i387")
5011 (set_attr "athlon_decode" "double,*,*")
5012 (set_attr "amdfam10_decode" "double,*,*")
5013 (set_attr "fp_int_src" "false,true,true")])
5015 (define_insn "*floatsidf2_mixed"
5016 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5017 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5018 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5024 cvtsi2sd\t{%1, %0|%0, %1}
5025 cvtsi2sd\t{%1, %0|%0, %1}
5026 cvtdq2pd\t{%1, %0|%0, %1}"
5027 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5028 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5029 (set_attr "unit" "*,i387,*,*,*")
5030 (set_attr "athlon_decode" "*,*,double,direct,double")
5031 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5032 (set_attr "fp_int_src" "true,true,true,true,false")])
5034 (define_insn "*floatsidf2_mixed_memory"
5035 [(set (match_operand:DF 0 "register_operand" "=f,x")
5036 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5037 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5038 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5041 cvtsi2sd\t{%1, %0|%0, %1}"
5042 [(set_attr "type" "fmov,sseicvt")
5043 (set_attr "mode" "DF")
5044 (set_attr "athlon_decode" "*,direct")
5045 (set_attr "amdfam10_decode" "*,double")
5046 (set_attr "fp_int_src" "true")])
5048 (define_insn "*floatsidf2_sse_vector"
5049 [(set (match_operand:DF 0 "register_operand" "=x")
5050 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5051 "TARGET_SSE2 && TARGET_SSE_MATH
5052 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5053 "cvtdq2pd\t{%1, %0|%0, %1}"
5054 [(set_attr "type" "sseicvt")
5055 (set_attr "mode" "V2DF")
5056 (set_attr "athlon_decode" "double")
5057 (set_attr "amdfam10_decode" "double")
5058 (set_attr "fp_int_src" "true")])
5061 [(set (match_operand:DF 0 "register_operand" "")
5062 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5063 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5064 && SSE_REG_P (operands[0])"
5069 (parallel [(const_int 0) (const_int 1)]))))]
5071 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5072 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5073 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5076 (define_insn "*floatsidf2_sse"
5077 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5078 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5079 "TARGET_SSE2 && TARGET_SSE_MATH
5080 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5083 cvtsi2sd\t{%1, %0|%0, %1}
5084 cvtsi2sd\t{%1, %0|%0, %1}
5085 cvtdq2pd\t{%1, %0|%0, %1}"
5086 [(set_attr "type" "sseicvt")
5087 (set_attr "mode" "DF,DF,V2DF")
5088 (set_attr "athlon_decode" "double,direct,double")
5089 (set_attr "amdfam10_decode" "vector,double,double")
5090 (set_attr "fp_int_src" "true")])
5092 (define_insn "*floatsidf2_memory"
5093 [(set (match_operand:DF 0 "register_operand" "=x")
5094 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5095 "TARGET_SSE2 && TARGET_SSE_MATH
5096 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5098 "cvtsi2sd\t{%1, %0|%0, %1}"
5099 [(set_attr "type" "sseicvt")
5100 (set_attr "mode" "DF")
5101 (set_attr "athlon_decode" "direct")
5102 (set_attr "amdfam10_decode" "double")
5103 (set_attr "fp_int_src" "true")])
5105 (define_insn "*floatsi<mode>2_i387"
5106 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5108 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5110 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5114 [(set_attr "type" "fmov,multi")
5115 (set_attr "mode" "<MODE>")
5116 (set_attr "unit" "*,i387")
5117 (set_attr "fp_int_src" "true")])
5119 (define_expand "floatdisf2"
5120 [(set (match_operand:SF 0 "register_operand" "")
5121 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5122 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5124 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5125 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5127 && !MEM_P (operands[1]))
5129 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5130 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5131 emit_move_insn (tmp, operands[1]);
5136 (define_insn "*floatdisf2_mixed"
5137 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5138 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5139 "TARGET_64BIT && TARGET_MIX_SSE_I387
5140 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5144 cvtsi2ss{q}\t{%1, %0|%0, %1}
5145 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5146 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5147 (set_attr "mode" "SF")
5148 (set_attr "unit" "*,i387,*,*")
5149 (set_attr "athlon_decode" "*,*,vector,double")
5150 (set_attr "amdfam10_decode" "*,*,vector,double")
5151 (set_attr "fp_int_src" "true")])
5153 (define_insn "*floatdisf2_mixed"
5154 [(set (match_operand:SF 0 "register_operand" "=f,x")
5155 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5156 "TARGET_64BIT && TARGET_MIX_SSE_I387
5157 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5160 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5161 [(set_attr "type" "fmov,sseicvt")
5162 (set_attr "mode" "SF")
5163 (set_attr "athlon_decode" "*,double")
5164 (set_attr "amdfam10_decode" "*,double")
5165 (set_attr "fp_int_src" "true")])
5167 (define_insn "*floatdisf2_sse"
5168 [(set (match_operand:SF 0 "register_operand" "=x,x")
5169 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5170 "TARGET_64BIT && TARGET_SSE_MATH
5171 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5172 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5173 [(set_attr "type" "sseicvt")
5174 (set_attr "mode" "SF")
5175 (set_attr "athlon_decode" "vector,double")
5176 (set_attr "amdfam10_decode" "vector,double")
5177 (set_attr "fp_int_src" "true")])
5179 (define_insn "*floatdisf2_memory"
5180 [(set (match_operand:SF 0 "register_operand" "=x")
5181 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5182 "TARGET_64BIT && TARGET_SSE_MATH
5183 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5184 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5185 [(set_attr "type" "sseicvt")
5186 (set_attr "mode" "SF")
5187 (set_attr "athlon_decode" "double")
5188 (set_attr "amdfam10_decode" "double")
5189 (set_attr "fp_int_src" "true")])
5191 (define_expand "floatdidf2"
5192 [(set (match_operand:DF 0 "register_operand" "")
5193 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5194 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5196 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5198 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5201 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5202 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5204 && !MEM_P (operands[1]))
5206 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5207 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5208 emit_move_insn (tmp, operands[1]);
5213 (define_insn "*floatdidf2_mixed"
5214 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5215 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5216 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5217 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5221 cvtsi2sd{q}\t{%1, %0|%0, %1}
5222 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5223 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5224 (set_attr "mode" "DF")
5225 (set_attr "unit" "*,i387,*,*")
5226 (set_attr "athlon_decode" "*,*,double,direct")
5227 (set_attr "amdfam10_decode" "*,*,vector,double")
5228 (set_attr "fp_int_src" "true")])
5230 (define_insn "*floatdidf2_mixed_memory"
5231 [(set (match_operand:DF 0 "register_operand" "=f,x")
5232 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5233 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5234 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5237 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5238 [(set_attr "type" "fmov,sseicvt")
5239 (set_attr "mode" "DF")
5240 (set_attr "athlon_decode" "*,direct")
5241 (set_attr "amdfam10_decode" "*,double")
5242 (set_attr "fp_int_src" "true")])
5244 (define_insn "*floatdidf2_sse"
5245 [(set (match_operand:DF 0 "register_operand" "=x,x")
5246 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5247 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5248 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5249 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5250 [(set_attr "type" "sseicvt")
5251 (set_attr "mode" "DF")
5252 (set_attr "athlon_decode" "double,direct")
5253 (set_attr "amdfam10_decode" "vector,double")
5254 (set_attr "fp_int_src" "true")])
5256 (define_insn "*floatdidf2_sse_memory"
5257 [(set (match_operand:DF 0 "register_operand" "=x")
5258 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5259 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5260 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5261 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5262 [(set_attr "type" "sseicvt")
5263 (set_attr "mode" "DF")
5264 (set_attr "athlon_decode" "direct")
5265 (set_attr "amdfam10_decode" "double")
5266 (set_attr "fp_int_src" "true")])
5268 (define_insn "*floatdi<mode>2_i387"
5269 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5271 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5273 && (!TARGET_SSE_MATH || !TARGET_64BIT
5274 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5278 [(set_attr "type" "fmov,multi")
5279 (set_attr "mode" "<MODE>")
5280 (set_attr "unit" "*,i387")
5281 (set_attr "fp_int_src" "true")])
5283 (define_insn "float<mode>xf2"
5284 [(set (match_operand:XF 0 "register_operand" "=f,f")
5285 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5290 [(set_attr "type" "fmov,multi")
5291 (set_attr "mode" "XF")
5292 (set_attr "unit" "*,i387")
5293 (set_attr "fp_int_src" "true")])
5295 ;; %%% Kill these when reload knows how to do it.
5297 [(set (match_operand 0 "fp_register_operand" "")
5298 (float (match_operand 1 "register_operand" "")))]
5300 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5303 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5304 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5306 ix86_free_from_memory (GET_MODE (operands[1]));
5310 (define_expand "floatunssi<mode>2"
5311 [(use (match_operand:MODEF 0 "register_operand" ""))
5312 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5313 "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5315 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5319 (define_expand "floatunsdisf2"
5320 [(use (match_operand:SF 0 "register_operand" ""))
5321 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5322 "TARGET_64BIT && TARGET_SSE_MATH"
5323 "x86_emit_floatuns (operands); DONE;")
5325 (define_expand "floatunsdidf2"
5326 [(use (match_operand:DF 0 "register_operand" ""))
5327 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5328 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5329 && TARGET_SSE2 && TARGET_SSE_MATH"
5332 x86_emit_floatuns (operands);
5334 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5340 ;; %%% splits for addditi3
5342 (define_expand "addti3"
5343 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5344 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5345 (match_operand:TI 2 "x86_64_general_operand" "")))
5346 (clobber (reg:CC FLAGS_REG))]
5348 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5350 (define_insn "*addti3_1"
5351 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5352 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5353 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5354 (clobber (reg:CC FLAGS_REG))]
5355 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5359 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5360 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5361 (match_operand:TI 2 "x86_64_general_operand" "")))
5362 (clobber (reg:CC FLAGS_REG))]
5363 "TARGET_64BIT && reload_completed"
5364 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5366 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5367 (parallel [(set (match_dup 3)
5368 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5371 (clobber (reg:CC FLAGS_REG))])]
5372 "split_ti (operands+0, 1, operands+0, operands+3);
5373 split_ti (operands+1, 1, operands+1, operands+4);
5374 split_ti (operands+2, 1, operands+2, operands+5);")
5376 ;; %%% splits for addsidi3
5377 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5378 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5379 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5381 (define_expand "adddi3"
5382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5384 (match_operand:DI 2 "x86_64_general_operand" "")))
5385 (clobber (reg:CC FLAGS_REG))]
5387 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5389 (define_insn "*adddi3_1"
5390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5391 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5392 (match_operand:DI 2 "general_operand" "roiF,riF")))
5393 (clobber (reg:CC FLAGS_REG))]
5394 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5398 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5399 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5400 (match_operand:DI 2 "general_operand" "")))
5401 (clobber (reg:CC FLAGS_REG))]
5402 "!TARGET_64BIT && reload_completed"
5403 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5405 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5406 (parallel [(set (match_dup 3)
5407 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5410 (clobber (reg:CC FLAGS_REG))])]
5411 "split_di (operands+0, 1, operands+0, operands+3);
5412 split_di (operands+1, 1, operands+1, operands+4);
5413 split_di (operands+2, 1, operands+2, operands+5);")
5415 (define_insn "adddi3_carry_rex64"
5416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5417 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5418 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5419 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5420 (clobber (reg:CC FLAGS_REG))]
5421 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5422 "adc{q}\t{%2, %0|%0, %2}"
5423 [(set_attr "type" "alu")
5424 (set_attr "pent_pair" "pu")
5425 (set_attr "mode" "DI")])
5427 (define_insn "*adddi3_cc_rex64"
5428 [(set (reg:CC FLAGS_REG)
5429 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5430 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5432 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5433 (plus:DI (match_dup 1) (match_dup 2)))]
5434 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5435 "add{q}\t{%2, %0|%0, %2}"
5436 [(set_attr "type" "alu")
5437 (set_attr "mode" "DI")])
5439 (define_insn "*<addsub><mode>3_cc_overflow"
5440 [(set (reg:CCC FLAGS_REG)
5443 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5444 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5447 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5448 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5449 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5450 [(set_attr "type" "alu")
5451 (set_attr "mode" "<MODE>")])
5453 (define_insn "*add<mode>3_cconly_overflow"
5454 [(set (reg:CCC FLAGS_REG)
5456 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5457 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5459 (clobber (match_scratch:SWI 0 "=<r>"))]
5460 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5461 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5462 [(set_attr "type" "alu")
5463 (set_attr "mode" "<MODE>")])
5465 (define_insn "*sub<mode>3_cconly_overflow"
5466 [(set (reg:CCC FLAGS_REG)
5468 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5469 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5472 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5473 [(set_attr "type" "icmp")
5474 (set_attr "mode" "<MODE>")])
5476 (define_insn "*<addsub>si3_zext_cc_overflow"
5477 [(set (reg:CCC FLAGS_REG)
5479 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5480 (match_operand:SI 2 "general_operand" "g"))
5482 (set (match_operand:DI 0 "register_operand" "=r")
5483 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5484 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5485 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5486 [(set_attr "type" "alu")
5487 (set_attr "mode" "SI")])
5489 (define_insn "addqi3_carry"
5490 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5491 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5492 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5493 (match_operand:QI 2 "general_operand" "qi,qm")))
5494 (clobber (reg:CC FLAGS_REG))]
5495 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5496 "adc{b}\t{%2, %0|%0, %2}"
5497 [(set_attr "type" "alu")
5498 (set_attr "pent_pair" "pu")
5499 (set_attr "mode" "QI")])
5501 (define_insn "addhi3_carry"
5502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5503 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5504 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5505 (match_operand:HI 2 "general_operand" "ri,rm")))
5506 (clobber (reg:CC FLAGS_REG))]
5507 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5508 "adc{w}\t{%2, %0|%0, %2}"
5509 [(set_attr "type" "alu")
5510 (set_attr "pent_pair" "pu")
5511 (set_attr "mode" "HI")])
5513 (define_insn "addsi3_carry"
5514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5515 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5516 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5517 (match_operand:SI 2 "general_operand" "ri,rm")))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5520 "adc{l}\t{%2, %0|%0, %2}"
5521 [(set_attr "type" "alu")
5522 (set_attr "pent_pair" "pu")
5523 (set_attr "mode" "SI")])
5525 (define_insn "*addsi3_carry_zext"
5526 [(set (match_operand:DI 0 "register_operand" "=r")
5528 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5529 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5530 (match_operand:SI 2 "general_operand" "g"))))
5531 (clobber (reg:CC FLAGS_REG))]
5532 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5533 "adc{l}\t{%2, %k0|%k0, %2}"
5534 [(set_attr "type" "alu")
5535 (set_attr "pent_pair" "pu")
5536 (set_attr "mode" "SI")])
5538 (define_insn "*addsi3_cc"
5539 [(set (reg:CC FLAGS_REG)
5540 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5541 (match_operand:SI 2 "general_operand" "ri,rm")]
5543 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5544 (plus:SI (match_dup 1) (match_dup 2)))]
5545 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5546 "add{l}\t{%2, %0|%0, %2}"
5547 [(set_attr "type" "alu")
5548 (set_attr "mode" "SI")])
5550 (define_insn "addqi3_cc"
5551 [(set (reg:CC FLAGS_REG)
5552 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5553 (match_operand:QI 2 "general_operand" "qi,qm")]
5555 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5556 (plus:QI (match_dup 1) (match_dup 2)))]
5557 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5558 "add{b}\t{%2, %0|%0, %2}"
5559 [(set_attr "type" "alu")
5560 (set_attr "mode" "QI")])
5562 (define_expand "addsi3"
5563 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5565 (match_operand:SI 2 "general_operand" "")))
5566 (clobber (reg:CC FLAGS_REG))])]
5568 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5570 (define_insn "*lea_1"
5571 [(set (match_operand:SI 0 "register_operand" "=r")
5572 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5574 "lea{l}\t{%a1, %0|%0, %a1}"
5575 [(set_attr "type" "lea")
5576 (set_attr "mode" "SI")])
5578 (define_insn "*lea_1_rex64"
5579 [(set (match_operand:SI 0 "register_operand" "=r")
5580 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5582 "lea{l}\t{%a1, %0|%0, %a1}"
5583 [(set_attr "type" "lea")
5584 (set_attr "mode" "SI")])
5586 (define_insn "*lea_1_zext"
5587 [(set (match_operand:DI 0 "register_operand" "=r")
5589 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5591 "lea{l}\t{%a1, %k0|%k0, %a1}"
5592 [(set_attr "type" "lea")
5593 (set_attr "mode" "SI")])
5595 (define_insn "*lea_2_rex64"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5599 "lea{q}\t{%a1, %0|%0, %a1}"
5600 [(set_attr "type" "lea")
5601 (set_attr "mode" "DI")])
5603 ;; The lea patterns for non-Pmodes needs to be matched by several
5604 ;; insns converted to real lea by splitters.
5606 (define_insn_and_split "*lea_general_1"
5607 [(set (match_operand 0 "register_operand" "=r")
5608 (plus (plus (match_operand 1 "index_register_operand" "l")
5609 (match_operand 2 "register_operand" "r"))
5610 (match_operand 3 "immediate_operand" "i")))]
5611 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5612 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5613 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5614 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5615 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5616 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5617 || GET_MODE (operands[3]) == VOIDmode)"
5619 "&& reload_completed"
5623 operands[0] = gen_lowpart (SImode, operands[0]);
5624 operands[1] = gen_lowpart (Pmode, operands[1]);
5625 operands[2] = gen_lowpart (Pmode, operands[2]);
5626 operands[3] = gen_lowpart (Pmode, operands[3]);
5627 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5629 if (Pmode != SImode)
5630 pat = gen_rtx_SUBREG (SImode, pat, 0);
5631 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5634 [(set_attr "type" "lea")
5635 (set_attr "mode" "SI")])
5637 (define_insn_and_split "*lea_general_1_zext"
5638 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5641 (match_operand:SI 2 "register_operand" "r"))
5642 (match_operand:SI 3 "immediate_operand" "i"))))]
5645 "&& reload_completed"
5647 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5649 (match_dup 3)) 0)))]
5651 operands[1] = gen_lowpart (Pmode, operands[1]);
5652 operands[2] = gen_lowpart (Pmode, operands[2]);
5653 operands[3] = gen_lowpart (Pmode, operands[3]);
5655 [(set_attr "type" "lea")
5656 (set_attr "mode" "SI")])
5658 (define_insn_and_split "*lea_general_2"
5659 [(set (match_operand 0 "register_operand" "=r")
5660 (plus (mult (match_operand 1 "index_register_operand" "l")
5661 (match_operand 2 "const248_operand" "i"))
5662 (match_operand 3 "nonmemory_operand" "ri")))]
5663 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5664 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5665 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5666 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5667 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5668 || GET_MODE (operands[3]) == VOIDmode)"
5670 "&& reload_completed"
5674 operands[0] = gen_lowpart (SImode, operands[0]);
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[3] = gen_lowpart (Pmode, operands[3]);
5677 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5679 if (Pmode != SImode)
5680 pat = gen_rtx_SUBREG (SImode, pat, 0);
5681 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5684 [(set_attr "type" "lea")
5685 (set_attr "mode" "SI")])
5687 (define_insn_and_split "*lea_general_2_zext"
5688 [(set (match_operand:DI 0 "register_operand" "=r")
5690 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5691 (match_operand:SI 2 "const248_operand" "n"))
5692 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5695 "&& reload_completed"
5697 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5699 (match_dup 3)) 0)))]
5701 operands[1] = gen_lowpart (Pmode, operands[1]);
5702 operands[3] = gen_lowpart (Pmode, operands[3]);
5704 [(set_attr "type" "lea")
5705 (set_attr "mode" "SI")])
5707 (define_insn_and_split "*lea_general_3"
5708 [(set (match_operand 0 "register_operand" "=r")
5709 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5710 (match_operand 2 "const248_operand" "i"))
5711 (match_operand 3 "register_operand" "r"))
5712 (match_operand 4 "immediate_operand" "i")))]
5713 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5714 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5715 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5716 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5717 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5719 "&& reload_completed"
5723 operands[0] = gen_lowpart (SImode, operands[0]);
5724 operands[1] = gen_lowpart (Pmode, operands[1]);
5725 operands[3] = gen_lowpart (Pmode, operands[3]);
5726 operands[4] = gen_lowpart (Pmode, operands[4]);
5727 pat = gen_rtx_PLUS (Pmode,
5728 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5732 if (Pmode != SImode)
5733 pat = gen_rtx_SUBREG (SImode, pat, 0);
5734 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5737 [(set_attr "type" "lea")
5738 (set_attr "mode" "SI")])
5740 (define_insn_and_split "*lea_general_3_zext"
5741 [(set (match_operand:DI 0 "register_operand" "=r")
5743 (plus:SI (plus:SI (mult:SI
5744 (match_operand:SI 1 "index_register_operand" "l")
5745 (match_operand:SI 2 "const248_operand" "n"))
5746 (match_operand:SI 3 "register_operand" "r"))
5747 (match_operand:SI 4 "immediate_operand" "i"))))]
5750 "&& reload_completed"
5752 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5755 (match_dup 4)) 0)))]
5757 operands[1] = gen_lowpart (Pmode, operands[1]);
5758 operands[3] = gen_lowpart (Pmode, operands[3]);
5759 operands[4] = gen_lowpart (Pmode, operands[4]);
5761 [(set_attr "type" "lea")
5762 (set_attr "mode" "SI")])
5764 (define_insn "*adddi_1_rex64"
5765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5766 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5767 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5768 (clobber (reg:CC FLAGS_REG))]
5769 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5771 switch (get_attr_type (insn))
5774 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5775 return "lea{q}\t{%a2, %0|%0, %a2}";
5778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779 if (operands[2] == const1_rtx)
5780 return "inc{q}\t%0";
5783 gcc_assert (operands[2] == constm1_rtx);
5784 return "dec{q}\t%0";
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5792 if (CONST_INT_P (operands[2])
5793 /* Avoid overflows. */
5794 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5795 && (INTVAL (operands[2]) == 128
5796 || (INTVAL (operands[2]) < 0
5797 && INTVAL (operands[2]) != -128)))
5799 operands[2] = GEN_INT (-INTVAL (operands[2]));
5800 return "sub{q}\t{%2, %0|%0, %2}";
5802 return "add{q}\t{%2, %0|%0, %2}";
5806 (cond [(eq_attr "alternative" "2")
5807 (const_string "lea")
5808 ; Current assemblers are broken and do not allow @GOTOFF in
5809 ; ought but a memory context.
5810 (match_operand:DI 2 "pic_symbolic_operand" "")
5811 (const_string "lea")
5812 (match_operand:DI 2 "incdec_operand" "")
5813 (const_string "incdec")
5815 (const_string "alu")))
5816 (set_attr "mode" "DI")])
5818 ;; Convert lea to the lea pattern to avoid flags dependency.
5820 [(set (match_operand:DI 0 "register_operand" "")
5821 (plus:DI (match_operand:DI 1 "register_operand" "")
5822 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5823 (clobber (reg:CC FLAGS_REG))]
5824 "TARGET_64BIT && reload_completed
5825 && true_regnum (operands[0]) != true_regnum (operands[1])"
5827 (plus:DI (match_dup 1)
5831 (define_insn "*adddi_2_rex64"
5832 [(set (reg FLAGS_REG)
5834 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5835 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5837 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5838 (plus:DI (match_dup 1) (match_dup 2)))]
5839 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5840 && ix86_binary_operator_ok (PLUS, DImode, operands)
5841 /* Current assemblers are broken and do not allow @GOTOFF in
5842 ought but a memory context. */
5843 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845 switch (get_attr_type (insn))
5848 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5849 if (operands[2] == const1_rtx)
5850 return "inc{q}\t%0";
5853 gcc_assert (operands[2] == constm1_rtx);
5854 return "dec{q}\t%0";
5858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5859 /* ???? We ought to handle there the 32bit case too
5860 - do we need new constraint? */
5861 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5862 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5863 if (CONST_INT_P (operands[2])
5864 /* Avoid overflows. */
5865 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5866 && (INTVAL (operands[2]) == 128
5867 || (INTVAL (operands[2]) < 0
5868 && INTVAL (operands[2]) != -128)))
5870 operands[2] = GEN_INT (-INTVAL (operands[2]));
5871 return "sub{q}\t{%2, %0|%0, %2}";
5873 return "add{q}\t{%2, %0|%0, %2}";
5877 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5878 (const_string "incdec")
5879 (const_string "alu")))
5880 (set_attr "mode" "DI")])
5882 (define_insn "*adddi_3_rex64"
5883 [(set (reg FLAGS_REG)
5884 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5885 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5886 (clobber (match_scratch:DI 0 "=r"))]
5888 && ix86_match_ccmode (insn, CCZmode)
5889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5890 /* Current assemblers are broken and do not allow @GOTOFF in
5891 ought but a memory context. */
5892 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5894 switch (get_attr_type (insn))
5897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898 if (operands[2] == const1_rtx)
5899 return "inc{q}\t%0";
5902 gcc_assert (operands[2] == constm1_rtx);
5903 return "dec{q}\t%0";
5907 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5908 /* ???? We ought to handle there the 32bit case too
5909 - do we need new constraint? */
5910 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5912 if (CONST_INT_P (operands[2])
5913 /* Avoid overflows. */
5914 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5915 && (INTVAL (operands[2]) == 128
5916 || (INTVAL (operands[2]) < 0
5917 && INTVAL (operands[2]) != -128)))
5919 operands[2] = GEN_INT (-INTVAL (operands[2]));
5920 return "sub{q}\t{%2, %0|%0, %2}";
5922 return "add{q}\t{%2, %0|%0, %2}";
5926 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5927 (const_string "incdec")
5928 (const_string "alu")))
5929 (set_attr "mode" "DI")])
5931 ; For comparisons against 1, -1 and 128, we may generate better code
5932 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5933 ; is matched then. We can't accept general immediate, because for
5934 ; case of overflows, the result is messed up.
5935 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5937 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5938 ; only for comparisons not depending on it.
5939 (define_insn "*adddi_4_rex64"
5940 [(set (reg FLAGS_REG)
5941 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5942 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5943 (clobber (match_scratch:DI 0 "=rm"))]
5945 && ix86_match_ccmode (insn, CCGCmode)"
5947 switch (get_attr_type (insn))
5950 if (operands[2] == constm1_rtx)
5951 return "inc{q}\t%0";
5954 gcc_assert (operands[2] == const1_rtx);
5955 return "dec{q}\t%0";
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if ((INTVAL (operands[2]) == -128
5963 || (INTVAL (operands[2]) > 0
5964 && INTVAL (operands[2]) != 128))
5965 /* Avoid overflows. */
5966 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5967 return "sub{q}\t{%2, %0|%0, %2}";
5968 operands[2] = GEN_INT (-INTVAL (operands[2]));
5969 return "add{q}\t{%2, %0|%0, %2}";
5973 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5974 (const_string "incdec")
5975 (const_string "alu")))
5976 (set_attr "mode" "DI")])
5978 (define_insn "*adddi_5_rex64"
5979 [(set (reg FLAGS_REG)
5981 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5982 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5984 (clobber (match_scratch:DI 0 "=r"))]
5986 && ix86_match_ccmode (insn, CCGOCmode)
5987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5988 /* Current assemblers are broken and do not allow @GOTOFF in
5989 ought but a memory context. */
5990 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5992 switch (get_attr_type (insn))
5995 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5996 if (operands[2] == const1_rtx)
5997 return "inc{q}\t%0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{q}\t%0";
6005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6007 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6008 if (CONST_INT_P (operands[2])
6009 /* Avoid overflows. */
6010 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6011 && (INTVAL (operands[2]) == 128
6012 || (INTVAL (operands[2]) < 0
6013 && INTVAL (operands[2]) != -128)))
6015 operands[2] = GEN_INT (-INTVAL (operands[2]));
6016 return "sub{q}\t{%2, %0|%0, %2}";
6018 return "add{q}\t{%2, %0|%0, %2}";
6022 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set_attr "mode" "DI")])
6028 (define_insn "*addsi_1"
6029 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6030 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6031 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6032 (clobber (reg:CC FLAGS_REG))]
6033 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6035 switch (get_attr_type (insn))
6038 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6039 return "lea{l}\t{%a2, %0|%0, %a2}";
6042 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043 if (operands[2] == const1_rtx)
6044 return "inc{l}\t%0";
6047 gcc_assert (operands[2] == constm1_rtx);
6048 return "dec{l}\t%0";
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (CONST_INT_P (operands[2])
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{l}\t{%2, %0|%0, %2}";
6064 return "add{l}\t{%2, %0|%0, %2}";
6068 (cond [(eq_attr "alternative" "2")
6069 (const_string "lea")
6070 ; Current assemblers are broken and do not allow @GOTOFF in
6071 ; ought but a memory context.
6072 (match_operand:SI 2 "pic_symbolic_operand" "")
6073 (const_string "lea")
6074 (match_operand:SI 2 "incdec_operand" "")
6075 (const_string "incdec")
6077 (const_string "alu")))
6078 (set_attr "mode" "SI")])
6080 ;; Convert lea to the lea pattern to avoid flags dependency.
6082 [(set (match_operand 0 "register_operand" "")
6083 (plus (match_operand 1 "register_operand" "")
6084 (match_operand 2 "nonmemory_operand" "")))
6085 (clobber (reg:CC FLAGS_REG))]
6087 && true_regnum (operands[0]) != true_regnum (operands[1])"
6091 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6092 may confuse gen_lowpart. */
6093 if (GET_MODE (operands[0]) != Pmode)
6095 operands[1] = gen_lowpart (Pmode, operands[1]);
6096 operands[2] = gen_lowpart (Pmode, operands[2]);
6098 operands[0] = gen_lowpart (SImode, operands[0]);
6099 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6100 if (Pmode != SImode)
6101 pat = gen_rtx_SUBREG (SImode, pat, 0);
6102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6106 ;; It may seem that nonimmediate operand is proper one for operand 1.
6107 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6108 ;; we take care in ix86_binary_operator_ok to not allow two memory
6109 ;; operands so proper swapping will be done in reload. This allow
6110 ;; patterns constructed from addsi_1 to match.
6111 (define_insn "addsi_1_zext"
6112 [(set (match_operand:DI 0 "register_operand" "=r,r")
6114 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6115 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6119 switch (get_attr_type (insn))
6122 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6123 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6126 if (operands[2] == const1_rtx)
6127 return "inc{l}\t%k0";
6130 gcc_assert (operands[2] == constm1_rtx);
6131 return "dec{l}\t%k0";
6135 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6136 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6137 if (CONST_INT_P (operands[2])
6138 && (INTVAL (operands[2]) == 128
6139 || (INTVAL (operands[2]) < 0
6140 && INTVAL (operands[2]) != -128)))
6142 operands[2] = GEN_INT (-INTVAL (operands[2]));
6143 return "sub{l}\t{%2, %k0|%k0, %2}";
6145 return "add{l}\t{%2, %k0|%k0, %2}";
6149 (cond [(eq_attr "alternative" "1")
6150 (const_string "lea")
6151 ; Current assemblers are broken and do not allow @GOTOFF in
6152 ; ought but a memory context.
6153 (match_operand:SI 2 "pic_symbolic_operand" "")
6154 (const_string "lea")
6155 (match_operand:SI 2 "incdec_operand" "")
6156 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "SI")])
6161 ;; Convert lea to the lea pattern to avoid flags dependency.
6163 [(set (match_operand:DI 0 "register_operand" "")
6165 (plus:SI (match_operand:SI 1 "register_operand" "")
6166 (match_operand:SI 2 "nonmemory_operand" ""))))
6167 (clobber (reg:CC FLAGS_REG))]
6168 "TARGET_64BIT && reload_completed
6169 && true_regnum (operands[0]) != true_regnum (operands[1])"
6171 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6173 operands[1] = gen_lowpart (Pmode, operands[1]);
6174 operands[2] = gen_lowpart (Pmode, operands[2]);
6177 (define_insn "*addsi_2"
6178 [(set (reg FLAGS_REG)
6180 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6181 (match_operand:SI 2 "general_operand" "rmni,rni"))
6183 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6184 (plus:SI (match_dup 1) (match_dup 2)))]
6185 "ix86_match_ccmode (insn, CCGOCmode)
6186 && ix86_binary_operator_ok (PLUS, SImode, operands)
6187 /* Current assemblers are broken and do not allow @GOTOFF in
6188 ought but a memory context. */
6189 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6191 switch (get_attr_type (insn))
6194 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6195 if (operands[2] == const1_rtx)
6196 return "inc{l}\t%0";
6199 gcc_assert (operands[2] == constm1_rtx);
6200 return "dec{l}\t%0";
6204 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6205 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6206 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6207 if (CONST_INT_P (operands[2])
6208 && (INTVAL (operands[2]) == 128
6209 || (INTVAL (operands[2]) < 0
6210 && INTVAL (operands[2]) != -128)))
6212 operands[2] = GEN_INT (-INTVAL (operands[2]));
6213 return "sub{l}\t{%2, %0|%0, %2}";
6215 return "add{l}\t{%2, %0|%0, %2}";
6219 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu")))
6222 (set_attr "mode" "SI")])
6224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6225 (define_insn "*addsi_2_zext"
6226 [(set (reg FLAGS_REG)
6228 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6229 (match_operand:SI 2 "general_operand" "rmni"))
6231 (set (match_operand:DI 0 "register_operand" "=r")
6232 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6233 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6234 && ix86_binary_operator_ok (PLUS, SImode, operands)
6235 /* Current assemblers are broken and do not allow @GOTOFF in
6236 ought but a memory context. */
6237 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6239 switch (get_attr_type (insn))
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%k0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return "dec{l}\t%k0";
6251 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6253 if (CONST_INT_P (operands[2])
6254 && (INTVAL (operands[2]) == 128
6255 || (INTVAL (operands[2]) < 0
6256 && INTVAL (operands[2]) != -128)))
6258 operands[2] = GEN_INT (-INTVAL (operands[2]));
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6265 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set_attr "mode" "SI")])
6270 (define_insn "*addsi_3"
6271 [(set (reg FLAGS_REG)
6272 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6273 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6274 (clobber (match_scratch:SI 0 "=r"))]
6275 "ix86_match_ccmode (insn, CCZmode)
6276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6277 /* Current assemblers are broken and do not allow @GOTOFF in
6278 ought but a memory context. */
6279 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6281 switch (get_attr_type (insn))
6284 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6285 if (operands[2] == const1_rtx)
6286 return "inc{l}\t%0";
6289 gcc_assert (operands[2] == constm1_rtx);
6290 return "dec{l}\t%0";
6294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6295 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6296 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6297 if (CONST_INT_P (operands[2])
6298 && (INTVAL (operands[2]) == 128
6299 || (INTVAL (operands[2]) < 0
6300 && INTVAL (operands[2]) != -128)))
6302 operands[2] = GEN_INT (-INTVAL (operands[2]));
6303 return "sub{l}\t{%2, %0|%0, %2}";
6305 return "add{l}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set_attr "mode" "SI")])
6314 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6315 (define_insn "*addsi_3_zext"
6316 [(set (reg FLAGS_REG)
6317 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6318 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6319 (set (match_operand:DI 0 "register_operand" "=r")
6320 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6321 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6322 && ix86_binary_operator_ok (PLUS, SImode, operands)
6323 /* Current assemblers are broken and do not allow @GOTOFF in
6324 ought but a memory context. */
6325 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6327 switch (get_attr_type (insn))
6330 if (operands[2] == const1_rtx)
6331 return "inc{l}\t%k0";
6334 gcc_assert (operands[2] == constm1_rtx);
6335 return "dec{l}\t%k0";
6339 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6340 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6341 if (CONST_INT_P (operands[2])
6342 && (INTVAL (operands[2]) == 128
6343 || (INTVAL (operands[2]) < 0
6344 && INTVAL (operands[2]) != -128)))
6346 operands[2] = GEN_INT (-INTVAL (operands[2]));
6347 return "sub{l}\t{%2, %k0|%k0, %2}";
6349 return "add{l}\t{%2, %k0|%k0, %2}";
6353 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6354 (const_string "incdec")
6355 (const_string "alu")))
6356 (set_attr "mode" "SI")])
6358 ; For comparisons against 1, -1 and 128, we may generate better code
6359 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6360 ; is matched then. We can't accept general immediate, because for
6361 ; case of overflows, the result is messed up.
6362 ; This pattern also don't hold of 0x80000000, since the value overflows
6364 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6365 ; only for comparisons not depending on it.
6366 (define_insn "*addsi_4"
6367 [(set (reg FLAGS_REG)
6368 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6369 (match_operand:SI 2 "const_int_operand" "n")))
6370 (clobber (match_scratch:SI 0 "=rm"))]
6371 "ix86_match_ccmode (insn, CCGCmode)
6372 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6374 switch (get_attr_type (insn))
6377 if (operands[2] == constm1_rtx)
6378 return "inc{l}\t%0";
6381 gcc_assert (operands[2] == const1_rtx);
6382 return "dec{l}\t%0";
6386 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6387 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6388 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6389 if ((INTVAL (operands[2]) == -128
6390 || (INTVAL (operands[2]) > 0
6391 && INTVAL (operands[2]) != 128)))
6392 return "sub{l}\t{%2, %0|%0, %2}";
6393 operands[2] = GEN_INT (-INTVAL (operands[2]));
6394 return "add{l}\t{%2, %0|%0, %2}";
6398 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6399 (const_string "incdec")
6400 (const_string "alu")))
6401 (set_attr "mode" "SI")])
6403 (define_insn "*addsi_5"
6404 [(set (reg FLAGS_REG)
6406 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6407 (match_operand:SI 2 "general_operand" "rmni"))
6409 (clobber (match_scratch:SI 0 "=r"))]
6410 "ix86_match_ccmode (insn, CCGOCmode)
6411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6412 /* Current assemblers are broken and do not allow @GOTOFF in
6413 ought but a memory context. */
6414 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6416 switch (get_attr_type (insn))
6419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6420 if (operands[2] == const1_rtx)
6421 return "inc{l}\t%0";
6424 gcc_assert (operands[2] == constm1_rtx);
6425 return "dec{l}\t%0";
6429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6430 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6431 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6432 if (CONST_INT_P (operands[2])
6433 && (INTVAL (operands[2]) == 128
6434 || (INTVAL (operands[2]) < 0
6435 && INTVAL (operands[2]) != -128)))
6437 operands[2] = GEN_INT (-INTVAL (operands[2]));
6438 return "sub{l}\t{%2, %0|%0, %2}";
6440 return "add{l}\t{%2, %0|%0, %2}";
6444 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "SI")])
6449 (define_expand "addhi3"
6450 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6451 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6452 (match_operand:HI 2 "general_operand" "")))
6453 (clobber (reg:CC FLAGS_REG))])]
6454 "TARGET_HIMODE_MATH"
6455 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6457 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6458 ;; type optimizations enabled by define-splits. This is not important
6459 ;; for PII, and in fact harmful because of partial register stalls.
6461 (define_insn "*addhi_1_lea"
6462 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6463 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6464 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6465 (clobber (reg:CC FLAGS_REG))]
6466 "!TARGET_PARTIAL_REG_STALL
6467 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6469 switch (get_attr_type (insn))
6474 if (operands[2] == const1_rtx)
6475 return "inc{w}\t%0";
6478 gcc_assert (operands[2] == constm1_rtx);
6479 return "dec{w}\t%0";
6483 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6485 if (CONST_INT_P (operands[2])
6486 && (INTVAL (operands[2]) == 128
6487 || (INTVAL (operands[2]) < 0
6488 && INTVAL (operands[2]) != -128)))
6490 operands[2] = GEN_INT (-INTVAL (operands[2]));
6491 return "sub{w}\t{%2, %0|%0, %2}";
6493 return "add{w}\t{%2, %0|%0, %2}";
6497 (if_then_else (eq_attr "alternative" "2")
6498 (const_string "lea")
6499 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6500 (const_string "incdec")
6501 (const_string "alu"))))
6502 (set_attr "mode" "HI,HI,SI")])
6504 (define_insn "*addhi_1"
6505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6506 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6507 (match_operand:HI 2 "general_operand" "ri,rm")))
6508 (clobber (reg:CC FLAGS_REG))]
6509 "TARGET_PARTIAL_REG_STALL
6510 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6512 switch (get_attr_type (insn))
6515 if (operands[2] == const1_rtx)
6516 return "inc{w}\t%0";
6519 gcc_assert (operands[2] == constm1_rtx);
6520 return "dec{w}\t%0";
6524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6526 if (CONST_INT_P (operands[2])
6527 && (INTVAL (operands[2]) == 128
6528 || (INTVAL (operands[2]) < 0
6529 && INTVAL (operands[2]) != -128)))
6531 operands[2] = GEN_INT (-INTVAL (operands[2]));
6532 return "sub{w}\t{%2, %0|%0, %2}";
6534 return "add{w}\t{%2, %0|%0, %2}";
6538 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6539 (const_string "incdec")
6540 (const_string "alu")))
6541 (set_attr "mode" "HI")])
6543 (define_insn "*addhi_2"
6544 [(set (reg FLAGS_REG)
6546 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6547 (match_operand:HI 2 "general_operand" "rmni,rni"))
6549 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6550 (plus:HI (match_dup 1) (match_dup 2)))]
6551 "ix86_match_ccmode (insn, CCGOCmode)
6552 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6554 switch (get_attr_type (insn))
6557 if (operands[2] == const1_rtx)
6558 return "inc{w}\t%0";
6561 gcc_assert (operands[2] == constm1_rtx);
6562 return "dec{w}\t%0";
6566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6568 if (CONST_INT_P (operands[2])
6569 && (INTVAL (operands[2]) == 128
6570 || (INTVAL (operands[2]) < 0
6571 && INTVAL (operands[2]) != -128)))
6573 operands[2] = GEN_INT (-INTVAL (operands[2]));
6574 return "sub{w}\t{%2, %0|%0, %2}";
6576 return "add{w}\t{%2, %0|%0, %2}";
6580 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6581 (const_string "incdec")
6582 (const_string "alu")))
6583 (set_attr "mode" "HI")])
6585 (define_insn "*addhi_3"
6586 [(set (reg FLAGS_REG)
6587 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6588 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6589 (clobber (match_scratch:HI 0 "=r"))]
6590 "ix86_match_ccmode (insn, CCZmode)
6591 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6593 switch (get_attr_type (insn))
6596 if (operands[2] == const1_rtx)
6597 return "inc{w}\t%0";
6600 gcc_assert (operands[2] == constm1_rtx);
6601 return "dec{w}\t%0";
6605 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6606 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6607 if (CONST_INT_P (operands[2])
6608 && (INTVAL (operands[2]) == 128
6609 || (INTVAL (operands[2]) < 0
6610 && INTVAL (operands[2]) != -128)))
6612 operands[2] = GEN_INT (-INTVAL (operands[2]));
6613 return "sub{w}\t{%2, %0|%0, %2}";
6615 return "add{w}\t{%2, %0|%0, %2}";
6619 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6620 (const_string "incdec")
6621 (const_string "alu")))
6622 (set_attr "mode" "HI")])
6624 ; See comments above addsi_4 for details.
6625 (define_insn "*addhi_4"
6626 [(set (reg FLAGS_REG)
6627 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6628 (match_operand:HI 2 "const_int_operand" "n")))
6629 (clobber (match_scratch:HI 0 "=rm"))]
6630 "ix86_match_ccmode (insn, CCGCmode)
6631 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6633 switch (get_attr_type (insn))
6636 if (operands[2] == constm1_rtx)
6637 return "inc{w}\t%0";
6640 gcc_assert (operands[2] == const1_rtx);
6641 return "dec{w}\t%0";
6645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6646 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6647 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6648 if ((INTVAL (operands[2]) == -128
6649 || (INTVAL (operands[2]) > 0
6650 && INTVAL (operands[2]) != 128)))
6651 return "sub{w}\t{%2, %0|%0, %2}";
6652 operands[2] = GEN_INT (-INTVAL (operands[2]));
6653 return "add{w}\t{%2, %0|%0, %2}";
6657 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6658 (const_string "incdec")
6659 (const_string "alu")))
6660 (set_attr "mode" "SI")])
6663 (define_insn "*addhi_5"
6664 [(set (reg FLAGS_REG)
6666 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6667 (match_operand:HI 2 "general_operand" "rmni"))
6669 (clobber (match_scratch:HI 0 "=r"))]
6670 "ix86_match_ccmode (insn, CCGOCmode)
6671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673 switch (get_attr_type (insn))
6676 if (operands[2] == const1_rtx)
6677 return "inc{w}\t%0";
6680 gcc_assert (operands[2] == constm1_rtx);
6681 return "dec{w}\t%0";
6685 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6686 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6687 if (CONST_INT_P (operands[2])
6688 && (INTVAL (operands[2]) == 128
6689 || (INTVAL (operands[2]) < 0
6690 && INTVAL (operands[2]) != -128)))
6692 operands[2] = GEN_INT (-INTVAL (operands[2]));
6693 return "sub{w}\t{%2, %0|%0, %2}";
6695 return "add{w}\t{%2, %0|%0, %2}";
6699 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6700 (const_string "incdec")
6701 (const_string "alu")))
6702 (set_attr "mode" "HI")])
6704 (define_expand "addqi3"
6705 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6706 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6707 (match_operand:QI 2 "general_operand" "")))
6708 (clobber (reg:CC FLAGS_REG))])]
6709 "TARGET_QIMODE_MATH"
6710 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6712 ;; %%% Potential partial reg stall on alternative 2. What to do?
6713 (define_insn "*addqi_1_lea"
6714 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6715 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6716 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6717 (clobber (reg:CC FLAGS_REG))]
6718 "!TARGET_PARTIAL_REG_STALL
6719 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6721 int widen = (which_alternative == 2);
6722 switch (get_attr_type (insn))
6727 if (operands[2] == const1_rtx)
6728 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6731 gcc_assert (operands[2] == constm1_rtx);
6732 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6738 if (CONST_INT_P (operands[2])
6739 && (INTVAL (operands[2]) == 128
6740 || (INTVAL (operands[2]) < 0
6741 && INTVAL (operands[2]) != -128)))
6743 operands[2] = GEN_INT (-INTVAL (operands[2]));
6745 return "sub{l}\t{%2, %k0|%k0, %2}";
6747 return "sub{b}\t{%2, %0|%0, %2}";
6750 return "add{l}\t{%k2, %k0|%k0, %k2}";
6752 return "add{b}\t{%2, %0|%0, %2}";
6756 (if_then_else (eq_attr "alternative" "3")
6757 (const_string "lea")
6758 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6759 (const_string "incdec")
6760 (const_string "alu"))))
6761 (set_attr "mode" "QI,QI,SI,SI")])
6763 (define_insn "*addqi_1"
6764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6765 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6766 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6767 (clobber (reg:CC FLAGS_REG))]
6768 "TARGET_PARTIAL_REG_STALL
6769 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6771 int widen = (which_alternative == 2);
6772 switch (get_attr_type (insn))
6775 if (operands[2] == const1_rtx)
6776 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6779 gcc_assert (operands[2] == constm1_rtx);
6780 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6784 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6785 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6786 if (CONST_INT_P (operands[2])
6787 && (INTVAL (operands[2]) == 128
6788 || (INTVAL (operands[2]) < 0
6789 && INTVAL (operands[2]) != -128)))
6791 operands[2] = GEN_INT (-INTVAL (operands[2]));
6793 return "sub{l}\t{%2, %k0|%k0, %2}";
6795 return "sub{b}\t{%2, %0|%0, %2}";
6798 return "add{l}\t{%k2, %k0|%k0, %k2}";
6800 return "add{b}\t{%2, %0|%0, %2}";
6804 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805 (const_string "incdec")
6806 (const_string "alu")))
6807 (set_attr "mode" "QI,QI,SI")])
6809 (define_insn "*addqi_1_slp"
6810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6811 (plus:QI (match_dup 0)
6812 (match_operand:QI 1 "general_operand" "qn,qnm")))
6813 (clobber (reg:CC FLAGS_REG))]
6814 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6815 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6817 switch (get_attr_type (insn))
6820 if (operands[1] == const1_rtx)
6821 return "inc{b}\t%0";
6824 gcc_assert (operands[1] == constm1_rtx);
6825 return "dec{b}\t%0";
6829 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6830 if (CONST_INT_P (operands[1])
6831 && INTVAL (operands[1]) < 0)
6833 operands[1] = GEN_INT (-INTVAL (operands[1]));
6834 return "sub{b}\t{%1, %0|%0, %1}";
6836 return "add{b}\t{%1, %0|%0, %1}";
6840 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6841 (const_string "incdec")
6842 (const_string "alu1")))
6843 (set (attr "memory")
6844 (if_then_else (match_operand 1 "memory_operand" "")
6845 (const_string "load")
6846 (const_string "none")))
6847 (set_attr "mode" "QI")])
6849 (define_insn "*addqi_2"
6850 [(set (reg FLAGS_REG)
6852 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6853 (match_operand:QI 2 "general_operand" "qmni,qni"))
6855 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6856 (plus:QI (match_dup 1) (match_dup 2)))]
6857 "ix86_match_ccmode (insn, CCGOCmode)
6858 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6860 switch (get_attr_type (insn))
6863 if (operands[2] == const1_rtx)
6864 return "inc{b}\t%0";
6867 gcc_assert (operands[2] == constm1_rtx
6868 || (CONST_INT_P (operands[2])
6869 && INTVAL (operands[2]) == 255));
6870 return "dec{b}\t%0";
6874 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6875 if (CONST_INT_P (operands[2])
6876 && INTVAL (operands[2]) < 0)
6878 operands[2] = GEN_INT (-INTVAL (operands[2]));
6879 return "sub{b}\t{%2, %0|%0, %2}";
6881 return "add{b}\t{%2, %0|%0, %2}";
6885 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6886 (const_string "incdec")
6887 (const_string "alu")))
6888 (set_attr "mode" "QI")])
6890 (define_insn "*addqi_3"
6891 [(set (reg FLAGS_REG)
6892 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6893 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6894 (clobber (match_scratch:QI 0 "=q"))]
6895 "ix86_match_ccmode (insn, CCZmode)
6896 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 switch (get_attr_type (insn))
6901 if (operands[2] == const1_rtx)
6902 return "inc{b}\t%0";
6905 gcc_assert (operands[2] == constm1_rtx
6906 || (CONST_INT_P (operands[2])
6907 && INTVAL (operands[2]) == 255));
6908 return "dec{b}\t%0";
6912 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6913 if (CONST_INT_P (operands[2])
6914 && INTVAL (operands[2]) < 0)
6916 operands[2] = GEN_INT (-INTVAL (operands[2]));
6917 return "sub{b}\t{%2, %0|%0, %2}";
6919 return "add{b}\t{%2, %0|%0, %2}";
6923 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6924 (const_string "incdec")
6925 (const_string "alu")))
6926 (set_attr "mode" "QI")])
6928 ; See comments above addsi_4 for details.
6929 (define_insn "*addqi_4"
6930 [(set (reg FLAGS_REG)
6931 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6932 (match_operand:QI 2 "const_int_operand" "n")))
6933 (clobber (match_scratch:QI 0 "=qm"))]
6934 "ix86_match_ccmode (insn, CCGCmode)
6935 && (INTVAL (operands[2]) & 0xff) != 0x80"
6937 switch (get_attr_type (insn))
6940 if (operands[2] == constm1_rtx
6941 || (CONST_INT_P (operands[2])
6942 && INTVAL (operands[2]) == 255))
6943 return "inc{b}\t%0";
6946 gcc_assert (operands[2] == const1_rtx);
6947 return "dec{b}\t%0";
6951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6952 if (INTVAL (operands[2]) < 0)
6954 operands[2] = GEN_INT (-INTVAL (operands[2]));
6955 return "add{b}\t{%2, %0|%0, %2}";
6957 return "sub{b}\t{%2, %0|%0, %2}";
6961 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6962 (const_string "incdec")
6963 (const_string "alu")))
6964 (set_attr "mode" "QI")])
6967 (define_insn "*addqi_5"
6968 [(set (reg FLAGS_REG)
6970 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6971 (match_operand:QI 2 "general_operand" "qmni"))
6973 (clobber (match_scratch:QI 0 "=q"))]
6974 "ix86_match_ccmode (insn, CCGOCmode)
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977 switch (get_attr_type (insn))
6980 if (operands[2] == const1_rtx)
6981 return "inc{b}\t%0";
6984 gcc_assert (operands[2] == constm1_rtx
6985 || (CONST_INT_P (operands[2])
6986 && INTVAL (operands[2]) == 255));
6987 return "dec{b}\t%0";
6991 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6992 if (CONST_INT_P (operands[2])
6993 && INTVAL (operands[2]) < 0)
6995 operands[2] = GEN_INT (-INTVAL (operands[2]));
6996 return "sub{b}\t{%2, %0|%0, %2}";
6998 return "add{b}\t{%2, %0|%0, %2}";
7002 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7003 (const_string "incdec")
7004 (const_string "alu")))
7005 (set_attr "mode" "QI")])
7008 (define_insn "addqi_ext_1"
7009 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7014 (match_operand 1 "ext_register_operand" "0")
7017 (match_operand:QI 2 "general_operand" "Qmn")))
7018 (clobber (reg:CC FLAGS_REG))]
7021 switch (get_attr_type (insn))
7024 if (operands[2] == const1_rtx)
7025 return "inc{b}\t%h0";
7028 gcc_assert (operands[2] == constm1_rtx
7029 || (CONST_INT_P (operands[2])
7030 && INTVAL (operands[2]) == 255));
7031 return "dec{b}\t%h0";
7035 return "add{b}\t{%2, %h0|%h0, %2}";
7039 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040 (const_string "incdec")
7041 (const_string "alu")))
7042 (set_attr "mode" "QI")])
7044 (define_insn "*addqi_ext_1_rex64"
7045 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7050 (match_operand 1 "ext_register_operand" "0")
7053 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7054 (clobber (reg:CC FLAGS_REG))]
7057 switch (get_attr_type (insn))
7060 if (operands[2] == const1_rtx)
7061 return "inc{b}\t%h0";
7064 gcc_assert (operands[2] == constm1_rtx
7065 || (CONST_INT_P (operands[2])
7066 && INTVAL (operands[2]) == 255));
7067 return "dec{b}\t%h0";
7071 return "add{b}\t{%2, %h0|%h0, %2}";
7075 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7076 (const_string "incdec")
7077 (const_string "alu")))
7078 (set_attr "mode" "QI")])
7080 (define_insn "*addqi_ext_2"
7081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7086 (match_operand 1 "ext_register_operand" "%0")
7090 (match_operand 2 "ext_register_operand" "Q")
7093 (clobber (reg:CC FLAGS_REG))]
7095 "add{b}\t{%h2, %h0|%h0, %h2}"
7096 [(set_attr "type" "alu")
7097 (set_attr "mode" "QI")])
7099 ;; The patterns that match these are at the end of this file.
7101 (define_expand "addxf3"
7102 [(set (match_operand:XF 0 "register_operand" "")
7103 (plus:XF (match_operand:XF 1 "register_operand" "")
7104 (match_operand:XF 2 "register_operand" "")))]
7108 (define_expand "add<mode>3"
7109 [(set (match_operand:MODEF 0 "register_operand" "")
7110 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7111 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7112 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7115 ;; Subtract instructions
7117 ;; %%% splits for subditi3
7119 (define_expand "subti3"
7120 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7121 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7122 (match_operand:TI 2 "x86_64_general_operand" "")))
7123 (clobber (reg:CC FLAGS_REG))])]
7125 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7127 (define_insn "*subti3_1"
7128 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7129 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7130 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7131 (clobber (reg:CC FLAGS_REG))]
7132 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7136 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7137 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7138 (match_operand:TI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))]
7140 "TARGET_64BIT && reload_completed"
7141 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7142 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7143 (parallel [(set (match_dup 3)
7144 (minus:DI (match_dup 4)
7145 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7147 (clobber (reg:CC FLAGS_REG))])]
7148 "split_ti (operands+0, 1, operands+0, operands+3);
7149 split_ti (operands+1, 1, operands+1, operands+4);
7150 split_ti (operands+2, 1, operands+2, operands+5);")
7152 ;; %%% splits for subsidi3
7154 (define_expand "subdi3"
7155 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7156 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7157 (match_operand:DI 2 "x86_64_general_operand" "")))
7158 (clobber (reg:CC FLAGS_REG))])]
7160 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7162 (define_insn "*subdi3_1"
7163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7164 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7165 (match_operand:DI 2 "general_operand" "roiF,riF")))
7166 (clobber (reg:CC FLAGS_REG))]
7167 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7171 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7172 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7173 (match_operand:DI 2 "general_operand" "")))
7174 (clobber (reg:CC FLAGS_REG))]
7175 "!TARGET_64BIT && reload_completed"
7176 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7177 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7178 (parallel [(set (match_dup 3)
7179 (minus:SI (match_dup 4)
7180 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7182 (clobber (reg:CC FLAGS_REG))])]
7183 "split_di (operands+0, 1, operands+0, operands+3);
7184 split_di (operands+1, 1, operands+1, operands+4);
7185 split_di (operands+2, 1, operands+2, operands+5);")
7187 (define_insn "subdi3_carry_rex64"
7188 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7189 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7190 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7191 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7192 (clobber (reg:CC FLAGS_REG))]
7193 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7194 "sbb{q}\t{%2, %0|%0, %2}"
7195 [(set_attr "type" "alu")
7196 (set_attr "pent_pair" "pu")
7197 (set_attr "mode" "DI")])
7199 (define_insn "*subdi_1_rex64"
7200 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7201 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7202 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7203 (clobber (reg:CC FLAGS_REG))]
7204 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7205 "sub{q}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "alu")
7207 (set_attr "mode" "DI")])
7209 (define_insn "*subdi_2_rex64"
7210 [(set (reg FLAGS_REG)
7212 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7213 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7215 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7216 (minus:DI (match_dup 1) (match_dup 2)))]
7217 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7218 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7219 "sub{q}\t{%2, %0|%0, %2}"
7220 [(set_attr "type" "alu")
7221 (set_attr "mode" "DI")])
7223 (define_insn "*subdi_3_rex63"
7224 [(set (reg FLAGS_REG)
7225 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7226 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7227 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7228 (minus:DI (match_dup 1) (match_dup 2)))]
7229 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7230 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7231 "sub{q}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "alu")
7233 (set_attr "mode" "DI")])
7235 (define_insn "subqi3_carry"
7236 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7237 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7238 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7239 (match_operand:QI 2 "general_operand" "qi,qm"))))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7242 "sbb{b}\t{%2, %0|%0, %2}"
7243 [(set_attr "type" "alu")
7244 (set_attr "pent_pair" "pu")
7245 (set_attr "mode" "QI")])
7247 (define_insn "subhi3_carry"
7248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7249 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7250 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7251 (match_operand:HI 2 "general_operand" "ri,rm"))))
7252 (clobber (reg:CC FLAGS_REG))]
7253 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7254 "sbb{w}\t{%2, %0|%0, %2}"
7255 [(set_attr "type" "alu")
7256 (set_attr "pent_pair" "pu")
7257 (set_attr "mode" "HI")])
7259 (define_insn "subsi3_carry"
7260 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7261 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7262 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7263 (match_operand:SI 2 "general_operand" "ri,rm"))))
7264 (clobber (reg:CC FLAGS_REG))]
7265 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7266 "sbb{l}\t{%2, %0|%0, %2}"
7267 [(set_attr "type" "alu")
7268 (set_attr "pent_pair" "pu")
7269 (set_attr "mode" "SI")])
7271 (define_insn "subsi3_carry_zext"
7272 [(set (match_operand:DI 0 "register_operand" "=r")
7274 (minus:SI (match_operand:SI 1 "register_operand" "0")
7275 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7276 (match_operand:SI 2 "general_operand" "g")))))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7279 "sbb{l}\t{%2, %k0|%k0, %2}"
7280 [(set_attr "type" "alu")
7281 (set_attr "pent_pair" "pu")
7282 (set_attr "mode" "SI")])
7284 (define_expand "subsi3"
7285 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7286 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7287 (match_operand:SI 2 "general_operand" "")))
7288 (clobber (reg:CC FLAGS_REG))])]
7290 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7292 (define_insn "*subsi_1"
7293 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7294 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7295 (match_operand:SI 2 "general_operand" "ri,rm")))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7298 "sub{l}\t{%2, %0|%0, %2}"
7299 [(set_attr "type" "alu")
7300 (set_attr "mode" "SI")])
7302 (define_insn "*subsi_1_zext"
7303 [(set (match_operand:DI 0 "register_operand" "=r")
7305 (minus:SI (match_operand:SI 1 "register_operand" "0")
7306 (match_operand:SI 2 "general_operand" "g"))))
7307 (clobber (reg:CC FLAGS_REG))]
7308 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7309 "sub{l}\t{%2, %k0|%k0, %2}"
7310 [(set_attr "type" "alu")
7311 (set_attr "mode" "SI")])
7313 (define_insn "*subsi_2"
7314 [(set (reg FLAGS_REG)
7316 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7317 (match_operand:SI 2 "general_operand" "ri,rm"))
7319 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7320 (minus:SI (match_dup 1) (match_dup 2)))]
7321 "ix86_match_ccmode (insn, CCGOCmode)
7322 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7323 "sub{l}\t{%2, %0|%0, %2}"
7324 [(set_attr "type" "alu")
7325 (set_attr "mode" "SI")])
7327 (define_insn "*subsi_2_zext"
7328 [(set (reg FLAGS_REG)
7330 (minus:SI (match_operand:SI 1 "register_operand" "0")
7331 (match_operand:SI 2 "general_operand" "g"))
7333 (set (match_operand:DI 0 "register_operand" "=r")
7335 (minus:SI (match_dup 1)
7337 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7338 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339 "sub{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "mode" "SI")])
7343 (define_insn "*subsi_3"
7344 [(set (reg FLAGS_REG)
7345 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7346 (match_operand:SI 2 "general_operand" "ri,rm")))
7347 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7348 (minus:SI (match_dup 1) (match_dup 2)))]
7349 "ix86_match_ccmode (insn, CCmode)
7350 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7351 "sub{l}\t{%2, %0|%0, %2}"
7352 [(set_attr "type" "alu")
7353 (set_attr "mode" "SI")])
7355 (define_insn "*subsi_3_zext"
7356 [(set (reg FLAGS_REG)
7357 (compare (match_operand:SI 1 "register_operand" "0")
7358 (match_operand:SI 2 "general_operand" "g")))
7359 (set (match_operand:DI 0 "register_operand" "=r")
7361 (minus:SI (match_dup 1)
7363 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7364 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7365 "sub{l}\t{%2, %1|%1, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "DI")])
7369 (define_expand "subhi3"
7370 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7371 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7372 (match_operand:HI 2 "general_operand" "")))
7373 (clobber (reg:CC FLAGS_REG))])]
7374 "TARGET_HIMODE_MATH"
7375 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7377 (define_insn "*subhi_1"
7378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7379 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7380 (match_operand:HI 2 "general_operand" "ri,rm")))
7381 (clobber (reg:CC FLAGS_REG))]
7382 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7383 "sub{w}\t{%2, %0|%0, %2}"
7384 [(set_attr "type" "alu")
7385 (set_attr "mode" "HI")])
7387 (define_insn "*subhi_2"
7388 [(set (reg FLAGS_REG)
7390 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7391 (match_operand:HI 2 "general_operand" "ri,rm"))
7393 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7394 (minus:HI (match_dup 1) (match_dup 2)))]
7395 "ix86_match_ccmode (insn, CCGOCmode)
7396 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7397 "sub{w}\t{%2, %0|%0, %2}"
7398 [(set_attr "type" "alu")
7399 (set_attr "mode" "HI")])
7401 (define_insn "*subhi_3"
7402 [(set (reg FLAGS_REG)
7403 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7404 (match_operand:HI 2 "general_operand" "ri,rm")))
7405 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7406 (minus:HI (match_dup 1) (match_dup 2)))]
7407 "ix86_match_ccmode (insn, CCmode)
7408 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7409 "sub{w}\t{%2, %0|%0, %2}"
7410 [(set_attr "type" "alu")
7411 (set_attr "mode" "HI")])
7413 (define_expand "subqi3"
7414 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7415 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7416 (match_operand:QI 2 "general_operand" "")))
7417 (clobber (reg:CC FLAGS_REG))])]
7418 "TARGET_QIMODE_MATH"
7419 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7421 (define_insn "*subqi_1"
7422 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7423 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7424 (match_operand:QI 2 "general_operand" "qn,qmn")))
7425 (clobber (reg:CC FLAGS_REG))]
7426 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7427 "sub{b}\t{%2, %0|%0, %2}"
7428 [(set_attr "type" "alu")
7429 (set_attr "mode" "QI")])
7431 (define_insn "*subqi_1_slp"
7432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7433 (minus:QI (match_dup 0)
7434 (match_operand:QI 1 "general_operand" "qn,qmn")))
7435 (clobber (reg:CC FLAGS_REG))]
7436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7438 "sub{b}\t{%1, %0|%0, %1}"
7439 [(set_attr "type" "alu1")
7440 (set_attr "mode" "QI")])
7442 (define_insn "*subqi_2"
7443 [(set (reg FLAGS_REG)
7445 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7446 (match_operand:QI 2 "general_operand" "qi,qm"))
7448 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7449 (minus:HI (match_dup 1) (match_dup 2)))]
7450 "ix86_match_ccmode (insn, CCGOCmode)
7451 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7452 "sub{b}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "alu")
7454 (set_attr "mode" "QI")])
7456 (define_insn "*subqi_3"
7457 [(set (reg FLAGS_REG)
7458 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7459 (match_operand:QI 2 "general_operand" "qi,qm")))
7460 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7461 (minus:HI (match_dup 1) (match_dup 2)))]
7462 "ix86_match_ccmode (insn, CCmode)
7463 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7464 "sub{b}\t{%2, %0|%0, %2}"
7465 [(set_attr "type" "alu")
7466 (set_attr "mode" "QI")])
7468 ;; The patterns that match these are at the end of this file.
7470 (define_expand "subxf3"
7471 [(set (match_operand:XF 0 "register_operand" "")
7472 (minus:XF (match_operand:XF 1 "register_operand" "")
7473 (match_operand:XF 2 "register_operand" "")))]
7477 (define_expand "sub<mode>3"
7478 [(set (match_operand:MODEF 0 "register_operand" "")
7479 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7480 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7481 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7484 ;; Multiply instructions
7486 (define_expand "muldi3"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (mult:DI (match_operand:DI 1 "register_operand" "")
7489 (match_operand:DI 2 "x86_64_general_operand" "")))
7490 (clobber (reg:CC FLAGS_REG))])]
7495 ;; IMUL reg64, reg64, imm8 Direct
7496 ;; IMUL reg64, mem64, imm8 VectorPath
7497 ;; IMUL reg64, reg64, imm32 Direct
7498 ;; IMUL reg64, mem64, imm32 VectorPath
7499 ;; IMUL reg64, reg64 Direct
7500 ;; IMUL reg64, mem64 Direct
7502 (define_insn "*muldi3_1_rex64"
7503 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7504 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7505 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7506 (clobber (reg:CC FLAGS_REG))]
7508 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510 imul{q}\t{%2, %1, %0|%0, %1, %2}
7511 imul{q}\t{%2, %1, %0|%0, %1, %2}
7512 imul{q}\t{%2, %0|%0, %2}"
7513 [(set_attr "type" "imul")
7514 (set_attr "prefix_0f" "0,0,1")
7515 (set (attr "athlon_decode")
7516 (cond [(eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (eq_attr "alternative" "1")
7519 (const_string "vector")
7520 (and (eq_attr "alternative" "2")
7521 (match_operand 1 "memory_operand" ""))
7522 (const_string "vector")]
7523 (const_string "direct")))
7524 (set (attr "amdfam10_decode")
7525 (cond [(and (eq_attr "alternative" "0,1")
7526 (match_operand 1 "memory_operand" ""))
7527 (const_string "vector")]
7528 (const_string "direct")))
7529 (set_attr "mode" "DI")])
7531 (define_expand "mulsi3"
7532 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7533 (mult:SI (match_operand:SI 1 "register_operand" "")
7534 (match_operand:SI 2 "general_operand" "")))
7535 (clobber (reg:CC FLAGS_REG))])]
7540 ;; IMUL reg32, reg32, imm8 Direct
7541 ;; IMUL reg32, mem32, imm8 VectorPath
7542 ;; IMUL reg32, reg32, imm32 Direct
7543 ;; IMUL reg32, mem32, imm32 VectorPath
7544 ;; IMUL reg32, reg32 Direct
7545 ;; IMUL reg32, mem32 Direct
7547 (define_insn "*mulsi3_1"
7548 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7550 (match_operand:SI 2 "general_operand" "K,i,mr")))
7551 (clobber (reg:CC FLAGS_REG))]
7552 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7554 imul{l}\t{%2, %1, %0|%0, %1, %2}
7555 imul{l}\t{%2, %1, %0|%0, %1, %2}
7556 imul{l}\t{%2, %0|%0, %2}"
7557 [(set_attr "type" "imul")
7558 (set_attr "prefix_0f" "0,0,1")
7559 (set (attr "athlon_decode")
7560 (cond [(eq_attr "cpu" "athlon")
7561 (const_string "vector")
7562 (eq_attr "alternative" "1")
7563 (const_string "vector")
7564 (and (eq_attr "alternative" "2")
7565 (match_operand 1 "memory_operand" ""))
7566 (const_string "vector")]
7567 (const_string "direct")))
7568 (set (attr "amdfam10_decode")
7569 (cond [(and (eq_attr "alternative" "0,1")
7570 (match_operand 1 "memory_operand" ""))
7571 (const_string "vector")]
7572 (const_string "direct")))
7573 (set_attr "mode" "SI")])
7575 (define_insn "*mulsi3_1_zext"
7576 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7578 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7579 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7580 (clobber (reg:CC FLAGS_REG))]
7582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7584 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7586 imul{l}\t{%2, %k0|%k0, %2}"
7587 [(set_attr "type" "imul")
7588 (set_attr "prefix_0f" "0,0,1")
7589 (set (attr "athlon_decode")
7590 (cond [(eq_attr "cpu" "athlon")
7591 (const_string "vector")
7592 (eq_attr "alternative" "1")
7593 (const_string "vector")
7594 (and (eq_attr "alternative" "2")
7595 (match_operand 1 "memory_operand" ""))
7596 (const_string "vector")]
7597 (const_string "direct")))
7598 (set (attr "amdfam10_decode")
7599 (cond [(and (eq_attr "alternative" "0,1")
7600 (match_operand 1 "memory_operand" ""))
7601 (const_string "vector")]
7602 (const_string "direct")))
7603 (set_attr "mode" "SI")])
7605 (define_expand "mulhi3"
7606 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7607 (mult:HI (match_operand:HI 1 "register_operand" "")
7608 (match_operand:HI 2 "general_operand" "")))
7609 (clobber (reg:CC FLAGS_REG))])]
7610 "TARGET_HIMODE_MATH"
7614 ;; IMUL reg16, reg16, imm8 VectorPath
7615 ;; IMUL reg16, mem16, imm8 VectorPath
7616 ;; IMUL reg16, reg16, imm16 VectorPath
7617 ;; IMUL reg16, mem16, imm16 VectorPath
7618 ;; IMUL reg16, reg16 Direct
7619 ;; IMUL reg16, mem16 Direct
7620 (define_insn "*mulhi3_1"
7621 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7622 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7623 (match_operand:HI 2 "general_operand" "K,i,mr")))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7627 imul{w}\t{%2, %1, %0|%0, %1, %2}
7628 imul{w}\t{%2, %1, %0|%0, %1, %2}
7629 imul{w}\t{%2, %0|%0, %2}"
7630 [(set_attr "type" "imul")
7631 (set_attr "prefix_0f" "0,0,1")
7632 (set (attr "athlon_decode")
7633 (cond [(eq_attr "cpu" "athlon")
7634 (const_string "vector")
7635 (eq_attr "alternative" "1,2")
7636 (const_string "vector")]
7637 (const_string "direct")))
7638 (set (attr "amdfam10_decode")
7639 (cond [(eq_attr "alternative" "0,1")
7640 (const_string "vector")]
7641 (const_string "direct")))
7642 (set_attr "mode" "HI")])
7644 (define_expand "mulqi3"
7645 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7646 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7647 (match_operand:QI 2 "register_operand" "")))
7648 (clobber (reg:CC FLAGS_REG))])]
7649 "TARGET_QIMODE_MATH"
7656 (define_insn "*mulqi3_1"
7657 [(set (match_operand:QI 0 "register_operand" "=a")
7658 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7659 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7660 (clobber (reg:CC FLAGS_REG))]
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7664 [(set_attr "type" "imul")
7665 (set_attr "length_immediate" "0")
7666 (set (attr "athlon_decode")
7667 (if_then_else (eq_attr "cpu" "athlon")
7668 (const_string "vector")
7669 (const_string "direct")))
7670 (set_attr "amdfam10_decode" "direct")
7671 (set_attr "mode" "QI")])
7673 (define_expand "umulqihi3"
7674 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7675 (mult:HI (zero_extend:HI
7676 (match_operand:QI 1 "nonimmediate_operand" ""))
7678 (match_operand:QI 2 "register_operand" ""))))
7679 (clobber (reg:CC FLAGS_REG))])]
7680 "TARGET_QIMODE_MATH"
7683 (define_insn "*umulqihi3_1"
7684 [(set (match_operand:HI 0 "register_operand" "=a")
7685 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7686 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7687 (clobber (reg:CC FLAGS_REG))]
7689 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7691 [(set_attr "type" "imul")
7692 (set_attr "length_immediate" "0")
7693 (set (attr "athlon_decode")
7694 (if_then_else (eq_attr "cpu" "athlon")
7695 (const_string "vector")
7696 (const_string "direct")))
7697 (set_attr "amdfam10_decode" "direct")
7698 (set_attr "mode" "QI")])
7700 (define_expand "mulqihi3"
7701 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7702 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7703 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7704 (clobber (reg:CC FLAGS_REG))])]
7705 "TARGET_QIMODE_MATH"
7708 (define_insn "*mulqihi3_insn"
7709 [(set (match_operand:HI 0 "register_operand" "=a")
7710 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7711 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7712 (clobber (reg:CC FLAGS_REG))]
7714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7716 [(set_attr "type" "imul")
7717 (set_attr "length_immediate" "0")
7718 (set (attr "athlon_decode")
7719 (if_then_else (eq_attr "cpu" "athlon")
7720 (const_string "vector")
7721 (const_string "direct")))
7722 (set_attr "amdfam10_decode" "direct")
7723 (set_attr "mode" "QI")])
7725 (define_expand "umulditi3"
7726 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7727 (mult:TI (zero_extend:TI
7728 (match_operand:DI 1 "nonimmediate_operand" ""))
7730 (match_operand:DI 2 "register_operand" ""))))
7731 (clobber (reg:CC FLAGS_REG))])]
7735 (define_insn "*umulditi3_insn"
7736 [(set (match_operand:TI 0 "register_operand" "=A")
7737 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7738 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7739 (clobber (reg:CC FLAGS_REG))]
7741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7743 [(set_attr "type" "imul")
7744 (set_attr "length_immediate" "0")
7745 (set (attr "athlon_decode")
7746 (if_then_else (eq_attr "cpu" "athlon")
7747 (const_string "vector")
7748 (const_string "double")))
7749 (set_attr "amdfam10_decode" "double")
7750 (set_attr "mode" "DI")])
7752 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7753 (define_expand "umulsidi3"
7754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7755 (mult:DI (zero_extend:DI
7756 (match_operand:SI 1 "nonimmediate_operand" ""))
7758 (match_operand:SI 2 "register_operand" ""))))
7759 (clobber (reg:CC FLAGS_REG))])]
7763 (define_insn "*umulsidi3_insn"
7764 [(set (match_operand:DI 0 "register_operand" "=A")
7765 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7766 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7767 (clobber (reg:CC FLAGS_REG))]
7769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771 [(set_attr "type" "imul")
7772 (set_attr "length_immediate" "0")
7773 (set (attr "athlon_decode")
7774 (if_then_else (eq_attr "cpu" "athlon")
7775 (const_string "vector")
7776 (const_string "double")))
7777 (set_attr "amdfam10_decode" "double")
7778 (set_attr "mode" "SI")])
7780 (define_expand "mulditi3"
7781 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7782 (mult:TI (sign_extend:TI
7783 (match_operand:DI 1 "nonimmediate_operand" ""))
7785 (match_operand:DI 2 "register_operand" ""))))
7786 (clobber (reg:CC FLAGS_REG))])]
7790 (define_insn "*mulditi3_insn"
7791 [(set (match_operand:TI 0 "register_operand" "=A")
7792 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7793 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7794 (clobber (reg:CC FLAGS_REG))]
7796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7798 [(set_attr "type" "imul")
7799 (set_attr "length_immediate" "0")
7800 (set (attr "athlon_decode")
7801 (if_then_else (eq_attr "cpu" "athlon")
7802 (const_string "vector")
7803 (const_string "double")))
7804 (set_attr "amdfam10_decode" "double")
7805 (set_attr "mode" "DI")])
7807 (define_expand "mulsidi3"
7808 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7809 (mult:DI (sign_extend:DI
7810 (match_operand:SI 1 "nonimmediate_operand" ""))
7812 (match_operand:SI 2 "register_operand" ""))))
7813 (clobber (reg:CC FLAGS_REG))])]
7817 (define_insn "*mulsidi3_insn"
7818 [(set (match_operand:DI 0 "register_operand" "=A")
7819 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7820 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7821 (clobber (reg:CC FLAGS_REG))]
7823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7825 [(set_attr "type" "imul")
7826 (set_attr "length_immediate" "0")
7827 (set (attr "athlon_decode")
7828 (if_then_else (eq_attr "cpu" "athlon")
7829 (const_string "vector")
7830 (const_string "double")))
7831 (set_attr "amdfam10_decode" "double")
7832 (set_attr "mode" "SI")])
7834 (define_expand "umuldi3_highpart"
7835 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7838 (mult:TI (zero_extend:TI
7839 (match_operand:DI 1 "nonimmediate_operand" ""))
7841 (match_operand:DI 2 "register_operand" "")))
7843 (clobber (match_scratch:DI 3 ""))
7844 (clobber (reg:CC FLAGS_REG))])]
7848 (define_insn "*umuldi3_highpart_rex64"
7849 [(set (match_operand:DI 0 "register_operand" "=d")
7852 (mult:TI (zero_extend:TI
7853 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7855 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7857 (clobber (match_scratch:DI 3 "=1"))
7858 (clobber (reg:CC FLAGS_REG))]
7860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7862 [(set_attr "type" "imul")
7863 (set_attr "length_immediate" "0")
7864 (set (attr "athlon_decode")
7865 (if_then_else (eq_attr "cpu" "athlon")
7866 (const_string "vector")
7867 (const_string "double")))
7868 (set_attr "amdfam10_decode" "double")
7869 (set_attr "mode" "DI")])
7871 (define_expand "umulsi3_highpart"
7872 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875 (mult:DI (zero_extend:DI
7876 (match_operand:SI 1 "nonimmediate_operand" ""))
7878 (match_operand:SI 2 "register_operand" "")))
7880 (clobber (match_scratch:SI 3 ""))
7881 (clobber (reg:CC FLAGS_REG))])]
7885 (define_insn "*umulsi3_highpart_insn"
7886 [(set (match_operand:SI 0 "register_operand" "=d")
7889 (mult:DI (zero_extend:DI
7890 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7892 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7894 (clobber (match_scratch:SI 3 "=1"))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7898 [(set_attr "type" "imul")
7899 (set_attr "length_immediate" "0")
7900 (set (attr "athlon_decode")
7901 (if_then_else (eq_attr "cpu" "athlon")
7902 (const_string "vector")
7903 (const_string "double")))
7904 (set_attr "amdfam10_decode" "double")
7905 (set_attr "mode" "SI")])
7907 (define_insn "*umulsi3_highpart_zext"
7908 [(set (match_operand:DI 0 "register_operand" "=d")
7909 (zero_extend:DI (truncate:SI
7911 (mult:DI (zero_extend:DI
7912 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7914 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7916 (clobber (match_scratch:SI 3 "=1"))
7917 (clobber (reg:CC FLAGS_REG))]
7919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7921 [(set_attr "type" "imul")
7922 (set_attr "length_immediate" "0")
7923 (set (attr "athlon_decode")
7924 (if_then_else (eq_attr "cpu" "athlon")
7925 (const_string "vector")
7926 (const_string "double")))
7927 (set_attr "amdfam10_decode" "double")
7928 (set_attr "mode" "SI")])
7930 (define_expand "smuldi3_highpart"
7931 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7934 (mult:TI (sign_extend:TI
7935 (match_operand:DI 1 "nonimmediate_operand" ""))
7937 (match_operand:DI 2 "register_operand" "")))
7939 (clobber (match_scratch:DI 3 ""))
7940 (clobber (reg:CC FLAGS_REG))])]
7944 (define_insn "*smuldi3_highpart_rex64"
7945 [(set (match_operand:DI 0 "register_operand" "=d")
7948 (mult:TI (sign_extend:TI
7949 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7951 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7953 (clobber (match_scratch:DI 3 "=1"))
7954 (clobber (reg:CC FLAGS_REG))]
7956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7958 [(set_attr "type" "imul")
7959 (set (attr "athlon_decode")
7960 (if_then_else (eq_attr "cpu" "athlon")
7961 (const_string "vector")
7962 (const_string "double")))
7963 (set_attr "amdfam10_decode" "double")
7964 (set_attr "mode" "DI")])
7966 (define_expand "smulsi3_highpart"
7967 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7970 (mult:DI (sign_extend:DI
7971 (match_operand:SI 1 "nonimmediate_operand" ""))
7973 (match_operand:SI 2 "register_operand" "")))
7975 (clobber (match_scratch:SI 3 ""))
7976 (clobber (reg:CC FLAGS_REG))])]
7980 (define_insn "*smulsi3_highpart_insn"
7981 [(set (match_operand:SI 0 "register_operand" "=d")
7984 (mult:DI (sign_extend:DI
7985 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7987 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7989 (clobber (match_scratch:SI 3 "=1"))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7993 [(set_attr "type" "imul")
7994 (set (attr "athlon_decode")
7995 (if_then_else (eq_attr "cpu" "athlon")
7996 (const_string "vector")
7997 (const_string "double")))
7998 (set_attr "amdfam10_decode" "double")
7999 (set_attr "mode" "SI")])
8001 (define_insn "*smulsi3_highpart_zext"
8002 [(set (match_operand:DI 0 "register_operand" "=d")
8003 (zero_extend:DI (truncate:SI
8005 (mult:DI (sign_extend:DI
8006 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8008 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8010 (clobber (match_scratch:SI 3 "=1"))
8011 (clobber (reg:CC FLAGS_REG))]
8013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8015 [(set_attr "type" "imul")
8016 (set (attr "athlon_decode")
8017 (if_then_else (eq_attr "cpu" "athlon")
8018 (const_string "vector")
8019 (const_string "double")))
8020 (set_attr "amdfam10_decode" "double")
8021 (set_attr "mode" "SI")])
8023 ;; The patterns that match these are at the end of this file.
8025 (define_expand "mulxf3"
8026 [(set (match_operand:XF 0 "register_operand" "")
8027 (mult:XF (match_operand:XF 1 "register_operand" "")
8028 (match_operand:XF 2 "register_operand" "")))]
8032 (define_expand "mul<mode>3"
8033 [(set (match_operand:MODEF 0 "register_operand" "")
8034 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8035 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8036 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8039 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8042 ;; Divide instructions
8044 (define_insn "divqi3"
8045 [(set (match_operand:QI 0 "register_operand" "=a")
8046 (div:QI (match_operand:HI 1 "register_operand" "0")
8047 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "TARGET_QIMODE_MATH"
8051 [(set_attr "type" "idiv")
8052 (set_attr "mode" "QI")])
8054 (define_insn "udivqi3"
8055 [(set (match_operand:QI 0 "register_operand" "=a")
8056 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8057 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8058 (clobber (reg:CC FLAGS_REG))]
8059 "TARGET_QIMODE_MATH"
8061 [(set_attr "type" "idiv")
8062 (set_attr "mode" "QI")])
8064 ;; The patterns that match these are at the end of this file.
8066 (define_expand "divxf3"
8067 [(set (match_operand:XF 0 "register_operand" "")
8068 (div:XF (match_operand:XF 1 "register_operand" "")
8069 (match_operand:XF 2 "register_operand" "")))]
8073 (define_expand "divdf3"
8074 [(set (match_operand:DF 0 "register_operand" "")
8075 (div:DF (match_operand:DF 1 "register_operand" "")
8076 (match_operand:DF 2 "nonimmediate_operand" "")))]
8077 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8080 (define_expand "divsf3"
8081 [(set (match_operand:SF 0 "register_operand" "")
8082 (div:SF (match_operand:SF 1 "register_operand" "")
8083 (match_operand:SF 2 "nonimmediate_operand" "")))]
8084 "TARGET_80387 || TARGET_SSE_MATH"
8086 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8087 && flag_finite_math_only && !flag_trapping_math
8088 && flag_unsafe_math_optimizations)
8090 ix86_emit_swdivsf (operands[0], operands[1],
8091 operands[2], SFmode);
8096 ;; Remainder instructions.
8098 (define_expand "divmoddi4"
8099 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8100 (div:DI (match_operand:DI 1 "register_operand" "")
8101 (match_operand:DI 2 "nonimmediate_operand" "")))
8102 (set (match_operand:DI 3 "register_operand" "")
8103 (mod:DI (match_dup 1) (match_dup 2)))
8104 (clobber (reg:CC FLAGS_REG))])]
8108 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8109 ;; Penalize eax case slightly because it results in worse scheduling
8111 (define_insn "*divmoddi4_nocltd_rex64"
8112 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8113 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8114 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8115 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8116 (mod:DI (match_dup 2) (match_dup 3)))
8117 (clobber (reg:CC FLAGS_REG))]
8118 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8120 [(set_attr "type" "multi")])
8122 (define_insn "*divmoddi4_cltd_rex64"
8123 [(set (match_operand:DI 0 "register_operand" "=a")
8124 (div:DI (match_operand:DI 2 "register_operand" "a")
8125 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8126 (set (match_operand:DI 1 "register_operand" "=&d")
8127 (mod:DI (match_dup 2) (match_dup 3)))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8131 [(set_attr "type" "multi")])
8133 (define_insn "*divmoddi_noext_rex64"
8134 [(set (match_operand:DI 0 "register_operand" "=a")
8135 (div:DI (match_operand:DI 1 "register_operand" "0")
8136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8137 (set (match_operand:DI 3 "register_operand" "=d")
8138 (mod:DI (match_dup 1) (match_dup 2)))
8139 (use (match_operand:DI 4 "register_operand" "3"))
8140 (clobber (reg:CC FLAGS_REG))]
8143 [(set_attr "type" "idiv")
8144 (set_attr "mode" "DI")])
8147 [(set (match_operand:DI 0 "register_operand" "")
8148 (div:DI (match_operand:DI 1 "register_operand" "")
8149 (match_operand:DI 2 "nonimmediate_operand" "")))
8150 (set (match_operand:DI 3 "register_operand" "")
8151 (mod:DI (match_dup 1) (match_dup 2)))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "TARGET_64BIT && reload_completed"
8154 [(parallel [(set (match_dup 3)
8155 (ashiftrt:DI (match_dup 4) (const_int 63)))
8156 (clobber (reg:CC FLAGS_REG))])
8157 (parallel [(set (match_dup 0)
8158 (div:DI (reg:DI 0) (match_dup 2)))
8160 (mod:DI (reg:DI 0) (match_dup 2)))
8162 (clobber (reg:CC FLAGS_REG))])]
8164 /* Avoid use of cltd in favor of a mov+shift. */
8165 if (!TARGET_USE_CLTD && !optimize_size)
8167 if (true_regnum (operands[1]))
8168 emit_move_insn (operands[0], operands[1]);
8170 emit_move_insn (operands[3], operands[1]);
8171 operands[4] = operands[3];
8175 gcc_assert (!true_regnum (operands[1]));
8176 operands[4] = operands[1];
8181 (define_expand "divmodsi4"
8182 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8183 (div:SI (match_operand:SI 1 "register_operand" "")
8184 (match_operand:SI 2 "nonimmediate_operand" "")))
8185 (set (match_operand:SI 3 "register_operand" "")
8186 (mod:SI (match_dup 1) (match_dup 2)))
8187 (clobber (reg:CC FLAGS_REG))])]
8191 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8192 ;; Penalize eax case slightly because it results in worse scheduling
8194 (define_insn "*divmodsi4_nocltd"
8195 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8196 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8197 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8198 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8199 (mod:SI (match_dup 2) (match_dup 3)))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "!optimize_size && !TARGET_USE_CLTD"
8203 [(set_attr "type" "multi")])
8205 (define_insn "*divmodsi4_cltd"
8206 [(set (match_operand:SI 0 "register_operand" "=a")
8207 (div:SI (match_operand:SI 2 "register_operand" "a")
8208 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8209 (set (match_operand:SI 1 "register_operand" "=&d")
8210 (mod:SI (match_dup 2) (match_dup 3)))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "optimize_size || TARGET_USE_CLTD"
8214 [(set_attr "type" "multi")])
8216 (define_insn "*divmodsi_noext"
8217 [(set (match_operand:SI 0 "register_operand" "=a")
8218 (div:SI (match_operand:SI 1 "register_operand" "0")
8219 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8220 (set (match_operand:SI 3 "register_operand" "=d")
8221 (mod:SI (match_dup 1) (match_dup 2)))
8222 (use (match_operand:SI 4 "register_operand" "3"))
8223 (clobber (reg:CC FLAGS_REG))]
8226 [(set_attr "type" "idiv")
8227 (set_attr "mode" "SI")])
8230 [(set (match_operand:SI 0 "register_operand" "")
8231 (div:SI (match_operand:SI 1 "register_operand" "")
8232 (match_operand:SI 2 "nonimmediate_operand" "")))
8233 (set (match_operand:SI 3 "register_operand" "")
8234 (mod:SI (match_dup 1) (match_dup 2)))
8235 (clobber (reg:CC FLAGS_REG))]
8237 [(parallel [(set (match_dup 3)
8238 (ashiftrt:SI (match_dup 4) (const_int 31)))
8239 (clobber (reg:CC FLAGS_REG))])
8240 (parallel [(set (match_dup 0)
8241 (div:SI (reg:SI 0) (match_dup 2)))
8243 (mod:SI (reg:SI 0) (match_dup 2)))
8245 (clobber (reg:CC FLAGS_REG))])]
8247 /* Avoid use of cltd in favor of a mov+shift. */
8248 if (!TARGET_USE_CLTD && !optimize_size)
8250 if (true_regnum (operands[1]))
8251 emit_move_insn (operands[0], operands[1]);
8253 emit_move_insn (operands[3], operands[1]);
8254 operands[4] = operands[3];
8258 gcc_assert (!true_regnum (operands[1]));
8259 operands[4] = operands[1];
8263 (define_insn "divmodhi4"
8264 [(set (match_operand:HI 0 "register_operand" "=a")
8265 (div:HI (match_operand:HI 1 "register_operand" "0")
8266 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8267 (set (match_operand:HI 3 "register_operand" "=&d")
8268 (mod:HI (match_dup 1) (match_dup 2)))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "TARGET_HIMODE_MATH"
8272 [(set_attr "type" "multi")
8273 (set_attr "length_immediate" "0")
8274 (set_attr "mode" "SI")])
8276 (define_insn "udivmoddi4"
8277 [(set (match_operand:DI 0 "register_operand" "=a")
8278 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8279 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8280 (set (match_operand:DI 3 "register_operand" "=&d")
8281 (umod:DI (match_dup 1) (match_dup 2)))
8282 (clobber (reg:CC FLAGS_REG))]
8284 "xor{q}\t%3, %3\;div{q}\t%2"
8285 [(set_attr "type" "multi")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "DI")])
8289 (define_insn "*udivmoddi4_noext"
8290 [(set (match_operand:DI 0 "register_operand" "=a")
8291 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8292 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8293 (set (match_operand:DI 3 "register_operand" "=d")
8294 (umod:DI (match_dup 1) (match_dup 2)))
8296 (clobber (reg:CC FLAGS_REG))]
8299 [(set_attr "type" "idiv")
8300 (set_attr "mode" "DI")])
8303 [(set (match_operand:DI 0 "register_operand" "")
8304 (udiv:DI (match_operand:DI 1 "register_operand" "")
8305 (match_operand:DI 2 "nonimmediate_operand" "")))
8306 (set (match_operand:DI 3 "register_operand" "")
8307 (umod:DI (match_dup 1) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "TARGET_64BIT && reload_completed"
8310 [(set (match_dup 3) (const_int 0))
8311 (parallel [(set (match_dup 0)
8312 (udiv:DI (match_dup 1) (match_dup 2)))
8314 (umod:DI (match_dup 1) (match_dup 2)))
8316 (clobber (reg:CC FLAGS_REG))])]
8319 (define_insn "udivmodsi4"
8320 [(set (match_operand:SI 0 "register_operand" "=a")
8321 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8322 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8323 (set (match_operand:SI 3 "register_operand" "=&d")
8324 (umod:SI (match_dup 1) (match_dup 2)))
8325 (clobber (reg:CC FLAGS_REG))]
8327 "xor{l}\t%3, %3\;div{l}\t%2"
8328 [(set_attr "type" "multi")
8329 (set_attr "length_immediate" "0")
8330 (set_attr "mode" "SI")])
8332 (define_insn "*udivmodsi4_noext"
8333 [(set (match_operand:SI 0 "register_operand" "=a")
8334 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8335 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8336 (set (match_operand:SI 3 "register_operand" "=d")
8337 (umod:SI (match_dup 1) (match_dup 2)))
8339 (clobber (reg:CC FLAGS_REG))]
8342 [(set_attr "type" "idiv")
8343 (set_attr "mode" "SI")])
8346 [(set (match_operand:SI 0 "register_operand" "")
8347 (udiv:SI (match_operand:SI 1 "register_operand" "")
8348 (match_operand:SI 2 "nonimmediate_operand" "")))
8349 (set (match_operand:SI 3 "register_operand" "")
8350 (umod:SI (match_dup 1) (match_dup 2)))
8351 (clobber (reg:CC FLAGS_REG))]
8353 [(set (match_dup 3) (const_int 0))
8354 (parallel [(set (match_dup 0)
8355 (udiv:SI (match_dup 1) (match_dup 2)))
8357 (umod:SI (match_dup 1) (match_dup 2)))
8359 (clobber (reg:CC FLAGS_REG))])]
8362 (define_expand "udivmodhi4"
8363 [(set (match_dup 4) (const_int 0))
8364 (parallel [(set (match_operand:HI 0 "register_operand" "")
8365 (udiv:HI (match_operand:HI 1 "register_operand" "")
8366 (match_operand:HI 2 "nonimmediate_operand" "")))
8367 (set (match_operand:HI 3 "register_operand" "")
8368 (umod:HI (match_dup 1) (match_dup 2)))
8370 (clobber (reg:CC FLAGS_REG))])]
8371 "TARGET_HIMODE_MATH"
8372 "operands[4] = gen_reg_rtx (HImode);")
8374 (define_insn "*udivmodhi_noext"
8375 [(set (match_operand:HI 0 "register_operand" "=a")
8376 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8377 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8378 (set (match_operand:HI 3 "register_operand" "=d")
8379 (umod:HI (match_dup 1) (match_dup 2)))
8380 (use (match_operand:HI 4 "register_operand" "3"))
8381 (clobber (reg:CC FLAGS_REG))]
8384 [(set_attr "type" "idiv")
8385 (set_attr "mode" "HI")])
8387 ;; We cannot use div/idiv for double division, because it causes
8388 ;; "division by zero" on the overflow and that's not what we expect
8389 ;; from truncate. Because true (non truncating) double division is
8390 ;; never generated, we can't create this insn anyway.
8393 ; [(set (match_operand:SI 0 "register_operand" "=a")
8395 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8397 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8398 ; (set (match_operand:SI 3 "register_operand" "=d")
8400 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8401 ; (clobber (reg:CC FLAGS_REG))]
8403 ; "div{l}\t{%2, %0|%0, %2}"
8404 ; [(set_attr "type" "idiv")])
8406 ;;- Logical AND instructions
8408 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8409 ;; Note that this excludes ah.
8411 (define_insn "*testdi_1_rex64"
8412 [(set (reg FLAGS_REG)
8414 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8415 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8418 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8420 test{l}\t{%k1, %k0|%k0, %k1}
8421 test{l}\t{%k1, %k0|%k0, %k1}
8422 test{q}\t{%1, %0|%0, %1}
8423 test{q}\t{%1, %0|%0, %1}
8424 test{q}\t{%1, %0|%0, %1}"
8425 [(set_attr "type" "test")
8426 (set_attr "modrm" "0,1,0,1,1")
8427 (set_attr "mode" "SI,SI,DI,DI,DI")
8428 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8430 (define_insn "testsi_1"
8431 [(set (reg FLAGS_REG)
8433 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8434 (match_operand:SI 1 "general_operand" "in,in,rin"))
8436 "ix86_match_ccmode (insn, CCNOmode)
8437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8438 "test{l}\t{%1, %0|%0, %1}"
8439 [(set_attr "type" "test")
8440 (set_attr "modrm" "0,1,1")
8441 (set_attr "mode" "SI")
8442 (set_attr "pent_pair" "uv,np,uv")])
8444 (define_expand "testsi_ccno_1"
8445 [(set (reg:CCNO FLAGS_REG)
8447 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8448 (match_operand:SI 1 "nonmemory_operand" ""))
8453 (define_insn "*testhi_1"
8454 [(set (reg FLAGS_REG)
8455 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8456 (match_operand:HI 1 "general_operand" "n,n,rn"))
8458 "ix86_match_ccmode (insn, CCNOmode)
8459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8460 "test{w}\t{%1, %0|%0, %1}"
8461 [(set_attr "type" "test")
8462 (set_attr "modrm" "0,1,1")
8463 (set_attr "mode" "HI")
8464 (set_attr "pent_pair" "uv,np,uv")])
8466 (define_expand "testqi_ccz_1"
8467 [(set (reg:CCZ FLAGS_REG)
8468 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8469 (match_operand:QI 1 "nonmemory_operand" ""))
8474 (define_insn "*testqi_1_maybe_si"
8475 [(set (reg FLAGS_REG)
8478 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8479 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8481 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8482 && ix86_match_ccmode (insn,
8483 CONST_INT_P (operands[1])
8484 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8486 if (which_alternative == 3)
8488 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8489 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8490 return "test{l}\t{%1, %k0|%k0, %1}";
8492 return "test{b}\t{%1, %0|%0, %1}";
8494 [(set_attr "type" "test")
8495 (set_attr "modrm" "0,1,1,1")
8496 (set_attr "mode" "QI,QI,QI,SI")
8497 (set_attr "pent_pair" "uv,np,uv,np")])
8499 (define_insn "*testqi_1"
8500 [(set (reg FLAGS_REG)
8503 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8504 (match_operand:QI 1 "general_operand" "n,n,qn"))
8506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8507 && ix86_match_ccmode (insn, CCNOmode)"
8508 "test{b}\t{%1, %0|%0, %1}"
8509 [(set_attr "type" "test")
8510 (set_attr "modrm" "0,1,1")
8511 (set_attr "mode" "QI")
8512 (set_attr "pent_pair" "uv,np,uv")])
8514 (define_expand "testqi_ext_ccno_0"
8515 [(set (reg:CCNO FLAGS_REG)
8519 (match_operand 0 "ext_register_operand" "")
8522 (match_operand 1 "const_int_operand" ""))
8527 (define_insn "*testqi_ext_0"
8528 [(set (reg FLAGS_REG)
8532 (match_operand 0 "ext_register_operand" "Q")
8535 (match_operand 1 "const_int_operand" "n"))
8537 "ix86_match_ccmode (insn, CCNOmode)"
8538 "test{b}\t{%1, %h0|%h0, %1}"
8539 [(set_attr "type" "test")
8540 (set_attr "mode" "QI")
8541 (set_attr "length_immediate" "1")
8542 (set_attr "pent_pair" "np")])
8544 (define_insn "*testqi_ext_1"
8545 [(set (reg FLAGS_REG)
8549 (match_operand 0 "ext_register_operand" "Q")
8553 (match_operand:QI 1 "general_operand" "Qm")))
8555 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557 "test{b}\t{%1, %h0|%h0, %1}"
8558 [(set_attr "type" "test")
8559 (set_attr "mode" "QI")])
8561 (define_insn "*testqi_ext_1_rex64"
8562 [(set (reg FLAGS_REG)
8566 (match_operand 0 "ext_register_operand" "Q")
8570 (match_operand:QI 1 "register_operand" "Q")))
8572 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8573 "test{b}\t{%1, %h0|%h0, %1}"
8574 [(set_attr "type" "test")
8575 (set_attr "mode" "QI")])
8577 (define_insn "*testqi_ext_2"
8578 [(set (reg FLAGS_REG)
8582 (match_operand 0 "ext_register_operand" "Q")
8586 (match_operand 1 "ext_register_operand" "Q")
8590 "ix86_match_ccmode (insn, CCNOmode)"
8591 "test{b}\t{%h1, %h0|%h0, %h1}"
8592 [(set_attr "type" "test")
8593 (set_attr "mode" "QI")])
8595 ;; Combine likes to form bit extractions for some tests. Humor it.
8596 (define_insn "*testqi_ext_3"
8597 [(set (reg FLAGS_REG)
8598 (compare (zero_extract:SI
8599 (match_operand 0 "nonimmediate_operand" "rm")
8600 (match_operand:SI 1 "const_int_operand" "")
8601 (match_operand:SI 2 "const_int_operand" ""))
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && INTVAL (operands[1]) > 0
8605 && INTVAL (operands[2]) >= 0
8606 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8607 && (GET_MODE (operands[0]) == SImode
8608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8609 || GET_MODE (operands[0]) == HImode
8610 || GET_MODE (operands[0]) == QImode)"
8613 (define_insn "*testqi_ext_3_rex64"
8614 [(set (reg FLAGS_REG)
8615 (compare (zero_extract:DI
8616 (match_operand 0 "nonimmediate_operand" "rm")
8617 (match_operand:DI 1 "const_int_operand" "")
8618 (match_operand:DI 2 "const_int_operand" ""))
8621 && ix86_match_ccmode (insn, CCNOmode)
8622 && INTVAL (operands[1]) > 0
8623 && INTVAL (operands[2]) >= 0
8624 /* Ensure that resulting mask is zero or sign extended operand. */
8625 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8626 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8627 && INTVAL (operands[1]) > 32))
8628 && (GET_MODE (operands[0]) == SImode
8629 || GET_MODE (operands[0]) == DImode
8630 || GET_MODE (operands[0]) == HImode
8631 || GET_MODE (operands[0]) == QImode)"
8635 [(set (match_operand 0 "flags_reg_operand" "")
8636 (match_operator 1 "compare_operator"
8638 (match_operand 2 "nonimmediate_operand" "")
8639 (match_operand 3 "const_int_operand" "")
8640 (match_operand 4 "const_int_operand" ""))
8642 "ix86_match_ccmode (insn, CCNOmode)"
8643 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8645 rtx val = operands[2];
8646 HOST_WIDE_INT len = INTVAL (operands[3]);
8647 HOST_WIDE_INT pos = INTVAL (operands[4]);
8649 enum machine_mode mode, submode;
8651 mode = GET_MODE (val);
8654 /* ??? Combine likes to put non-volatile mem extractions in QImode
8655 no matter the size of the test. So find a mode that works. */
8656 if (! MEM_VOLATILE_P (val))
8658 mode = smallest_mode_for_size (pos + len, MODE_INT);
8659 val = adjust_address (val, mode, 0);
8662 else if (GET_CODE (val) == SUBREG
8663 && (submode = GET_MODE (SUBREG_REG (val)),
8664 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8665 && pos + len <= GET_MODE_BITSIZE (submode))
8667 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8669 val = SUBREG_REG (val);
8671 else if (mode == HImode && pos + len <= 8)
8673 /* Small HImode tests can be converted to QImode. */
8675 val = gen_lowpart (QImode, val);
8678 if (len == HOST_BITS_PER_WIDE_INT)
8681 mask = ((HOST_WIDE_INT)1 << len) - 1;
8684 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8687 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8688 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8689 ;; this is relatively important trick.
8690 ;; Do the conversion only post-reload to avoid limiting of the register class
8693 [(set (match_operand 0 "flags_reg_operand" "")
8694 (match_operator 1 "compare_operator"
8695 [(and (match_operand 2 "register_operand" "")
8696 (match_operand 3 "const_int_operand" ""))
8699 && QI_REG_P (operands[2])
8700 && GET_MODE (operands[2]) != QImode
8701 && ((ix86_match_ccmode (insn, CCZmode)
8702 && !(INTVAL (operands[3]) & ~(255 << 8)))
8703 || (ix86_match_ccmode (insn, CCNOmode)
8704 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8707 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8710 "operands[2] = gen_lowpart (SImode, operands[2]);
8711 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8714 [(set (match_operand 0 "flags_reg_operand" "")
8715 (match_operator 1 "compare_operator"
8716 [(and (match_operand 2 "nonimmediate_operand" "")
8717 (match_operand 3 "const_int_operand" ""))
8720 && GET_MODE (operands[2]) != QImode
8721 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8722 && ((ix86_match_ccmode (insn, CCZmode)
8723 && !(INTVAL (operands[3]) & ~255))
8724 || (ix86_match_ccmode (insn, CCNOmode)
8725 && !(INTVAL (operands[3]) & ~127)))"
8727 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8729 "operands[2] = gen_lowpart (QImode, operands[2]);
8730 operands[3] = gen_lowpart (QImode, operands[3]);")
8733 ;; %%% This used to optimize known byte-wide and operations to memory,
8734 ;; and sometimes to QImode registers. If this is considered useful,
8735 ;; it should be done with splitters.
8737 (define_expand "anddi3"
8738 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8739 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8740 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8741 (clobber (reg:CC FLAGS_REG))]
8743 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8745 (define_insn "*anddi_1_rex64"
8746 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8747 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8748 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8749 (clobber (reg:CC FLAGS_REG))]
8750 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8752 switch (get_attr_type (insn))
8756 enum machine_mode mode;
8758 gcc_assert (CONST_INT_P (operands[2]));
8759 if (INTVAL (operands[2]) == 0xff)
8763 gcc_assert (INTVAL (operands[2]) == 0xffff);
8767 operands[1] = gen_lowpart (mode, operands[1]);
8769 return "movz{bq|x}\t{%1,%0|%0, %1}";
8771 return "movz{wq|x}\t{%1,%0|%0, %1}";
8775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8776 if (get_attr_mode (insn) == MODE_SI)
8777 return "and{l}\t{%k2, %k0|%k0, %k2}";
8779 return "and{q}\t{%2, %0|%0, %2}";
8782 [(set_attr "type" "alu,alu,alu,imovx")
8783 (set_attr "length_immediate" "*,*,*,0")
8784 (set_attr "mode" "SI,DI,DI,DI")])
8786 (define_insn "*anddi_2"
8787 [(set (reg FLAGS_REG)
8788 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8789 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8791 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8792 (and:DI (match_dup 1) (match_dup 2)))]
8793 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8794 && ix86_binary_operator_ok (AND, DImode, operands)"
8796 and{l}\t{%k2, %k0|%k0, %k2}
8797 and{q}\t{%2, %0|%0, %2}
8798 and{q}\t{%2, %0|%0, %2}"
8799 [(set_attr "type" "alu")
8800 (set_attr "mode" "SI,DI,DI")])
8802 (define_expand "andsi3"
8803 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8805 (match_operand:SI 2 "general_operand" "")))
8806 (clobber (reg:CC FLAGS_REG))]
8808 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8810 (define_insn "*andsi_1"
8811 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8812 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8813 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "ix86_binary_operator_ok (AND, SImode, operands)"
8817 switch (get_attr_type (insn))
8821 enum machine_mode mode;
8823 gcc_assert (CONST_INT_P (operands[2]));
8824 if (INTVAL (operands[2]) == 0xff)
8828 gcc_assert (INTVAL (operands[2]) == 0xffff);
8832 operands[1] = gen_lowpart (mode, operands[1]);
8834 return "movz{bl|x}\t{%1,%0|%0, %1}";
8836 return "movz{wl|x}\t{%1,%0|%0, %1}";
8840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8841 return "and{l}\t{%2, %0|%0, %2}";
8844 [(set_attr "type" "alu,alu,imovx")
8845 (set_attr "length_immediate" "*,*,0")
8846 (set_attr "mode" "SI")])
8849 [(set (match_operand 0 "register_operand" "")
8851 (const_int -65536)))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8854 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8855 "operands[1] = gen_lowpart (HImode, operands[0]);")
8858 [(set (match_operand 0 "ext_register_operand" "")
8861 (clobber (reg:CC FLAGS_REG))]
8862 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8863 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8864 "operands[1] = gen_lowpart (QImode, operands[0]);")
8867 [(set (match_operand 0 "ext_register_operand" "")
8869 (const_int -65281)))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8872 [(parallel [(set (zero_extract:SI (match_dup 0)
8876 (zero_extract:SI (match_dup 0)
8879 (zero_extract:SI (match_dup 0)
8882 (clobber (reg:CC FLAGS_REG))])]
8883 "operands[0] = gen_lowpart (SImode, operands[0]);")
8885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8886 (define_insn "*andsi_1_zext"
8887 [(set (match_operand:DI 0 "register_operand" "=r")
8889 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8890 (match_operand:SI 2 "general_operand" "g"))))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8893 "and{l}\t{%2, %k0|%k0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "SI")])
8897 (define_insn "*andsi_2"
8898 [(set (reg FLAGS_REG)
8899 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8900 (match_operand:SI 2 "general_operand" "g,ri"))
8902 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8903 (and:SI (match_dup 1) (match_dup 2)))]
8904 "ix86_match_ccmode (insn, CCNOmode)
8905 && ix86_binary_operator_ok (AND, SImode, operands)"
8906 "and{l}\t{%2, %0|%0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "SI")])
8910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8911 (define_insn "*andsi_2_zext"
8912 [(set (reg FLAGS_REG)
8913 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8914 (match_operand:SI 2 "general_operand" "g"))
8916 (set (match_operand:DI 0 "register_operand" "=r")
8917 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8918 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919 && ix86_binary_operator_ok (AND, SImode, operands)"
8920 "and{l}\t{%2, %k0|%k0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8924 (define_expand "andhi3"
8925 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8926 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8927 (match_operand:HI 2 "general_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "TARGET_HIMODE_MATH"
8930 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8932 (define_insn "*andhi_1"
8933 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8934 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8935 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "ix86_binary_operator_ok (AND, HImode, operands)"
8939 switch (get_attr_type (insn))
8942 gcc_assert (CONST_INT_P (operands[2]));
8943 gcc_assert (INTVAL (operands[2]) == 0xff);
8944 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8947 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8949 return "and{w}\t{%2, %0|%0, %2}";
8952 [(set_attr "type" "alu,alu,imovx")
8953 (set_attr "length_immediate" "*,*,0")
8954 (set_attr "mode" "HI,HI,SI")])
8956 (define_insn "*andhi_2"
8957 [(set (reg FLAGS_REG)
8958 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8959 (match_operand:HI 2 "general_operand" "g,ri"))
8961 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8962 (and:HI (match_dup 1) (match_dup 2)))]
8963 "ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (AND, HImode, operands)"
8965 "and{w}\t{%2, %0|%0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "HI")])
8969 (define_expand "andqi3"
8970 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8971 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8972 (match_operand:QI 2 "general_operand" "")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "TARGET_QIMODE_MATH"
8975 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8977 ;; %%% Potential partial reg stall on alternative 2. What to do?
8978 (define_insn "*andqi_1"
8979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8980 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8981 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "ix86_binary_operator_ok (AND, QImode, operands)"
8985 and{b}\t{%2, %0|%0, %2}
8986 and{b}\t{%2, %0|%0, %2}
8987 and{l}\t{%k2, %k0|%k0, %k2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "QI,QI,SI")])
8991 (define_insn "*andqi_1_slp"
8992 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8993 (and:QI (match_dup 0)
8994 (match_operand:QI 1 "general_operand" "qi,qmi")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8997 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8998 "and{b}\t{%1, %0|%0, %1}"
8999 [(set_attr "type" "alu1")
9000 (set_attr "mode" "QI")])
9002 (define_insn "*andqi_2_maybe_si"
9003 [(set (reg FLAGS_REG)
9005 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9006 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9008 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9009 (and:QI (match_dup 1) (match_dup 2)))]
9010 "ix86_binary_operator_ok (AND, QImode, operands)
9011 && ix86_match_ccmode (insn,
9012 CONST_INT_P (operands[2])
9013 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9015 if (which_alternative == 2)
9017 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9018 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9019 return "and{l}\t{%2, %k0|%k0, %2}";
9021 return "and{b}\t{%2, %0|%0, %2}";
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "QI,QI,SI")])
9026 (define_insn "*andqi_2"
9027 [(set (reg FLAGS_REG)
9029 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9030 (match_operand:QI 2 "general_operand" "qim,qi"))
9032 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9033 (and:QI (match_dup 1) (match_dup 2)))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (AND, QImode, operands)"
9036 "and{b}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "QI")])
9040 (define_insn "*andqi_2_slp"
9041 [(set (reg FLAGS_REG)
9043 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9044 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9046 (set (strict_low_part (match_dup 0))
9047 (and:QI (match_dup 0) (match_dup 1)))]
9048 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9049 && ix86_match_ccmode (insn, CCNOmode)
9050 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9051 "and{b}\t{%1, %0|%0, %1}"
9052 [(set_attr "type" "alu1")
9053 (set_attr "mode" "QI")])
9055 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9056 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9057 ;; for a QImode operand, which of course failed.
9059 (define_insn "andqi_ext_0"
9060 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065 (match_operand 1 "ext_register_operand" "0")
9068 (match_operand 2 "const_int_operand" "n")))
9069 (clobber (reg:CC FLAGS_REG))]
9071 "and{b}\t{%2, %h0|%h0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "length_immediate" "1")
9074 (set_attr "mode" "QI")])
9076 ;; Generated by peephole translating test to and. This shows up
9077 ;; often in fp comparisons.
9079 (define_insn "*andqi_ext_0_cc"
9080 [(set (reg FLAGS_REG)
9084 (match_operand 1 "ext_register_operand" "0")
9087 (match_operand 2 "const_int_operand" "n"))
9089 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9098 "ix86_match_ccmode (insn, CCNOmode)"
9099 "and{b}\t{%2, %h0|%h0, %2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "length_immediate" "1")
9102 (set_attr "mode" "QI")])
9104 (define_insn "*andqi_ext_1"
9105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110 (match_operand 1 "ext_register_operand" "0")
9114 (match_operand:QI 2 "general_operand" "Qm"))))
9115 (clobber (reg:CC FLAGS_REG))]
9117 "and{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "length_immediate" "0")
9120 (set_attr "mode" "QI")])
9122 (define_insn "*andqi_ext_1_rex64"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (match_operand 1 "ext_register_operand" "0")
9132 (match_operand 2 "ext_register_operand" "Q"))))
9133 (clobber (reg:CC FLAGS_REG))]
9135 "and{b}\t{%2, %h0|%h0, %2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "length_immediate" "0")
9138 (set_attr "mode" "QI")])
9140 (define_insn "*andqi_ext_2"
9141 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9146 (match_operand 1 "ext_register_operand" "%0")
9150 (match_operand 2 "ext_register_operand" "Q")
9153 (clobber (reg:CC FLAGS_REG))]
9155 "and{b}\t{%h2, %h0|%h0, %h2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "length_immediate" "0")
9158 (set_attr "mode" "QI")])
9160 ;; Convert wide AND instructions with immediate operand to shorter QImode
9161 ;; equivalents when possible.
9162 ;; Don't do the splitting with memory operands, since it introduces risk
9163 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9164 ;; for size, but that can (should?) be handled by generic code instead.
9166 [(set (match_operand 0 "register_operand" "")
9167 (and (match_operand 1 "register_operand" "")
9168 (match_operand 2 "const_int_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))]
9171 && QI_REG_P (operands[0])
9172 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9173 && !(~INTVAL (operands[2]) & ~(255 << 8))
9174 && GET_MODE (operands[0]) != QImode"
9175 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9176 (and:SI (zero_extract:SI (match_dup 1)
9177 (const_int 8) (const_int 8))
9179 (clobber (reg:CC FLAGS_REG))])]
9180 "operands[0] = gen_lowpart (SImode, operands[0]);
9181 operands[1] = gen_lowpart (SImode, operands[1]);
9182 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9184 ;; Since AND can be encoded with sign extended immediate, this is only
9185 ;; profitable when 7th bit is not set.
9187 [(set (match_operand 0 "register_operand" "")
9188 (and (match_operand 1 "general_operand" "")
9189 (match_operand 2 "const_int_operand" "")))
9190 (clobber (reg:CC FLAGS_REG))]
9192 && ANY_QI_REG_P (operands[0])
9193 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9194 && !(~INTVAL (operands[2]) & ~255)
9195 && !(INTVAL (operands[2]) & 128)
9196 && GET_MODE (operands[0]) != QImode"
9197 [(parallel [(set (strict_low_part (match_dup 0))
9198 (and:QI (match_dup 1)
9200 (clobber (reg:CC FLAGS_REG))])]
9201 "operands[0] = gen_lowpart (QImode, operands[0]);
9202 operands[1] = gen_lowpart (QImode, operands[1]);
9203 operands[2] = gen_lowpart (QImode, operands[2]);")
9205 ;; Logical inclusive OR instructions
9207 ;; %%% This used to optimize known byte-wide and operations to memory.
9208 ;; If this is considered useful, it should be done with splitters.
9210 (define_expand "iordi3"
9211 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9212 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9213 (match_operand:DI 2 "x86_64_general_operand" "")))
9214 (clobber (reg:CC FLAGS_REG))]
9216 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9218 (define_insn "*iordi_1_rex64"
9219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9220 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9221 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9222 (clobber (reg:CC FLAGS_REG))]
9224 && ix86_binary_operator_ok (IOR, DImode, operands)"
9225 "or{q}\t{%2, %0|%0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "DI")])
9229 (define_insn "*iordi_2_rex64"
9230 [(set (reg FLAGS_REG)
9231 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9232 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9234 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9235 (ior:DI (match_dup 1) (match_dup 2)))]
9237 && ix86_match_ccmode (insn, CCNOmode)
9238 && ix86_binary_operator_ok (IOR, DImode, operands)"
9239 "or{q}\t{%2, %0|%0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "DI")])
9243 (define_insn "*iordi_3_rex64"
9244 [(set (reg FLAGS_REG)
9245 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9246 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9248 (clobber (match_scratch:DI 0 "=r"))]
9250 && ix86_match_ccmode (insn, CCNOmode)
9251 && ix86_binary_operator_ok (IOR, DImode, operands)"
9252 "or{q}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "DI")])
9257 (define_expand "iorsi3"
9258 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9259 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9260 (match_operand:SI 2 "general_operand" "")))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9265 (define_insn "*iorsi_1"
9266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9267 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:SI 2 "general_operand" "ri,g")))
9269 (clobber (reg:CC FLAGS_REG))]
9270 "ix86_binary_operator_ok (IOR, SImode, operands)"
9271 "or{l}\t{%2, %0|%0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "mode" "SI")])
9275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9276 (define_insn "*iorsi_1_zext"
9277 [(set (match_operand:DI 0 "register_operand" "=r")
9279 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280 (match_operand:SI 2 "general_operand" "g"))))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9283 "or{l}\t{%2, %k0|%k0, %2}"
9284 [(set_attr "type" "alu")
9285 (set_attr "mode" "SI")])
9287 (define_insn "*iorsi_1_zext_imm"
9288 [(set (match_operand:DI 0 "register_operand" "=r")
9289 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9290 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9291 (clobber (reg:CC FLAGS_REG))]
9293 "or{l}\t{%2, %k0|%k0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "SI")])
9297 (define_insn "*iorsi_2"
9298 [(set (reg FLAGS_REG)
9299 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9300 (match_operand:SI 2 "general_operand" "g,ri"))
9302 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9303 (ior:SI (match_dup 1) (match_dup 2)))]
9304 "ix86_match_ccmode (insn, CCNOmode)
9305 && ix86_binary_operator_ok (IOR, SImode, operands)"
9306 "or{l}\t{%2, %0|%0, %2}"
9307 [(set_attr "type" "alu")
9308 (set_attr "mode" "SI")])
9310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9311 ;; ??? Special case for immediate operand is missing - it is tricky.
9312 (define_insn "*iorsi_2_zext"
9313 [(set (reg FLAGS_REG)
9314 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9315 (match_operand:SI 2 "general_operand" "g"))
9317 (set (match_operand:DI 0 "register_operand" "=r")
9318 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9319 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9320 && ix86_binary_operator_ok (IOR, SImode, operands)"
9321 "or{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9325 (define_insn "*iorsi_2_zext_imm"
9326 [(set (reg FLAGS_REG)
9327 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9330 (set (match_operand:DI 0 "register_operand" "=r")
9331 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9332 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9333 && ix86_binary_operator_ok (IOR, SImode, operands)"
9334 "or{l}\t{%2, %k0|%k0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "SI")])
9338 (define_insn "*iorsi_3"
9339 [(set (reg FLAGS_REG)
9340 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9341 (match_operand:SI 2 "general_operand" "g"))
9343 (clobber (match_scratch:SI 0 "=r"))]
9344 "ix86_match_ccmode (insn, CCNOmode)
9345 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9346 "or{l}\t{%2, %0|%0, %2}"
9347 [(set_attr "type" "alu")
9348 (set_attr "mode" "SI")])
9350 (define_expand "iorhi3"
9351 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9352 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9353 (match_operand:HI 2 "general_operand" "")))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "TARGET_HIMODE_MATH"
9356 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9358 (define_insn "*iorhi_1"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9360 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9361 (match_operand:HI 2 "general_operand" "g,ri")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "ix86_binary_operator_ok (IOR, HImode, operands)"
9364 "or{w}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "HI")])
9368 (define_insn "*iorhi_2"
9369 [(set (reg FLAGS_REG)
9370 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9371 (match_operand:HI 2 "general_operand" "g,ri"))
9373 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9374 (ior:HI (match_dup 1) (match_dup 2)))]
9375 "ix86_match_ccmode (insn, CCNOmode)
9376 && ix86_binary_operator_ok (IOR, HImode, operands)"
9377 "or{w}\t{%2, %0|%0, %2}"
9378 [(set_attr "type" "alu")
9379 (set_attr "mode" "HI")])
9381 (define_insn "*iorhi_3"
9382 [(set (reg FLAGS_REG)
9383 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9384 (match_operand:HI 2 "general_operand" "g"))
9386 (clobber (match_scratch:HI 0 "=r"))]
9387 "ix86_match_ccmode (insn, CCNOmode)
9388 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9389 "or{w}\t{%2, %0|%0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "HI")])
9393 (define_expand "iorqi3"
9394 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9395 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9396 (match_operand:QI 2 "general_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_QIMODE_MATH"
9399 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9401 ;; %%% Potential partial reg stall on alternative 2. What to do?
9402 (define_insn "*iorqi_1"
9403 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9404 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9405 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9406 (clobber (reg:CC FLAGS_REG))]
9407 "ix86_binary_operator_ok (IOR, QImode, operands)"
9409 or{b}\t{%2, %0|%0, %2}
9410 or{b}\t{%2, %0|%0, %2}
9411 or{l}\t{%k2, %k0|%k0, %k2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "QI,QI,SI")])
9415 (define_insn "*iorqi_1_slp"
9416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9417 (ior:QI (match_dup 0)
9418 (match_operand:QI 1 "general_operand" "qmi,qi")))
9419 (clobber (reg:CC FLAGS_REG))]
9420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9422 "or{b}\t{%1, %0|%0, %1}"
9423 [(set_attr "type" "alu1")
9424 (set_attr "mode" "QI")])
9426 (define_insn "*iorqi_2"
9427 [(set (reg FLAGS_REG)
9428 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9429 (match_operand:QI 2 "general_operand" "qim,qi"))
9431 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9432 (ior:QI (match_dup 1) (match_dup 2)))]
9433 "ix86_match_ccmode (insn, CCNOmode)
9434 && ix86_binary_operator_ok (IOR, QImode, operands)"
9435 "or{b}\t{%2, %0|%0, %2}"
9436 [(set_attr "type" "alu")
9437 (set_attr "mode" "QI")])
9439 (define_insn "*iorqi_2_slp"
9440 [(set (reg FLAGS_REG)
9441 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9442 (match_operand:QI 1 "general_operand" "qim,qi"))
9444 (set (strict_low_part (match_dup 0))
9445 (ior:QI (match_dup 0) (match_dup 1)))]
9446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9447 && ix86_match_ccmode (insn, CCNOmode)
9448 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9449 "or{b}\t{%1, %0|%0, %1}"
9450 [(set_attr "type" "alu1")
9451 (set_attr "mode" "QI")])
9453 (define_insn "*iorqi_3"
9454 [(set (reg FLAGS_REG)
9455 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9456 (match_operand:QI 2 "general_operand" "qim"))
9458 (clobber (match_scratch:QI 0 "=q"))]
9459 "ix86_match_ccmode (insn, CCNOmode)
9460 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9461 "or{b}\t{%2, %0|%0, %2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "mode" "QI")])
9465 (define_insn "iorqi_ext_0"
9466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9471 (match_operand 1 "ext_register_operand" "0")
9474 (match_operand 2 "const_int_operand" "n")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9477 "or{b}\t{%2, %h0|%h0, %2}"
9478 [(set_attr "type" "alu")
9479 (set_attr "length_immediate" "1")
9480 (set_attr "mode" "QI")])
9482 (define_insn "*iorqi_ext_1"
9483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9488 (match_operand 1 "ext_register_operand" "0")
9492 (match_operand:QI 2 "general_operand" "Qm"))))
9493 (clobber (reg:CC FLAGS_REG))]
9495 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9496 "or{b}\t{%2, %h0|%h0, %2}"
9497 [(set_attr "type" "alu")
9498 (set_attr "length_immediate" "0")
9499 (set_attr "mode" "QI")])
9501 (define_insn "*iorqi_ext_1_rex64"
9502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9507 (match_operand 1 "ext_register_operand" "0")
9511 (match_operand 2 "ext_register_operand" "Q"))))
9512 (clobber (reg:CC FLAGS_REG))]
9514 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "or{b}\t{%2, %h0|%h0, %2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*iorqi_ext_2"
9521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9525 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9528 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9531 (clobber (reg:CC FLAGS_REG))]
9532 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9533 "ior{b}\t{%h2, %h0|%h0, %h2}"
9534 [(set_attr "type" "alu")
9535 (set_attr "length_immediate" "0")
9536 (set_attr "mode" "QI")])
9539 [(set (match_operand 0 "register_operand" "")
9540 (ior (match_operand 1 "register_operand" "")
9541 (match_operand 2 "const_int_operand" "")))
9542 (clobber (reg:CC FLAGS_REG))]
9544 && QI_REG_P (operands[0])
9545 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9546 && !(INTVAL (operands[2]) & ~(255 << 8))
9547 && GET_MODE (operands[0]) != QImode"
9548 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9549 (ior:SI (zero_extract:SI (match_dup 1)
9550 (const_int 8) (const_int 8))
9552 (clobber (reg:CC FLAGS_REG))])]
9553 "operands[0] = gen_lowpart (SImode, operands[0]);
9554 operands[1] = gen_lowpart (SImode, operands[1]);
9555 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9557 ;; Since OR can be encoded with sign extended immediate, this is only
9558 ;; profitable when 7th bit is set.
9560 [(set (match_operand 0 "register_operand" "")
9561 (ior (match_operand 1 "general_operand" "")
9562 (match_operand 2 "const_int_operand" "")))
9563 (clobber (reg:CC FLAGS_REG))]
9565 && ANY_QI_REG_P (operands[0])
9566 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9567 && !(INTVAL (operands[2]) & ~255)
9568 && (INTVAL (operands[2]) & 128)
9569 && GET_MODE (operands[0]) != QImode"
9570 [(parallel [(set (strict_low_part (match_dup 0))
9571 (ior:QI (match_dup 1)
9573 (clobber (reg:CC FLAGS_REG))])]
9574 "operands[0] = gen_lowpart (QImode, operands[0]);
9575 operands[1] = gen_lowpart (QImode, operands[1]);
9576 operands[2] = gen_lowpart (QImode, operands[2]);")
9578 ;; Logical XOR instructions
9580 ;; %%% This used to optimize known byte-wide and operations to memory.
9581 ;; If this is considered useful, it should be done with splitters.
9583 (define_expand "xordi3"
9584 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586 (match_operand:DI 2 "x86_64_general_operand" "")))
9587 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9591 (define_insn "*xordi_1_rex64"
9592 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9593 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9594 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9595 (clobber (reg:CC FLAGS_REG))]
9597 && ix86_binary_operator_ok (XOR, DImode, operands)"
9599 xor{q}\t{%2, %0|%0, %2}
9600 xor{q}\t{%2, %0|%0, %2}"
9601 [(set_attr "type" "alu")
9602 (set_attr "mode" "DI,DI")])
9604 (define_insn "*xordi_2_rex64"
9605 [(set (reg FLAGS_REG)
9606 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9607 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9609 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9610 (xor:DI (match_dup 1) (match_dup 2)))]
9612 && ix86_match_ccmode (insn, CCNOmode)
9613 && ix86_binary_operator_ok (XOR, DImode, operands)"
9615 xor{q}\t{%2, %0|%0, %2}
9616 xor{q}\t{%2, %0|%0, %2}"
9617 [(set_attr "type" "alu")
9618 (set_attr "mode" "DI,DI")])
9620 (define_insn "*xordi_3_rex64"
9621 [(set (reg FLAGS_REG)
9622 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9625 (clobber (match_scratch:DI 0 "=r"))]
9627 && ix86_match_ccmode (insn, CCNOmode)
9628 && ix86_binary_operator_ok (XOR, DImode, operands)"
9629 "xor{q}\t{%2, %0|%0, %2}"
9630 [(set_attr "type" "alu")
9631 (set_attr "mode" "DI")])
9633 (define_expand "xorsi3"
9634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9635 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9636 (match_operand:SI 2 "general_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9641 (define_insn "*xorsi_1"
9642 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9643 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9644 (match_operand:SI 2 "general_operand" "ri,rm")))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "ix86_binary_operator_ok (XOR, SImode, operands)"
9647 "xor{l}\t{%2, %0|%0, %2}"
9648 [(set_attr "type" "alu")
9649 (set_attr "mode" "SI")])
9651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9652 ;; Add speccase for immediates
9653 (define_insn "*xorsi_1_zext"
9654 [(set (match_operand:DI 0 "register_operand" "=r")
9656 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9657 (match_operand:SI 2 "general_operand" "g"))))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9660 "xor{l}\t{%2, %k0|%k0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "mode" "SI")])
9664 (define_insn "*xorsi_1_zext_imm"
9665 [(set (match_operand:DI 0 "register_operand" "=r")
9666 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9668 (clobber (reg:CC FLAGS_REG))]
9669 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9670 "xor{l}\t{%2, %k0|%k0, %2}"
9671 [(set_attr "type" "alu")
9672 (set_attr "mode" "SI")])
9674 (define_insn "*xorsi_2"
9675 [(set (reg FLAGS_REG)
9676 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9677 (match_operand:SI 2 "general_operand" "g,ri"))
9679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9680 (xor:SI (match_dup 1) (match_dup 2)))]
9681 "ix86_match_ccmode (insn, CCNOmode)
9682 && ix86_binary_operator_ok (XOR, SImode, operands)"
9683 "xor{l}\t{%2, %0|%0, %2}"
9684 [(set_attr "type" "alu")
9685 (set_attr "mode" "SI")])
9687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9688 ;; ??? Special case for immediate operand is missing - it is tricky.
9689 (define_insn "*xorsi_2_zext"
9690 [(set (reg FLAGS_REG)
9691 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692 (match_operand:SI 2 "general_operand" "g"))
9694 (set (match_operand:DI 0 "register_operand" "=r")
9695 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9697 && ix86_binary_operator_ok (XOR, SImode, operands)"
9698 "xor{l}\t{%2, %k0|%k0, %2}"
9699 [(set_attr "type" "alu")
9700 (set_attr "mode" "SI")])
9702 (define_insn "*xorsi_2_zext_imm"
9703 [(set (reg FLAGS_REG)
9704 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9707 (set (match_operand:DI 0 "register_operand" "=r")
9708 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9710 && ix86_binary_operator_ok (XOR, SImode, operands)"
9711 "xor{l}\t{%2, %k0|%k0, %2}"
9712 [(set_attr "type" "alu")
9713 (set_attr "mode" "SI")])
9715 (define_insn "*xorsi_3"
9716 [(set (reg FLAGS_REG)
9717 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9718 (match_operand:SI 2 "general_operand" "g"))
9720 (clobber (match_scratch:SI 0 "=r"))]
9721 "ix86_match_ccmode (insn, CCNOmode)
9722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723 "xor{l}\t{%2, %0|%0, %2}"
9724 [(set_attr "type" "alu")
9725 (set_attr "mode" "SI")])
9727 (define_expand "xorhi3"
9728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9729 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9730 (match_operand:HI 2 "general_operand" "")))
9731 (clobber (reg:CC FLAGS_REG))]
9732 "TARGET_HIMODE_MATH"
9733 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9735 (define_insn "*xorhi_1"
9736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9737 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9738 (match_operand:HI 2 "general_operand" "g,ri")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "ix86_binary_operator_ok (XOR, HImode, operands)"
9741 "xor{w}\t{%2, %0|%0, %2}"
9742 [(set_attr "type" "alu")
9743 (set_attr "mode" "HI")])
9745 (define_insn "*xorhi_2"
9746 [(set (reg FLAGS_REG)
9747 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9748 (match_operand:HI 2 "general_operand" "g,ri"))
9750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9751 (xor:HI (match_dup 1) (match_dup 2)))]
9752 "ix86_match_ccmode (insn, CCNOmode)
9753 && ix86_binary_operator_ok (XOR, HImode, operands)"
9754 "xor{w}\t{%2, %0|%0, %2}"
9755 [(set_attr "type" "alu")
9756 (set_attr "mode" "HI")])
9758 (define_insn "*xorhi_3"
9759 [(set (reg FLAGS_REG)
9760 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9761 (match_operand:HI 2 "general_operand" "g"))
9763 (clobber (match_scratch:HI 0 "=r"))]
9764 "ix86_match_ccmode (insn, CCNOmode)
9765 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9766 "xor{w}\t{%2, %0|%0, %2}"
9767 [(set_attr "type" "alu")
9768 (set_attr "mode" "HI")])
9770 (define_expand "xorqi3"
9771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9772 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9773 (match_operand:QI 2 "general_operand" "")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "TARGET_QIMODE_MATH"
9776 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9778 ;; %%% Potential partial reg stall on alternative 2. What to do?
9779 (define_insn "*xorqi_1"
9780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9781 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "ix86_binary_operator_ok (XOR, QImode, operands)"
9786 xor{b}\t{%2, %0|%0, %2}
9787 xor{b}\t{%2, %0|%0, %2}
9788 xor{l}\t{%k2, %k0|%k0, %k2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "QI,QI,SI")])
9792 (define_insn "*xorqi_1_slp"
9793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9794 (xor:QI (match_dup 0)
9795 (match_operand:QI 1 "general_operand" "qi,qmi")))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9799 "xor{b}\t{%1, %0|%0, %1}"
9800 [(set_attr "type" "alu1")
9801 (set_attr "mode" "QI")])
9803 (define_insn "xorqi_ext_0"
9804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9809 (match_operand 1 "ext_register_operand" "0")
9812 (match_operand 2 "const_int_operand" "n")))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9815 "xor{b}\t{%2, %h0|%h0, %2}"
9816 [(set_attr "type" "alu")
9817 (set_attr "length_immediate" "1")
9818 (set_attr "mode" "QI")])
9820 (define_insn "*xorqi_ext_1"
9821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9826 (match_operand 1 "ext_register_operand" "0")
9830 (match_operand:QI 2 "general_operand" "Qm"))))
9831 (clobber (reg:CC FLAGS_REG))]
9833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9834 "xor{b}\t{%2, %h0|%h0, %2}"
9835 [(set_attr "type" "alu")
9836 (set_attr "length_immediate" "0")
9837 (set_attr "mode" "QI")])
9839 (define_insn "*xorqi_ext_1_rex64"
9840 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9845 (match_operand 1 "ext_register_operand" "0")
9849 (match_operand 2 "ext_register_operand" "Q"))))
9850 (clobber (reg:CC FLAGS_REG))]
9852 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9853 "xor{b}\t{%2, %h0|%h0, %2}"
9854 [(set_attr "type" "alu")
9855 (set_attr "length_immediate" "0")
9856 (set_attr "mode" "QI")])
9858 (define_insn "*xorqi_ext_2"
9859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9863 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9866 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9869 (clobber (reg:CC FLAGS_REG))]
9870 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9871 "xor{b}\t{%h2, %h0|%h0, %h2}"
9872 [(set_attr "type" "alu")
9873 (set_attr "length_immediate" "0")
9874 (set_attr "mode" "QI")])
9876 (define_insn "*xorqi_cc_1"
9877 [(set (reg FLAGS_REG)
9879 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9880 (match_operand:QI 2 "general_operand" "qim,qi"))
9882 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9883 (xor:QI (match_dup 1) (match_dup 2)))]
9884 "ix86_match_ccmode (insn, CCNOmode)
9885 && ix86_binary_operator_ok (XOR, QImode, operands)"
9886 "xor{b}\t{%2, %0|%0, %2}"
9887 [(set_attr "type" "alu")
9888 (set_attr "mode" "QI")])
9890 (define_insn "*xorqi_2_slp"
9891 [(set (reg FLAGS_REG)
9892 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9893 (match_operand:QI 1 "general_operand" "qim,qi"))
9895 (set (strict_low_part (match_dup 0))
9896 (xor:QI (match_dup 0) (match_dup 1)))]
9897 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9898 && ix86_match_ccmode (insn, CCNOmode)
9899 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9900 "xor{b}\t{%1, %0|%0, %1}"
9901 [(set_attr "type" "alu1")
9902 (set_attr "mode" "QI")])
9904 (define_insn "*xorqi_cc_2"
9905 [(set (reg FLAGS_REG)
9907 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9908 (match_operand:QI 2 "general_operand" "qim"))
9910 (clobber (match_scratch:QI 0 "=q"))]
9911 "ix86_match_ccmode (insn, CCNOmode)
9912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9913 "xor{b}\t{%2, %0|%0, %2}"
9914 [(set_attr "type" "alu")
9915 (set_attr "mode" "QI")])
9917 (define_insn "*xorqi_cc_ext_1"
9918 [(set (reg FLAGS_REG)
9922 (match_operand 1 "ext_register_operand" "0")
9925 (match_operand:QI 2 "general_operand" "qmn"))
9927 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9931 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9934 "xor{b}\t{%2, %h0|%h0, %2}"
9935 [(set_attr "type" "alu")
9936 (set_attr "mode" "QI")])
9938 (define_insn "*xorqi_cc_ext_1_rex64"
9939 [(set (reg FLAGS_REG)
9943 (match_operand 1 "ext_register_operand" "0")
9946 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9948 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9952 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9955 "xor{b}\t{%2, %h0|%h0, %2}"
9956 [(set_attr "type" "alu")
9957 (set_attr "mode" "QI")])
9959 (define_expand "xorqi_cc_ext_1"
9961 (set (reg:CCNO FLAGS_REG)
9965 (match_operand 1 "ext_register_operand" "")
9968 (match_operand:QI 2 "general_operand" ""))
9970 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9974 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9980 [(set (match_operand 0 "register_operand" "")
9981 (xor (match_operand 1 "register_operand" "")
9982 (match_operand 2 "const_int_operand" "")))
9983 (clobber (reg:CC FLAGS_REG))]
9985 && QI_REG_P (operands[0])
9986 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9987 && !(INTVAL (operands[2]) & ~(255 << 8))
9988 && GET_MODE (operands[0]) != QImode"
9989 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9990 (xor:SI (zero_extract:SI (match_dup 1)
9991 (const_int 8) (const_int 8))
9993 (clobber (reg:CC FLAGS_REG))])]
9994 "operands[0] = gen_lowpart (SImode, operands[0]);
9995 operands[1] = gen_lowpart (SImode, operands[1]);
9996 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9998 ;; Since XOR can be encoded with sign extended immediate, this is only
9999 ;; profitable when 7th bit is set.
10001 [(set (match_operand 0 "register_operand" "")
10002 (xor (match_operand 1 "general_operand" "")
10003 (match_operand 2 "const_int_operand" "")))
10004 (clobber (reg:CC FLAGS_REG))]
10006 && ANY_QI_REG_P (operands[0])
10007 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10008 && !(INTVAL (operands[2]) & ~255)
10009 && (INTVAL (operands[2]) & 128)
10010 && GET_MODE (operands[0]) != QImode"
10011 [(parallel [(set (strict_low_part (match_dup 0))
10012 (xor:QI (match_dup 1)
10014 (clobber (reg:CC FLAGS_REG))])]
10015 "operands[0] = gen_lowpart (QImode, operands[0]);
10016 operands[1] = gen_lowpart (QImode, operands[1]);
10017 operands[2] = gen_lowpart (QImode, operands[2]);")
10019 ;; Negation instructions
10021 (define_expand "negti2"
10022 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10023 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10024 (clobber (reg:CC FLAGS_REG))])]
10026 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10028 (define_insn "*negti2_1"
10029 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10030 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10031 (clobber (reg:CC FLAGS_REG))]
10033 && ix86_unary_operator_ok (NEG, TImode, operands)"
10037 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10038 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10039 (clobber (reg:CC FLAGS_REG))]
10040 "TARGET_64BIT && reload_completed"
10042 [(set (reg:CCZ FLAGS_REG)
10043 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10044 (set (match_dup 0) (neg:DI (match_dup 2)))])
10046 [(set (match_dup 1)
10047 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10050 (clobber (reg:CC FLAGS_REG))])
10052 [(set (match_dup 1)
10053 (neg:DI (match_dup 1)))
10054 (clobber (reg:CC FLAGS_REG))])]
10055 "split_ti (operands+1, 1, operands+2, operands+3);
10056 split_ti (operands+0, 1, operands+0, operands+1);")
10058 (define_expand "negdi2"
10059 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10060 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10061 (clobber (reg:CC FLAGS_REG))])]
10063 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10065 (define_insn "*negdi2_1"
10066 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10067 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10068 (clobber (reg:CC FLAGS_REG))]
10070 && ix86_unary_operator_ok (NEG, DImode, operands)"
10074 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10075 (neg:DI (match_operand:DI 1 "general_operand" "")))
10076 (clobber (reg:CC FLAGS_REG))]
10077 "!TARGET_64BIT && reload_completed"
10079 [(set (reg:CCZ FLAGS_REG)
10080 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10081 (set (match_dup 0) (neg:SI (match_dup 2)))])
10083 [(set (match_dup 1)
10084 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10087 (clobber (reg:CC FLAGS_REG))])
10089 [(set (match_dup 1)
10090 (neg:SI (match_dup 1)))
10091 (clobber (reg:CC FLAGS_REG))])]
10092 "split_di (operands+1, 1, operands+2, operands+3);
10093 split_di (operands+0, 1, operands+0, operands+1);")
10095 (define_insn "*negdi2_1_rex64"
10096 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10097 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10098 (clobber (reg:CC FLAGS_REG))]
10099 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10101 [(set_attr "type" "negnot")
10102 (set_attr "mode" "DI")])
10104 ;; The problem with neg is that it does not perform (compare x 0),
10105 ;; it really performs (compare 0 x), which leaves us with the zero
10106 ;; flag being the only useful item.
10108 (define_insn "*negdi2_cmpz_rex64"
10109 [(set (reg:CCZ FLAGS_REG)
10110 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10112 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10113 (neg:DI (match_dup 1)))]
10114 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10116 [(set_attr "type" "negnot")
10117 (set_attr "mode" "DI")])
10120 (define_expand "negsi2"
10121 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10123 (clobber (reg:CC FLAGS_REG))])]
10125 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10127 (define_insn "*negsi2_1"
10128 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10129 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10130 (clobber (reg:CC FLAGS_REG))]
10131 "ix86_unary_operator_ok (NEG, SImode, operands)"
10133 [(set_attr "type" "negnot")
10134 (set_attr "mode" "SI")])
10136 ;; Combine is quite creative about this pattern.
10137 (define_insn "*negsi2_1_zext"
10138 [(set (match_operand:DI 0 "register_operand" "=r")
10139 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10142 (clobber (reg:CC FLAGS_REG))]
10143 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10145 [(set_attr "type" "negnot")
10146 (set_attr "mode" "SI")])
10148 ;; The problem with neg is that it does not perform (compare x 0),
10149 ;; it really performs (compare 0 x), which leaves us with the zero
10150 ;; flag being the only useful item.
10152 (define_insn "*negsi2_cmpz"
10153 [(set (reg:CCZ FLAGS_REG)
10154 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10156 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10157 (neg:SI (match_dup 1)))]
10158 "ix86_unary_operator_ok (NEG, SImode, operands)"
10160 [(set_attr "type" "negnot")
10161 (set_attr "mode" "SI")])
10163 (define_insn "*negsi2_cmpz_zext"
10164 [(set (reg:CCZ FLAGS_REG)
10165 (compare:CCZ (lshiftrt:DI
10167 (match_operand:DI 1 "register_operand" "0")
10171 (set (match_operand:DI 0 "register_operand" "=r")
10172 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10175 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10177 [(set_attr "type" "negnot")
10178 (set_attr "mode" "SI")])
10180 (define_expand "neghi2"
10181 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10182 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))])]
10184 "TARGET_HIMODE_MATH"
10185 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10187 (define_insn "*neghi2_1"
10188 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10189 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10190 (clobber (reg:CC FLAGS_REG))]
10191 "ix86_unary_operator_ok (NEG, HImode, operands)"
10193 [(set_attr "type" "negnot")
10194 (set_attr "mode" "HI")])
10196 (define_insn "*neghi2_cmpz"
10197 [(set (reg:CCZ FLAGS_REG)
10198 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10200 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10201 (neg:HI (match_dup 1)))]
10202 "ix86_unary_operator_ok (NEG, HImode, operands)"
10204 [(set_attr "type" "negnot")
10205 (set_attr "mode" "HI")])
10207 (define_expand "negqi2"
10208 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10209 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10210 (clobber (reg:CC FLAGS_REG))])]
10211 "TARGET_QIMODE_MATH"
10212 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10214 (define_insn "*negqi2_1"
10215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10216 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "ix86_unary_operator_ok (NEG, QImode, operands)"
10220 [(set_attr "type" "negnot")
10221 (set_attr "mode" "QI")])
10223 (define_insn "*negqi2_cmpz"
10224 [(set (reg:CCZ FLAGS_REG)
10225 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10227 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10228 (neg:QI (match_dup 1)))]
10229 "ix86_unary_operator_ok (NEG, QImode, operands)"
10231 [(set_attr "type" "negnot")
10232 (set_attr "mode" "QI")])
10234 ;; Changing of sign for FP values is doable using integer unit too.
10236 (define_expand "neg<mode>2"
10237 [(set (match_operand:X87MODEF 0 "register_operand" "")
10238 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10239 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10240 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10242 (define_expand "abs<mode>2"
10243 [(set (match_operand:X87MODEF 0 "register_operand" "")
10244 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10245 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10246 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10248 (define_insn "*absneg<mode>2_mixed"
10249 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10250 (match_operator:MODEF 3 "absneg_operator"
10251 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10252 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10257 (define_insn "*absneg<mode>2_sse"
10258 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10259 (match_operator:MODEF 3 "absneg_operator"
10260 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10261 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10266 (define_insn "*absneg<mode>2_i387"
10267 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10268 (match_operator:X87MODEF 3 "absneg_operator"
10269 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10270 (use (match_operand 2 "" ""))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10275 (define_expand "negtf2"
10276 [(set (match_operand:TF 0 "register_operand" "")
10277 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10279 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10281 (define_expand "abstf2"
10282 [(set (match_operand:TF 0 "register_operand" "")
10283 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10285 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10287 (define_insn "*absnegtf2_sse"
10288 [(set (match_operand:TF 0 "register_operand" "=x,x")
10289 (match_operator:TF 3 "absneg_operator"
10290 [(match_operand:TF 1 "register_operand" "0,x")]))
10291 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10292 (clobber (reg:CC FLAGS_REG))]
10296 ;; Splitters for fp abs and neg.
10299 [(set (match_operand 0 "fp_register_operand" "")
10300 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10301 (use (match_operand 2 "" ""))
10302 (clobber (reg:CC FLAGS_REG))]
10304 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10307 [(set (match_operand 0 "register_operand" "")
10308 (match_operator 3 "absneg_operator"
10309 [(match_operand 1 "register_operand" "")]))
10310 (use (match_operand 2 "nonimmediate_operand" ""))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "reload_completed && SSE_REG_P (operands[0])"
10313 [(set (match_dup 0) (match_dup 3))]
10315 enum machine_mode mode = GET_MODE (operands[0]);
10316 enum machine_mode vmode = GET_MODE (operands[2]);
10319 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10320 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10321 if (operands_match_p (operands[0], operands[2]))
10324 operands[1] = operands[2];
10327 if (GET_CODE (operands[3]) == ABS)
10328 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10330 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10335 [(set (match_operand:SF 0 "register_operand" "")
10336 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10337 (use (match_operand:V4SF 2 "" ""))
10338 (clobber (reg:CC FLAGS_REG))]
10340 [(parallel [(set (match_dup 0) (match_dup 1))
10341 (clobber (reg:CC FLAGS_REG))])]
10344 operands[0] = gen_lowpart (SImode, operands[0]);
10345 if (GET_CODE (operands[1]) == ABS)
10347 tmp = gen_int_mode (0x7fffffff, SImode);
10348 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10352 tmp = gen_int_mode (0x80000000, SImode);
10353 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10359 [(set (match_operand:DF 0 "register_operand" "")
10360 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10361 (use (match_operand 2 "" ""))
10362 (clobber (reg:CC FLAGS_REG))]
10364 [(parallel [(set (match_dup 0) (match_dup 1))
10365 (clobber (reg:CC FLAGS_REG))])]
10370 tmp = gen_lowpart (DImode, operands[0]);
10371 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10374 if (GET_CODE (operands[1]) == ABS)
10377 tmp = gen_rtx_NOT (DImode, tmp);
10381 operands[0] = gen_highpart (SImode, operands[0]);
10382 if (GET_CODE (operands[1]) == ABS)
10384 tmp = gen_int_mode (0x7fffffff, SImode);
10385 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10389 tmp = gen_int_mode (0x80000000, SImode);
10390 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10397 [(set (match_operand:XF 0 "register_operand" "")
10398 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10399 (use (match_operand 2 "" ""))
10400 (clobber (reg:CC FLAGS_REG))]
10402 [(parallel [(set (match_dup 0) (match_dup 1))
10403 (clobber (reg:CC FLAGS_REG))])]
10406 operands[0] = gen_rtx_REG (SImode,
10407 true_regnum (operands[0])
10408 + (TARGET_64BIT ? 1 : 2));
10409 if (GET_CODE (operands[1]) == ABS)
10411 tmp = GEN_INT (0x7fff);
10412 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10416 tmp = GEN_INT (0x8000);
10417 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10422 ;; Conditionalize these after reload. If they match before reload, we
10423 ;; lose the clobber and ability to use integer instructions.
10425 (define_insn "*neg<mode>2_1"
10426 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10427 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10429 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10431 [(set_attr "type" "fsgn")
10432 (set_attr "mode" "<MODE>")])
10434 (define_insn "*abs<mode>2_1"
10435 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10436 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10438 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10440 [(set_attr "type" "fsgn")
10441 (set_attr "mode" "<MODE>")])
10443 (define_insn "*negextendsfdf2"
10444 [(set (match_operand:DF 0 "register_operand" "=f")
10445 (neg:DF (float_extend:DF
10446 (match_operand:SF 1 "register_operand" "0"))))]
10447 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10449 [(set_attr "type" "fsgn")
10450 (set_attr "mode" "DF")])
10452 (define_insn "*negextenddfxf2"
10453 [(set (match_operand:XF 0 "register_operand" "=f")
10454 (neg:XF (float_extend:XF
10455 (match_operand:DF 1 "register_operand" "0"))))]
10458 [(set_attr "type" "fsgn")
10459 (set_attr "mode" "XF")])
10461 (define_insn "*negextendsfxf2"
10462 [(set (match_operand:XF 0 "register_operand" "=f")
10463 (neg:XF (float_extend:XF
10464 (match_operand:SF 1 "register_operand" "0"))))]
10467 [(set_attr "type" "fsgn")
10468 (set_attr "mode" "XF")])
10470 (define_insn "*absextendsfdf2"
10471 [(set (match_operand:DF 0 "register_operand" "=f")
10472 (abs:DF (float_extend:DF
10473 (match_operand:SF 1 "register_operand" "0"))))]
10474 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10476 [(set_attr "type" "fsgn")
10477 (set_attr "mode" "DF")])
10479 (define_insn "*absextenddfxf2"
10480 [(set (match_operand:XF 0 "register_operand" "=f")
10481 (abs:XF (float_extend:XF
10482 (match_operand:DF 1 "register_operand" "0"))))]
10485 [(set_attr "type" "fsgn")
10486 (set_attr "mode" "XF")])
10488 (define_insn "*absextendsfxf2"
10489 [(set (match_operand:XF 0 "register_operand" "=f")
10490 (abs:XF (float_extend:XF
10491 (match_operand:SF 1 "register_operand" "0"))))]
10494 [(set_attr "type" "fsgn")
10495 (set_attr "mode" "XF")])
10497 ;; Copysign instructions
10499 (define_mode_iterator CSGNMODE [SF DF TF])
10500 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10502 (define_expand "copysign<mode>3"
10503 [(match_operand:CSGNMODE 0 "register_operand" "")
10504 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10505 (match_operand:CSGNMODE 2 "register_operand" "")]
10506 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10507 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10509 ix86_expand_copysign (operands);
10513 (define_insn_and_split "copysign<mode>3_const"
10514 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10516 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10517 (match_operand:CSGNMODE 2 "register_operand" "0")
10518 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10520 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10521 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10523 "&& reload_completed"
10526 ix86_split_copysign_const (operands);
10530 (define_insn "copysign<mode>3_var"
10531 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10533 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10534 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10535 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10536 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10538 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10539 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10540 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10544 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10546 [(match_operand:CSGNMODE 2 "register_operand" "")
10547 (match_operand:CSGNMODE 3 "register_operand" "")
10548 (match_operand:<CSGNVMODE> 4 "" "")
10549 (match_operand:<CSGNVMODE> 5 "" "")]
10551 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10552 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10553 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10554 && reload_completed"
10557 ix86_split_copysign_var (operands);
10561 ;; One complement instructions
10563 (define_expand "one_cmpldi2"
10564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10565 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10567 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10569 (define_insn "*one_cmpldi2_1_rex64"
10570 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10571 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10572 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10574 [(set_attr "type" "negnot")
10575 (set_attr "mode" "DI")])
10577 (define_insn "*one_cmpldi2_2_rex64"
10578 [(set (reg FLAGS_REG)
10579 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10581 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10582 (not:DI (match_dup 1)))]
10583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10584 && ix86_unary_operator_ok (NOT, DImode, operands)"
10586 [(set_attr "type" "alu1")
10587 (set_attr "mode" "DI")])
10590 [(set (match_operand 0 "flags_reg_operand" "")
10591 (match_operator 2 "compare_operator"
10592 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10594 (set (match_operand:DI 1 "nonimmediate_operand" "")
10595 (not:DI (match_dup 3)))]
10596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10597 [(parallel [(set (match_dup 0)
10599 [(xor:DI (match_dup 3) (const_int -1))
10602 (xor:DI (match_dup 3) (const_int -1)))])]
10605 (define_expand "one_cmplsi2"
10606 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10607 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10609 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10611 (define_insn "*one_cmplsi2_1"
10612 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10613 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10614 "ix86_unary_operator_ok (NOT, SImode, operands)"
10616 [(set_attr "type" "negnot")
10617 (set_attr "mode" "SI")])
10619 ;; ??? Currently never generated - xor is used instead.
10620 (define_insn "*one_cmplsi2_1_zext"
10621 [(set (match_operand:DI 0 "register_operand" "=r")
10622 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10623 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10625 [(set_attr "type" "negnot")
10626 (set_attr "mode" "SI")])
10628 (define_insn "*one_cmplsi2_2"
10629 [(set (reg FLAGS_REG)
10630 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10632 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10633 (not:SI (match_dup 1)))]
10634 "ix86_match_ccmode (insn, CCNOmode)
10635 && ix86_unary_operator_ok (NOT, SImode, operands)"
10637 [(set_attr "type" "alu1")
10638 (set_attr "mode" "SI")])
10641 [(set (match_operand 0 "flags_reg_operand" "")
10642 (match_operator 2 "compare_operator"
10643 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10645 (set (match_operand:SI 1 "nonimmediate_operand" "")
10646 (not:SI (match_dup 3)))]
10647 "ix86_match_ccmode (insn, CCNOmode)"
10648 [(parallel [(set (match_dup 0)
10649 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10652 (xor:SI (match_dup 3) (const_int -1)))])]
10655 ;; ??? Currently never generated - xor is used instead.
10656 (define_insn "*one_cmplsi2_2_zext"
10657 [(set (reg FLAGS_REG)
10658 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10660 (set (match_operand:DI 0 "register_operand" "=r")
10661 (zero_extend:DI (not:SI (match_dup 1))))]
10662 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10663 && ix86_unary_operator_ok (NOT, SImode, operands)"
10665 [(set_attr "type" "alu1")
10666 (set_attr "mode" "SI")])
10669 [(set (match_operand 0 "flags_reg_operand" "")
10670 (match_operator 2 "compare_operator"
10671 [(not:SI (match_operand:SI 3 "register_operand" ""))
10673 (set (match_operand:DI 1 "register_operand" "")
10674 (zero_extend:DI (not:SI (match_dup 3))))]
10675 "ix86_match_ccmode (insn, CCNOmode)"
10676 [(parallel [(set (match_dup 0)
10677 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10680 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10683 (define_expand "one_cmplhi2"
10684 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10685 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10686 "TARGET_HIMODE_MATH"
10687 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10689 (define_insn "*one_cmplhi2_1"
10690 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10692 "ix86_unary_operator_ok (NOT, HImode, operands)"
10694 [(set_attr "type" "negnot")
10695 (set_attr "mode" "HI")])
10697 (define_insn "*one_cmplhi2_2"
10698 [(set (reg FLAGS_REG)
10699 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10701 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10702 (not:HI (match_dup 1)))]
10703 "ix86_match_ccmode (insn, CCNOmode)
10704 && ix86_unary_operator_ok (NEG, HImode, operands)"
10706 [(set_attr "type" "alu1")
10707 (set_attr "mode" "HI")])
10710 [(set (match_operand 0 "flags_reg_operand" "")
10711 (match_operator 2 "compare_operator"
10712 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10714 (set (match_operand:HI 1 "nonimmediate_operand" "")
10715 (not:HI (match_dup 3)))]
10716 "ix86_match_ccmode (insn, CCNOmode)"
10717 [(parallel [(set (match_dup 0)
10718 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10721 (xor:HI (match_dup 3) (const_int -1)))])]
10724 ;; %%% Potential partial reg stall on alternative 1. What to do?
10725 (define_expand "one_cmplqi2"
10726 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10727 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10728 "TARGET_QIMODE_MATH"
10729 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10731 (define_insn "*one_cmplqi2_1"
10732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10733 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10734 "ix86_unary_operator_ok (NOT, QImode, operands)"
10738 [(set_attr "type" "negnot")
10739 (set_attr "mode" "QI,SI")])
10741 (define_insn "*one_cmplqi2_2"
10742 [(set (reg FLAGS_REG)
10743 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10745 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10746 (not:QI (match_dup 1)))]
10747 "ix86_match_ccmode (insn, CCNOmode)
10748 && ix86_unary_operator_ok (NOT, QImode, operands)"
10750 [(set_attr "type" "alu1")
10751 (set_attr "mode" "QI")])
10754 [(set (match_operand 0 "flags_reg_operand" "")
10755 (match_operator 2 "compare_operator"
10756 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10758 (set (match_operand:QI 1 "nonimmediate_operand" "")
10759 (not:QI (match_dup 3)))]
10760 "ix86_match_ccmode (insn, CCNOmode)"
10761 [(parallel [(set (match_dup 0)
10762 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10765 (xor:QI (match_dup 3) (const_int -1)))])]
10768 ;; Arithmetic shift instructions
10770 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10771 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10772 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10773 ;; from the assembler input.
10775 ;; This instruction shifts the target reg/mem as usual, but instead of
10776 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10777 ;; is a left shift double, bits are taken from the high order bits of
10778 ;; reg, else if the insn is a shift right double, bits are taken from the
10779 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10780 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10782 ;; Since sh[lr]d does not change the `reg' operand, that is done
10783 ;; separately, making all shifts emit pairs of shift double and normal
10784 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10785 ;; support a 63 bit shift, each shift where the count is in a reg expands
10786 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10788 ;; If the shift count is a constant, we need never emit more than one
10789 ;; shift pair, instead using moves and sign extension for counts greater
10792 (define_expand "ashlti3"
10793 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10794 (ashift:TI (match_operand:TI 1 "register_operand" "")
10795 (match_operand:QI 2 "nonmemory_operand" "")))
10796 (clobber (reg:CC FLAGS_REG))])]
10799 if (! immediate_operand (operands[2], QImode))
10801 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10804 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10808 (define_insn "ashlti3_1"
10809 [(set (match_operand:TI 0 "register_operand" "=r")
10810 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10811 (match_operand:QI 2 "register_operand" "c")))
10812 (clobber (match_scratch:DI 3 "=&r"))
10813 (clobber (reg:CC FLAGS_REG))]
10816 [(set_attr "type" "multi")])
10818 ;; This pattern must be defined before *ashlti3_2 to prevent
10819 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10821 (define_insn "sse2_ashlti3"
10822 [(set (match_operand:TI 0 "register_operand" "=x")
10823 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10824 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10827 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10828 return "pslldq\t{%2, %0|%0, %2}";
10830 [(set_attr "type" "sseishft")
10831 (set_attr "prefix_data16" "1")
10832 (set_attr "mode" "TI")])
10834 (define_insn "*ashlti3_2"
10835 [(set (match_operand:TI 0 "register_operand" "=r")
10836 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10837 (match_operand:QI 2 "immediate_operand" "O")))
10838 (clobber (reg:CC FLAGS_REG))]
10841 [(set_attr "type" "multi")])
10844 [(set (match_operand:TI 0 "register_operand" "")
10845 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10846 (match_operand:QI 2 "register_operand" "")))
10847 (clobber (match_scratch:DI 3 ""))
10848 (clobber (reg:CC FLAGS_REG))]
10849 "TARGET_64BIT && reload_completed"
10851 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10854 [(set (match_operand:TI 0 "register_operand" "")
10855 (ashift:TI (match_operand:TI 1 "register_operand" "")
10856 (match_operand:QI 2 "immediate_operand" "")))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "TARGET_64BIT && reload_completed"
10860 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10862 (define_insn "x86_64_shld"
10863 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10864 (ior:DI (ashift:DI (match_dup 0)
10865 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10866 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10867 (minus:QI (const_int 64) (match_dup 2)))))
10868 (clobber (reg:CC FLAGS_REG))]
10871 shld{q}\t{%2, %1, %0|%0, %1, %2}
10872 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10873 [(set_attr "type" "ishift")
10874 (set_attr "prefix_0f" "1")
10875 (set_attr "mode" "DI")
10876 (set_attr "athlon_decode" "vector")
10877 (set_attr "amdfam10_decode" "vector")])
10879 (define_expand "x86_64_shift_adj"
10880 [(set (reg:CCZ FLAGS_REG)
10881 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10884 (set (match_operand:DI 0 "register_operand" "")
10885 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10886 (match_operand:DI 1 "register_operand" "")
10889 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10890 (match_operand:DI 3 "register_operand" "r")
10895 (define_expand "ashldi3"
10896 [(set (match_operand:DI 0 "shiftdi_operand" "")
10897 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10898 (match_operand:QI 2 "nonmemory_operand" "")))]
10900 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10902 (define_insn "*ashldi3_1_rex64"
10903 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10904 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10905 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10909 switch (get_attr_type (insn))
10912 gcc_assert (operands[2] == const1_rtx);
10913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10914 return "add{q}\t%0, %0";
10917 gcc_assert (CONST_INT_P (operands[2]));
10918 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10919 operands[1] = gen_rtx_MULT (DImode, operands[1],
10920 GEN_INT (1 << INTVAL (operands[2])));
10921 return "lea{q}\t{%a1, %0|%0, %a1}";
10924 if (REG_P (operands[2]))
10925 return "sal{q}\t{%b2, %0|%0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 return "sal{q}\t%0";
10930 return "sal{q}\t{%2, %0|%0, %2}";
10933 [(set (attr "type")
10934 (cond [(eq_attr "alternative" "1")
10935 (const_string "lea")
10936 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938 (match_operand 0 "register_operand" ""))
10939 (match_operand 2 "const1_operand" ""))
10940 (const_string "alu")
10942 (const_string "ishift")))
10943 (set_attr "mode" "DI")])
10945 ;; Convert lea to the lea pattern to avoid flags dependency.
10947 [(set (match_operand:DI 0 "register_operand" "")
10948 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10949 (match_operand:QI 2 "immediate_operand" "")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_64BIT && reload_completed
10952 && true_regnum (operands[0]) != true_regnum (operands[1])"
10953 [(set (match_dup 0)
10954 (mult:DI (match_dup 1)
10956 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags. We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashldi3_cmp_rex64"
10962 [(set (reg FLAGS_REG)
10964 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "immediate_operand" "e"))
10967 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10968 (ashift:DI (match_dup 1) (match_dup 2)))]
10971 || !TARGET_PARTIAL_FLAG_REG_STALL
10972 || (operands[2] == const1_rtx
10974 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10975 && ix86_match_ccmode (insn, CCGOCmode)
10976 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10978 switch (get_attr_type (insn))
10981 gcc_assert (operands[2] == const1_rtx);
10982 return "add{q}\t%0, %0";
10985 if (REG_P (operands[2]))
10986 return "sal{q}\t{%b2, %0|%0, %b2}";
10987 else if (operands[2] == const1_rtx
10988 && (TARGET_SHIFT1 || optimize_size))
10989 return "sal{q}\t%0";
10991 return "sal{q}\t{%2, %0|%0, %2}";
10994 [(set (attr "type")
10995 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997 (match_operand 0 "register_operand" ""))
10998 (match_operand 2 "const1_operand" ""))
10999 (const_string "alu")
11001 (const_string "ishift")))
11002 (set_attr "mode" "DI")])
11004 (define_insn "*ashldi3_cconly_rex64"
11005 [(set (reg FLAGS_REG)
11007 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11008 (match_operand:QI 2 "immediate_operand" "e"))
11010 (clobber (match_scratch:DI 0 "=r"))]
11013 || !TARGET_PARTIAL_FLAG_REG_STALL
11014 || (operands[2] == const1_rtx
11016 || TARGET_DOUBLE_WITH_ADD)))
11017 && ix86_match_ccmode (insn, CCGOCmode)
11018 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11020 switch (get_attr_type (insn))
11023 gcc_assert (operands[2] == const1_rtx);
11024 return "add{q}\t%0, %0";
11027 if (REG_P (operands[2]))
11028 return "sal{q}\t{%b2, %0|%0, %b2}";
11029 else if (operands[2] == const1_rtx
11030 && (TARGET_SHIFT1 || optimize_size))
11031 return "sal{q}\t%0";
11033 return "sal{q}\t{%2, %0|%0, %2}";
11036 [(set (attr "type")
11037 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 0 "register_operand" ""))
11040 (match_operand 2 "const1_operand" ""))
11041 (const_string "alu")
11043 (const_string "ishift")))
11044 (set_attr "mode" "DI")])
11046 (define_insn "*ashldi3_1"
11047 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11048 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11049 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11050 (clobber (reg:CC FLAGS_REG))]
11053 [(set_attr "type" "multi")])
11055 ;; By default we don't ask for a scratch register, because when DImode
11056 ;; values are manipulated, registers are already at a premium. But if
11057 ;; we have one handy, we won't turn it away.
11059 [(match_scratch:SI 3 "r")
11060 (parallel [(set (match_operand:DI 0 "register_operand" "")
11061 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11062 (match_operand:QI 2 "nonmemory_operand" "")))
11063 (clobber (reg:CC FLAGS_REG))])
11065 "!TARGET_64BIT && TARGET_CMOVE"
11067 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11070 [(set (match_operand:DI 0 "register_operand" "")
11071 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11072 (match_operand:QI 2 "nonmemory_operand" "")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11075 ? epilogue_completed : reload_completed)"
11077 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11079 (define_insn "x86_shld_1"
11080 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11081 (ior:SI (ashift:SI (match_dup 0)
11082 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11083 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11084 (minus:QI (const_int 32) (match_dup 2)))))
11085 (clobber (reg:CC FLAGS_REG))]
11088 shld{l}\t{%2, %1, %0|%0, %1, %2}
11089 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11090 [(set_attr "type" "ishift")
11091 (set_attr "prefix_0f" "1")
11092 (set_attr "mode" "SI")
11093 (set_attr "pent_pair" "np")
11094 (set_attr "athlon_decode" "vector")
11095 (set_attr "amdfam10_decode" "vector")])
11097 (define_expand "x86_shift_adj_1"
11098 [(set (reg:CCZ FLAGS_REG)
11099 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11102 (set (match_operand:SI 0 "register_operand" "")
11103 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11104 (match_operand:SI 1 "register_operand" "")
11107 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11108 (match_operand:SI 3 "register_operand" "r")
11113 (define_expand "x86_shift_adj_2"
11114 [(use (match_operand:SI 0 "register_operand" ""))
11115 (use (match_operand:SI 1 "register_operand" ""))
11116 (use (match_operand:QI 2 "register_operand" ""))]
11119 rtx label = gen_label_rtx ();
11122 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11124 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11125 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11126 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11127 gen_rtx_LABEL_REF (VOIDmode, label),
11129 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11130 JUMP_LABEL (tmp) = label;
11132 emit_move_insn (operands[0], operands[1]);
11133 ix86_expand_clear (operands[1]);
11135 emit_label (label);
11136 LABEL_NUSES (label) = 1;
11141 (define_expand "ashlsi3"
11142 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11143 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11144 (match_operand:QI 2 "nonmemory_operand" "")))
11145 (clobber (reg:CC FLAGS_REG))]
11147 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11149 (define_insn "*ashlsi3_1"
11150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11151 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11152 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11156 switch (get_attr_type (insn))
11159 gcc_assert (operands[2] == const1_rtx);
11160 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11161 return "add{l}\t%0, %0";
11167 if (REG_P (operands[2]))
11168 return "sal{l}\t{%b2, %0|%0, %b2}";
11169 else if (operands[2] == const1_rtx
11170 && (TARGET_SHIFT1 || optimize_size))
11171 return "sal{l}\t%0";
11173 return "sal{l}\t{%2, %0|%0, %2}";
11176 [(set (attr "type")
11177 (cond [(eq_attr "alternative" "1")
11178 (const_string "lea")
11179 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11181 (match_operand 0 "register_operand" ""))
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11188 ;; Convert lea to the lea pattern to avoid flags dependency.
11190 [(set (match_operand 0 "register_operand" "")
11191 (ashift (match_operand 1 "index_register_operand" "")
11192 (match_operand:QI 2 "const_int_operand" "")))
11193 (clobber (reg:CC FLAGS_REG))]
11195 && true_regnum (operands[0]) != true_regnum (operands[1])
11196 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11200 enum machine_mode mode = GET_MODE (operands[0]);
11202 if (GET_MODE_SIZE (mode) < 4)
11203 operands[0] = gen_lowpart (SImode, operands[0]);
11205 operands[1] = gen_lowpart (Pmode, operands[1]);
11206 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11208 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11209 if (Pmode != SImode)
11210 pat = gen_rtx_SUBREG (SImode, pat, 0);
11211 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11215 ;; Rare case of shifting RSP is handled by generating move and shift
11217 [(set (match_operand 0 "register_operand" "")
11218 (ashift (match_operand 1 "register_operand" "")
11219 (match_operand:QI 2 "const_int_operand" "")))
11220 (clobber (reg:CC FLAGS_REG))]
11222 && true_regnum (operands[0]) != true_regnum (operands[1])"
11226 emit_move_insn (operands[0], operands[1]);
11227 pat = gen_rtx_SET (VOIDmode, operands[0],
11228 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11229 operands[0], operands[2]));
11230 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11231 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11235 (define_insn "*ashlsi3_1_zext"
11236 [(set (match_operand:DI 0 "register_operand" "=r,r")
11237 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11238 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11239 (clobber (reg:CC FLAGS_REG))]
11240 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11242 switch (get_attr_type (insn))
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{l}\t%k0, %k0";
11252 if (REG_P (operands[2]))
11253 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11254 else if (operands[2] == const1_rtx
11255 && (TARGET_SHIFT1 || optimize_size))
11256 return "sal{l}\t%k0";
11258 return "sal{l}\t{%2, %k0|%k0, %2}";
11261 [(set (attr "type")
11262 (cond [(eq_attr "alternative" "1")
11263 (const_string "lea")
11264 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11269 (const_string "ishift")))
11270 (set_attr "mode" "SI")])
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11274 [(set (match_operand:DI 0 "register_operand" "")
11275 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11276 (match_operand:QI 2 "const_int_operand" ""))))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && reload_completed
11279 && true_regnum (operands[0]) != true_regnum (operands[1])"
11280 [(set (match_dup 0) (zero_extend:DI
11281 (subreg:SI (mult:SI (match_dup 1)
11282 (match_dup 2)) 0)))]
11284 operands[1] = gen_lowpart (Pmode, operands[1]);
11285 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11288 ;; This pattern can't accept a variable shift count, since shifts by
11289 ;; zero don't affect the flags. We assume that shifts by constant
11290 ;; zero are optimized away.
11291 (define_insn "*ashlsi3_cmp"
11292 [(set (reg FLAGS_REG)
11294 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11295 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11297 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11298 (ashift:SI (match_dup 1) (match_dup 2)))]
11300 || !TARGET_PARTIAL_FLAG_REG_STALL
11301 || (operands[2] == const1_rtx
11303 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11304 && ix86_match_ccmode (insn, CCGOCmode)
11305 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11307 switch (get_attr_type (insn))
11310 gcc_assert (operands[2] == const1_rtx);
11311 return "add{l}\t%0, %0";
11314 if (REG_P (operands[2]))
11315 return "sal{l}\t{%b2, %0|%0, %b2}";
11316 else if (operands[2] == const1_rtx
11317 && (TARGET_SHIFT1 || optimize_size))
11318 return "sal{l}\t%0";
11320 return "sal{l}\t{%2, %0|%0, %2}";
11323 [(set (attr "type")
11324 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11326 (match_operand 0 "register_operand" ""))
11327 (match_operand 2 "const1_operand" ""))
11328 (const_string "alu")
11330 (const_string "ishift")))
11331 (set_attr "mode" "SI")])
11333 (define_insn "*ashlsi3_cconly"
11334 [(set (reg FLAGS_REG)
11336 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11337 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11339 (clobber (match_scratch:SI 0 "=r"))]
11341 || !TARGET_PARTIAL_FLAG_REG_STALL
11342 || (operands[2] == const1_rtx
11344 || TARGET_DOUBLE_WITH_ADD)))
11345 && ix86_match_ccmode (insn, CCGOCmode)
11346 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11348 switch (get_attr_type (insn))
11351 gcc_assert (operands[2] == const1_rtx);
11352 return "add{l}\t%0, %0";
11355 if (REG_P (operands[2]))
11356 return "sal{l}\t{%b2, %0|%0, %b2}";
11357 else if (operands[2] == const1_rtx
11358 && (TARGET_SHIFT1 || optimize_size))
11359 return "sal{l}\t%0";
11361 return "sal{l}\t{%2, %0|%0, %2}";
11364 [(set (attr "type")
11365 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11367 (match_operand 0 "register_operand" ""))
11368 (match_operand 2 "const1_operand" ""))
11369 (const_string "alu")
11371 (const_string "ishift")))
11372 (set_attr "mode" "SI")])
11374 (define_insn "*ashlsi3_cmp_zext"
11375 [(set (reg FLAGS_REG)
11377 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11378 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11380 (set (match_operand:DI 0 "register_operand" "=r")
11381 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11384 || !TARGET_PARTIAL_FLAG_REG_STALL
11385 || (operands[2] == const1_rtx
11387 || TARGET_DOUBLE_WITH_ADD)))
11388 && ix86_match_ccmode (insn, CCGOCmode)
11389 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11391 switch (get_attr_type (insn))
11394 gcc_assert (operands[2] == const1_rtx);
11395 return "add{l}\t%k0, %k0";
11398 if (REG_P (operands[2]))
11399 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11400 else if (operands[2] == const1_rtx
11401 && (TARGET_SHIFT1 || optimize_size))
11402 return "sal{l}\t%k0";
11404 return "sal{l}\t{%2, %k0|%k0, %2}";
11407 [(set (attr "type")
11408 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11410 (match_operand 2 "const1_operand" ""))
11411 (const_string "alu")
11413 (const_string "ishift")))
11414 (set_attr "mode" "SI")])
11416 (define_expand "ashlhi3"
11417 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419 (match_operand:QI 2 "nonmemory_operand" "")))
11420 (clobber (reg:CC FLAGS_REG))]
11421 "TARGET_HIMODE_MATH"
11422 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11424 (define_insn "*ashlhi3_1_lea"
11425 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11426 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11427 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "!TARGET_PARTIAL_REG_STALL
11430 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11432 switch (get_attr_type (insn))
11437 gcc_assert (operands[2] == const1_rtx);
11438 return "add{w}\t%0, %0";
11441 if (REG_P (operands[2]))
11442 return "sal{w}\t{%b2, %0|%0, %b2}";
11443 else if (operands[2] == const1_rtx
11444 && (TARGET_SHIFT1 || optimize_size))
11445 return "sal{w}\t%0";
11447 return "sal{w}\t{%2, %0|%0, %2}";
11450 [(set (attr "type")
11451 (cond [(eq_attr "alternative" "1")
11452 (const_string "lea")
11453 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11455 (match_operand 0 "register_operand" ""))
11456 (match_operand 2 "const1_operand" ""))
11457 (const_string "alu")
11459 (const_string "ishift")))
11460 (set_attr "mode" "HI,SI")])
11462 (define_insn "*ashlhi3_1"
11463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11464 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11465 (match_operand:QI 2 "nonmemory_operand" "cI")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "TARGET_PARTIAL_REG_STALL
11468 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11470 switch (get_attr_type (insn))
11473 gcc_assert (operands[2] == const1_rtx);
11474 return "add{w}\t%0, %0";
11477 if (REG_P (operands[2]))
11478 return "sal{w}\t{%b2, %0|%0, %b2}";
11479 else if (operands[2] == const1_rtx
11480 && (TARGET_SHIFT1 || optimize_size))
11481 return "sal{w}\t%0";
11483 return "sal{w}\t{%2, %0|%0, %2}";
11486 [(set (attr "type")
11487 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11489 (match_operand 0 "register_operand" ""))
11490 (match_operand 2 "const1_operand" ""))
11491 (const_string "alu")
11493 (const_string "ishift")))
11494 (set_attr "mode" "HI")])
11496 ;; This pattern can't accept a variable shift count, since shifts by
11497 ;; zero don't affect the flags. We assume that shifts by constant
11498 ;; zero are optimized away.
11499 (define_insn "*ashlhi3_cmp"
11500 [(set (reg FLAGS_REG)
11502 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11503 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11506 (ashift:HI (match_dup 1) (match_dup 2)))]
11508 || !TARGET_PARTIAL_FLAG_REG_STALL
11509 || (operands[2] == const1_rtx
11511 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11512 && ix86_match_ccmode (insn, CCGOCmode)
11513 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11515 switch (get_attr_type (insn))
11518 gcc_assert (operands[2] == const1_rtx);
11519 return "add{w}\t%0, %0";
11522 if (REG_P (operands[2]))
11523 return "sal{w}\t{%b2, %0|%0, %b2}";
11524 else if (operands[2] == const1_rtx
11525 && (TARGET_SHIFT1 || optimize_size))
11526 return "sal{w}\t%0";
11528 return "sal{w}\t{%2, %0|%0, %2}";
11531 [(set (attr "type")
11532 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11534 (match_operand 0 "register_operand" ""))
11535 (match_operand 2 "const1_operand" ""))
11536 (const_string "alu")
11538 (const_string "ishift")))
11539 (set_attr "mode" "HI")])
11541 (define_insn "*ashlhi3_cconly"
11542 [(set (reg FLAGS_REG)
11544 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11545 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11547 (clobber (match_scratch:HI 0 "=r"))]
11549 || !TARGET_PARTIAL_FLAG_REG_STALL
11550 || (operands[2] == const1_rtx
11552 || TARGET_DOUBLE_WITH_ADD)))
11553 && ix86_match_ccmode (insn, CCGOCmode)
11554 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11556 switch (get_attr_type (insn))
11559 gcc_assert (operands[2] == const1_rtx);
11560 return "add{w}\t%0, %0";
11563 if (REG_P (operands[2]))
11564 return "sal{w}\t{%b2, %0|%0, %b2}";
11565 else if (operands[2] == const1_rtx
11566 && (TARGET_SHIFT1 || optimize_size))
11567 return "sal{w}\t%0";
11569 return "sal{w}\t{%2, %0|%0, %2}";
11572 [(set (attr "type")
11573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11575 (match_operand 0 "register_operand" ""))
11576 (match_operand 2 "const1_operand" ""))
11577 (const_string "alu")
11579 (const_string "ishift")))
11580 (set_attr "mode" "HI")])
11582 (define_expand "ashlqi3"
11583 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11584 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))
11586 (clobber (reg:CC FLAGS_REG))]
11587 "TARGET_QIMODE_MATH"
11588 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11590 ;; %%% Potential partial reg stall on alternative 2. What to do?
11592 (define_insn "*ashlqi3_1_lea"
11593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11594 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11595 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "!TARGET_PARTIAL_REG_STALL
11598 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11600 switch (get_attr_type (insn))
11605 gcc_assert (operands[2] == const1_rtx);
11606 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11607 return "add{l}\t%k0, %k0";
11609 return "add{b}\t%0, %0";
11612 if (REG_P (operands[2]))
11614 if (get_attr_mode (insn) == MODE_SI)
11615 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11617 return "sal{b}\t{%b2, %0|%0, %b2}";
11619 else if (operands[2] == const1_rtx
11620 && (TARGET_SHIFT1 || optimize_size))
11622 if (get_attr_mode (insn) == MODE_SI)
11623 return "sal{l}\t%0";
11625 return "sal{b}\t%0";
11629 if (get_attr_mode (insn) == MODE_SI)
11630 return "sal{l}\t{%2, %k0|%k0, %2}";
11632 return "sal{b}\t{%2, %0|%0, %2}";
11636 [(set (attr "type")
11637 (cond [(eq_attr "alternative" "2")
11638 (const_string "lea")
11639 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11641 (match_operand 0 "register_operand" ""))
11642 (match_operand 2 "const1_operand" ""))
11643 (const_string "alu")
11645 (const_string "ishift")))
11646 (set_attr "mode" "QI,SI,SI")])
11648 (define_insn "*ashlqi3_1"
11649 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11650 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11651 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11652 (clobber (reg:CC FLAGS_REG))]
11653 "TARGET_PARTIAL_REG_STALL
11654 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11656 switch (get_attr_type (insn))
11659 gcc_assert (operands[2] == const1_rtx);
11660 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11661 return "add{l}\t%k0, %k0";
11663 return "add{b}\t%0, %0";
11666 if (REG_P (operands[2]))
11668 if (get_attr_mode (insn) == MODE_SI)
11669 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11671 return "sal{b}\t{%b2, %0|%0, %b2}";
11673 else if (operands[2] == const1_rtx
11674 && (TARGET_SHIFT1 || optimize_size))
11676 if (get_attr_mode (insn) == MODE_SI)
11677 return "sal{l}\t%0";
11679 return "sal{b}\t%0";
11683 if (get_attr_mode (insn) == MODE_SI)
11684 return "sal{l}\t{%2, %k0|%k0, %2}";
11686 return "sal{b}\t{%2, %0|%0, %2}";
11690 [(set (attr "type")
11691 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11693 (match_operand 0 "register_operand" ""))
11694 (match_operand 2 "const1_operand" ""))
11695 (const_string "alu")
11697 (const_string "ishift")))
11698 (set_attr "mode" "QI,SI")])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags. We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*ashlqi3_cmp"
11704 [(set (reg FLAGS_REG)
11706 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11709 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11710 (ashift:QI (match_dup 1) (match_dup 2)))]
11712 || !TARGET_PARTIAL_FLAG_REG_STALL
11713 || (operands[2] == const1_rtx
11715 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11716 && ix86_match_ccmode (insn, CCGOCmode)
11717 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11719 switch (get_attr_type (insn))
11722 gcc_assert (operands[2] == const1_rtx);
11723 return "add{b}\t%0, %0";
11726 if (REG_P (operands[2]))
11727 return "sal{b}\t{%b2, %0|%0, %b2}";
11728 else if (operands[2] == const1_rtx
11729 && (TARGET_SHIFT1 || optimize_size))
11730 return "sal{b}\t%0";
11732 return "sal{b}\t{%2, %0|%0, %2}";
11735 [(set (attr "type")
11736 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11738 (match_operand 0 "register_operand" ""))
11739 (match_operand 2 "const1_operand" ""))
11740 (const_string "alu")
11742 (const_string "ishift")))
11743 (set_attr "mode" "QI")])
11745 (define_insn "*ashlqi3_cconly"
11746 [(set (reg FLAGS_REG)
11748 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11751 (clobber (match_scratch:QI 0 "=q"))]
11753 || !TARGET_PARTIAL_FLAG_REG_STALL
11754 || (operands[2] == const1_rtx
11756 || TARGET_DOUBLE_WITH_ADD)))
11757 && ix86_match_ccmode (insn, CCGOCmode)
11758 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11760 switch (get_attr_type (insn))
11763 gcc_assert (operands[2] == const1_rtx);
11764 return "add{b}\t%0, %0";
11767 if (REG_P (operands[2]))
11768 return "sal{b}\t{%b2, %0|%0, %b2}";
11769 else if (operands[2] == const1_rtx
11770 && (TARGET_SHIFT1 || optimize_size))
11771 return "sal{b}\t%0";
11773 return "sal{b}\t{%2, %0|%0, %2}";
11776 [(set (attr "type")
11777 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11779 (match_operand 0 "register_operand" ""))
11780 (match_operand 2 "const1_operand" ""))
11781 (const_string "alu")
11783 (const_string "ishift")))
11784 (set_attr "mode" "QI")])
11786 ;; See comment above `ashldi3' about how this works.
11788 (define_expand "ashrti3"
11789 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11790 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11791 (match_operand:QI 2 "nonmemory_operand" "")))
11792 (clobber (reg:CC FLAGS_REG))])]
11795 if (! immediate_operand (operands[2], QImode))
11797 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11800 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11804 (define_insn "ashrti3_1"
11805 [(set (match_operand:TI 0 "register_operand" "=r")
11806 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11807 (match_operand:QI 2 "register_operand" "c")))
11808 (clobber (match_scratch:DI 3 "=&r"))
11809 (clobber (reg:CC FLAGS_REG))]
11812 [(set_attr "type" "multi")])
11814 (define_insn "*ashrti3_2"
11815 [(set (match_operand:TI 0 "register_operand" "=r")
11816 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11817 (match_operand:QI 2 "immediate_operand" "O")))
11818 (clobber (reg:CC FLAGS_REG))]
11821 [(set_attr "type" "multi")])
11824 [(set (match_operand:TI 0 "register_operand" "")
11825 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11826 (match_operand:QI 2 "register_operand" "")))
11827 (clobber (match_scratch:DI 3 ""))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "TARGET_64BIT && reload_completed"
11831 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11834 [(set (match_operand:TI 0 "register_operand" "")
11835 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11836 (match_operand:QI 2 "immediate_operand" "")))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "TARGET_64BIT && reload_completed"
11840 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11842 (define_insn "x86_64_shrd"
11843 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11844 (ior:DI (ashiftrt:DI (match_dup 0)
11845 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11846 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11847 (minus:QI (const_int 64) (match_dup 2)))))
11848 (clobber (reg:CC FLAGS_REG))]
11851 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11852 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11853 [(set_attr "type" "ishift")
11854 (set_attr "prefix_0f" "1")
11855 (set_attr "mode" "DI")
11856 (set_attr "athlon_decode" "vector")
11857 (set_attr "amdfam10_decode" "vector")])
11859 (define_expand "ashrdi3"
11860 [(set (match_operand:DI 0 "shiftdi_operand" "")
11861 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11862 (match_operand:QI 2 "nonmemory_operand" "")))]
11864 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11866 (define_insn "*ashrdi3_63_rex64"
11867 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11868 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11869 (match_operand:DI 2 "const_int_operand" "i,i")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "TARGET_64BIT && INTVAL (operands[2]) == 63
11872 && (TARGET_USE_CLTD || optimize_size)
11873 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11876 sar{q}\t{%2, %0|%0, %2}"
11877 [(set_attr "type" "imovx,ishift")
11878 (set_attr "prefix_0f" "0,*")
11879 (set_attr "length_immediate" "0,*")
11880 (set_attr "modrm" "0,1")
11881 (set_attr "mode" "DI")])
11883 (define_insn "*ashrdi3_1_one_bit_rex64"
11884 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11885 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const1_operand" "")))
11887 (clobber (reg:CC FLAGS_REG))]
11889 && (TARGET_SHIFT1 || optimize_size)
11890 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11892 [(set_attr "type" "ishift")
11893 (set (attr "length")
11894 (if_then_else (match_operand:DI 0 "register_operand" "")
11896 (const_string "*")))])
11898 (define_insn "*ashrdi3_1_rex64"
11899 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11900 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11901 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11905 sar{q}\t{%2, %0|%0, %2}
11906 sar{q}\t{%b2, %0|%0, %b2}"
11907 [(set_attr "type" "ishift")
11908 (set_attr "mode" "DI")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags. We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11914 [(set (reg FLAGS_REG)
11916 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const1_operand" ""))
11919 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11920 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11922 && (TARGET_SHIFT1 || optimize_size)
11923 && ix86_match_ccmode (insn, CCGOCmode)
11924 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11926 [(set_attr "type" "ishift")
11927 (set (attr "length")
11928 (if_then_else (match_operand:DI 0 "register_operand" "")
11930 (const_string "*")))])
11932 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11933 [(set (reg FLAGS_REG)
11935 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11936 (match_operand:QI 2 "const1_operand" ""))
11938 (clobber (match_scratch:DI 0 "=r"))]
11940 && (TARGET_SHIFT1 || optimize_size)
11941 && ix86_match_ccmode (insn, CCGOCmode)
11942 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11944 [(set_attr "type" "ishift")
11945 (set_attr "length" "2")])
11947 ;; This pattern can't accept a variable shift count, since shifts by
11948 ;; zero don't affect the flags. We assume that shifts by constant
11949 ;; zero are optimized away.
11950 (define_insn "*ashrdi3_cmp_rex64"
11951 [(set (reg FLAGS_REG)
11953 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11954 (match_operand:QI 2 "const_int_operand" "n"))
11956 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11957 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11959 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11960 && ix86_match_ccmode (insn, CCGOCmode)
11961 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11962 "sar{q}\t{%2, %0|%0, %2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "DI")])
11966 (define_insn "*ashrdi3_cconly_rex64"
11967 [(set (reg FLAGS_REG)
11969 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11970 (match_operand:QI 2 "const_int_operand" "n"))
11972 (clobber (match_scratch:DI 0 "=r"))]
11974 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11975 && ix86_match_ccmode (insn, CCGOCmode)
11976 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11977 "sar{q}\t{%2, %0|%0, %2}"
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "DI")])
11981 (define_insn "*ashrdi3_1"
11982 [(set (match_operand:DI 0 "register_operand" "=r")
11983 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11984 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11985 (clobber (reg:CC FLAGS_REG))]
11988 [(set_attr "type" "multi")])
11990 ;; By default we don't ask for a scratch register, because when DImode
11991 ;; values are manipulated, registers are already at a premium. But if
11992 ;; we have one handy, we won't turn it away.
11994 [(match_scratch:SI 3 "r")
11995 (parallel [(set (match_operand:DI 0 "register_operand" "")
11996 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11997 (match_operand:QI 2 "nonmemory_operand" "")))
11998 (clobber (reg:CC FLAGS_REG))])
12000 "!TARGET_64BIT && TARGET_CMOVE"
12002 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12005 [(set (match_operand:DI 0 "register_operand" "")
12006 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12007 (match_operand:QI 2 "nonmemory_operand" "")))
12008 (clobber (reg:CC FLAGS_REG))]
12009 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12010 ? epilogue_completed : reload_completed)"
12012 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12014 (define_insn "x86_shrd_1"
12015 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12016 (ior:SI (ashiftrt:SI (match_dup 0)
12017 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12018 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12019 (minus:QI (const_int 32) (match_dup 2)))))
12020 (clobber (reg:CC FLAGS_REG))]
12023 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12024 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12025 [(set_attr "type" "ishift")
12026 (set_attr "prefix_0f" "1")
12027 (set_attr "pent_pair" "np")
12028 (set_attr "mode" "SI")])
12030 (define_expand "x86_shift_adj_3"
12031 [(use (match_operand:SI 0 "register_operand" ""))
12032 (use (match_operand:SI 1 "register_operand" ""))
12033 (use (match_operand:QI 2 "register_operand" ""))]
12036 rtx label = gen_label_rtx ();
12039 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12041 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12042 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12043 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12044 gen_rtx_LABEL_REF (VOIDmode, label),
12046 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12047 JUMP_LABEL (tmp) = label;
12049 emit_move_insn (operands[0], operands[1]);
12050 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12052 emit_label (label);
12053 LABEL_NUSES (label) = 1;
12058 (define_insn "ashrsi3_31"
12059 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12060 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12061 (match_operand:SI 2 "const_int_operand" "i,i")))
12062 (clobber (reg:CC FLAGS_REG))]
12063 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12067 sar{l}\t{%2, %0|%0, %2}"
12068 [(set_attr "type" "imovx,ishift")
12069 (set_attr "prefix_0f" "0,*")
12070 (set_attr "length_immediate" "0,*")
12071 (set_attr "modrm" "0,1")
12072 (set_attr "mode" "SI")])
12074 (define_insn "*ashrsi3_31_zext"
12075 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12076 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12077 (match_operand:SI 2 "const_int_operand" "i,i"))))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12080 && INTVAL (operands[2]) == 31
12081 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12084 sar{l}\t{%2, %k0|%k0, %2}"
12085 [(set_attr "type" "imovx,ishift")
12086 (set_attr "prefix_0f" "0,*")
12087 (set_attr "length_immediate" "0,*")
12088 (set_attr "modrm" "0,1")
12089 (set_attr "mode" "SI")])
12091 (define_expand "ashrsi3"
12092 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12093 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12094 (match_operand:QI 2 "nonmemory_operand" "")))
12095 (clobber (reg:CC FLAGS_REG))]
12097 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12099 (define_insn "*ashrsi3_1_one_bit"
12100 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12101 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12102 (match_operand:QI 2 "const1_operand" "")))
12103 (clobber (reg:CC FLAGS_REG))]
12104 "(TARGET_SHIFT1 || optimize_size)
12105 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12107 [(set_attr "type" "ishift")
12108 (set (attr "length")
12109 (if_then_else (match_operand:SI 0 "register_operand" "")
12111 (const_string "*")))])
12113 (define_insn "*ashrsi3_1_one_bit_zext"
12114 [(set (match_operand:DI 0 "register_operand" "=r")
12115 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12116 (match_operand:QI 2 "const1_operand" ""))))
12117 (clobber (reg:CC FLAGS_REG))]
12119 && (TARGET_SHIFT1 || optimize_size)
12120 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12122 [(set_attr "type" "ishift")
12123 (set_attr "length" "2")])
12125 (define_insn "*ashrsi3_1"
12126 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12127 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12128 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12132 sar{l}\t{%2, %0|%0, %2}
12133 sar{l}\t{%b2, %0|%0, %b2}"
12134 [(set_attr "type" "ishift")
12135 (set_attr "mode" "SI")])
12137 (define_insn "*ashrsi3_1_zext"
12138 [(set (match_operand:DI 0 "register_operand" "=r,r")
12139 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12140 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12144 sar{l}\t{%2, %k0|%k0, %2}
12145 sar{l}\t{%b2, %k0|%k0, %b2}"
12146 [(set_attr "type" "ishift")
12147 (set_attr "mode" "SI")])
12149 ;; This pattern can't accept a variable shift count, since shifts by
12150 ;; zero don't affect the flags. We assume that shifts by constant
12151 ;; zero are optimized away.
12152 (define_insn "*ashrsi3_one_bit_cmp"
12153 [(set (reg FLAGS_REG)
12155 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12156 (match_operand:QI 2 "const1_operand" ""))
12158 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12159 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12160 "(TARGET_SHIFT1 || optimize_size)
12161 && ix86_match_ccmode (insn, CCGOCmode)
12162 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12164 [(set_attr "type" "ishift")
12165 (set (attr "length")
12166 (if_then_else (match_operand:SI 0 "register_operand" "")
12168 (const_string "*")))])
12170 (define_insn "*ashrsi3_one_bit_cconly"
12171 [(set (reg FLAGS_REG)
12173 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const1_operand" ""))
12176 (clobber (match_scratch:SI 0 "=r"))]
12177 "(TARGET_SHIFT1 || optimize_size)
12178 && ix86_match_ccmode (insn, CCGOCmode)
12179 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_one_bit_cmp_zext"
12185 [(set (reg FLAGS_REG)
12187 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12188 (match_operand:QI 2 "const1_operand" ""))
12190 (set (match_operand:DI 0 "register_operand" "=r")
12191 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12193 && (TARGET_SHIFT1 || optimize_size)
12194 && ix86_match_ccmode (insn, CCmode)
12195 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set_attr "length" "2")])
12200 ;; This pattern can't accept a variable shift count, since shifts by
12201 ;; zero don't affect the flags. We assume that shifts by constant
12202 ;; zero are optimized away.
12203 (define_insn "*ashrsi3_cmp"
12204 [(set (reg FLAGS_REG)
12206 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12209 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12210 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12211 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12212 && ix86_match_ccmode (insn, CCGOCmode)
12213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214 "sar{l}\t{%2, %0|%0, %2}"
12215 [(set_attr "type" "ishift")
12216 (set_attr "mode" "SI")])
12218 (define_insn "*ashrsi3_cconly"
12219 [(set (reg FLAGS_REG)
12221 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12222 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12224 (clobber (match_scratch:SI 0 "=r"))]
12225 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12226 && ix86_match_ccmode (insn, CCGOCmode)
12227 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12228 "sar{l}\t{%2, %0|%0, %2}"
12229 [(set_attr "type" "ishift")
12230 (set_attr "mode" "SI")])
12232 (define_insn "*ashrsi3_cmp_zext"
12233 [(set (reg FLAGS_REG)
12235 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12236 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12238 (set (match_operand:DI 0 "register_operand" "=r")
12239 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12241 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12242 && ix86_match_ccmode (insn, CCGOCmode)
12243 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12244 "sar{l}\t{%2, %k0|%k0, %2}"
12245 [(set_attr "type" "ishift")
12246 (set_attr "mode" "SI")])
12248 (define_expand "ashrhi3"
12249 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12250 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12251 (match_operand:QI 2 "nonmemory_operand" "")))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_HIMODE_MATH"
12254 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12256 (define_insn "*ashrhi3_1_one_bit"
12257 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12258 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12259 (match_operand:QI 2 "const1_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))]
12261 "(TARGET_SHIFT1 || optimize_size)
12262 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12264 [(set_attr "type" "ishift")
12265 (set (attr "length")
12266 (if_then_else (match_operand 0 "register_operand" "")
12268 (const_string "*")))])
12270 (define_insn "*ashrhi3_1"
12271 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12272 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12273 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12274 (clobber (reg:CC FLAGS_REG))]
12275 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12277 sar{w}\t{%2, %0|%0, %2}
12278 sar{w}\t{%b2, %0|%0, %b2}"
12279 [(set_attr "type" "ishift")
12280 (set_attr "mode" "HI")])
12282 ;; This pattern can't accept a variable shift count, since shifts by
12283 ;; zero don't affect the flags. We assume that shifts by constant
12284 ;; zero are optimized away.
12285 (define_insn "*ashrhi3_one_bit_cmp"
12286 [(set (reg FLAGS_REG)
12288 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12289 (match_operand:QI 2 "const1_operand" ""))
12291 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12292 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12293 "(TARGET_SHIFT1 || optimize_size)
12294 && ix86_match_ccmode (insn, CCGOCmode)
12295 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12297 [(set_attr "type" "ishift")
12298 (set (attr "length")
12299 (if_then_else (match_operand 0 "register_operand" "")
12301 (const_string "*")))])
12303 (define_insn "*ashrhi3_one_bit_cconly"
12304 [(set (reg FLAGS_REG)
12306 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12307 (match_operand:QI 2 "const1_operand" ""))
12309 (clobber (match_scratch:HI 0 "=r"))]
12310 "(TARGET_SHIFT1 || optimize_size)
12311 && ix86_match_ccmode (insn, CCGOCmode)
12312 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12314 [(set_attr "type" "ishift")
12315 (set_attr "length" "2")])
12317 ;; This pattern can't accept a variable shift count, since shifts by
12318 ;; zero don't affect the flags. We assume that shifts by constant
12319 ;; zero are optimized away.
12320 (define_insn "*ashrhi3_cmp"
12321 [(set (reg FLAGS_REG)
12323 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12326 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12327 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12328 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12329 && ix86_match_ccmode (insn, CCGOCmode)
12330 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12331 "sar{w}\t{%2, %0|%0, %2}"
12332 [(set_attr "type" "ishift")
12333 (set_attr "mode" "HI")])
12335 (define_insn "*ashrhi3_cconly"
12336 [(set (reg FLAGS_REG)
12338 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12339 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12341 (clobber (match_scratch:HI 0 "=r"))]
12342 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12343 && ix86_match_ccmode (insn, CCGOCmode)
12344 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12345 "sar{w}\t{%2, %0|%0, %2}"
12346 [(set_attr "type" "ishift")
12347 (set_attr "mode" "HI")])
12349 (define_expand "ashrqi3"
12350 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12351 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12352 (match_operand:QI 2 "nonmemory_operand" "")))
12353 (clobber (reg:CC FLAGS_REG))]
12354 "TARGET_QIMODE_MATH"
12355 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12357 (define_insn "*ashrqi3_1_one_bit"
12358 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12359 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12360 (match_operand:QI 2 "const1_operand" "")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "(TARGET_SHIFT1 || optimize_size)
12363 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12365 [(set_attr "type" "ishift")
12366 (set (attr "length")
12367 (if_then_else (match_operand 0 "register_operand" "")
12369 (const_string "*")))])
12371 (define_insn "*ashrqi3_1_one_bit_slp"
12372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12373 (ashiftrt:QI (match_dup 0)
12374 (match_operand:QI 1 "const1_operand" "")))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12377 && (TARGET_SHIFT1 || optimize_size)
12378 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12380 [(set_attr "type" "ishift1")
12381 (set (attr "length")
12382 (if_then_else (match_operand 0 "register_operand" "")
12384 (const_string "*")))])
12386 (define_insn "*ashrqi3_1"
12387 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12388 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12389 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12393 sar{b}\t{%2, %0|%0, %2}
12394 sar{b}\t{%b2, %0|%0, %b2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "QI")])
12398 (define_insn "*ashrqi3_1_slp"
12399 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12400 (ashiftrt:QI (match_dup 0)
12401 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12402 (clobber (reg:CC FLAGS_REG))]
12403 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12404 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12406 sar{b}\t{%1, %0|%0, %1}
12407 sar{b}\t{%b1, %0|%0, %b1}"
12408 [(set_attr "type" "ishift1")
12409 (set_attr "mode" "QI")])
12411 ;; This pattern can't accept a variable shift count, since shifts by
12412 ;; zero don't affect the flags. We assume that shifts by constant
12413 ;; zero are optimized away.
12414 (define_insn "*ashrqi3_one_bit_cmp"
12415 [(set (reg FLAGS_REG)
12417 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12418 (match_operand:QI 2 "const1_operand" "I"))
12420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12421 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12422 "(TARGET_SHIFT1 || optimize_size)
12423 && ix86_match_ccmode (insn, CCGOCmode)
12424 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12426 [(set_attr "type" "ishift")
12427 (set (attr "length")
12428 (if_then_else (match_operand 0 "register_operand" "")
12430 (const_string "*")))])
12432 (define_insn "*ashrqi3_one_bit_cconly"
12433 [(set (reg FLAGS_REG)
12435 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const1_operand" "I"))
12438 (clobber (match_scratch:QI 0 "=q"))]
12439 "(TARGET_SHIFT1 || optimize_size)
12440 && ix86_match_ccmode (insn, CCGOCmode)
12441 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12443 [(set_attr "type" "ishift")
12444 (set_attr "length" "2")])
12446 ;; This pattern can't accept a variable shift count, since shifts by
12447 ;; zero don't affect the flags. We assume that shifts by constant
12448 ;; zero are optimized away.
12449 (define_insn "*ashrqi3_cmp"
12450 [(set (reg FLAGS_REG)
12452 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12455 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12456 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12457 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12458 && ix86_match_ccmode (insn, CCGOCmode)
12459 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12460 "sar{b}\t{%2, %0|%0, %2}"
12461 [(set_attr "type" "ishift")
12462 (set_attr "mode" "QI")])
12464 (define_insn "*ashrqi3_cconly"
12465 [(set (reg FLAGS_REG)
12467 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12468 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12470 (clobber (match_scratch:QI 0 "=q"))]
12471 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12472 && ix86_match_ccmode (insn, CCGOCmode)
12473 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12474 "sar{b}\t{%2, %0|%0, %2}"
12475 [(set_attr "type" "ishift")
12476 (set_attr "mode" "QI")])
12479 ;; Logical shift instructions
12481 ;; See comment above `ashldi3' about how this works.
12483 (define_expand "lshrti3"
12484 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12485 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12486 (match_operand:QI 2 "nonmemory_operand" "")))
12487 (clobber (reg:CC FLAGS_REG))])]
12490 if (! immediate_operand (operands[2], QImode))
12492 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12495 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12499 (define_insn "lshrti3_1"
12500 [(set (match_operand:TI 0 "register_operand" "=r")
12501 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12502 (match_operand:QI 2 "register_operand" "c")))
12503 (clobber (match_scratch:DI 3 "=&r"))
12504 (clobber (reg:CC FLAGS_REG))]
12507 [(set_attr "type" "multi")])
12509 ;; This pattern must be defined before *lshrti3_2 to prevent
12510 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12512 (define_insn "sse2_lshrti3"
12513 [(set (match_operand:TI 0 "register_operand" "=x")
12514 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12515 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12518 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12519 return "psrldq\t{%2, %0|%0, %2}";
12521 [(set_attr "type" "sseishft")
12522 (set_attr "prefix_data16" "1")
12523 (set_attr "mode" "TI")])
12525 (define_insn "*lshrti3_2"
12526 [(set (match_operand:TI 0 "register_operand" "=r")
12527 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12528 (match_operand:QI 2 "immediate_operand" "O")))
12529 (clobber (reg:CC FLAGS_REG))]
12532 [(set_attr "type" "multi")])
12535 [(set (match_operand:TI 0 "register_operand" "")
12536 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12537 (match_operand:QI 2 "register_operand" "")))
12538 (clobber (match_scratch:DI 3 ""))
12539 (clobber (reg:CC FLAGS_REG))]
12540 "TARGET_64BIT && reload_completed"
12542 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12545 [(set (match_operand:TI 0 "register_operand" "")
12546 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12547 (match_operand:QI 2 "immediate_operand" "")))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "TARGET_64BIT && reload_completed"
12551 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12553 (define_expand "lshrdi3"
12554 [(set (match_operand:DI 0 "shiftdi_operand" "")
12555 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12556 (match_operand:QI 2 "nonmemory_operand" "")))]
12558 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12560 (define_insn "*lshrdi3_1_one_bit_rex64"
12561 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12562 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const1_operand" "")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 && (TARGET_SHIFT1 || optimize_size)
12567 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12569 [(set_attr "type" "ishift")
12570 (set (attr "length")
12571 (if_then_else (match_operand:DI 0 "register_operand" "")
12573 (const_string "*")))])
12575 (define_insn "*lshrdi3_1_rex64"
12576 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12577 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12578 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12579 (clobber (reg:CC FLAGS_REG))]
12580 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12582 shr{q}\t{%2, %0|%0, %2}
12583 shr{q}\t{%b2, %0|%0, %b2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "DI")])
12587 ;; This pattern can't accept a variable shift count, since shifts by
12588 ;; zero don't affect the flags. We assume that shifts by constant
12589 ;; zero are optimized away.
12590 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12591 [(set (reg FLAGS_REG)
12593 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12594 (match_operand:QI 2 "const1_operand" ""))
12596 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12597 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12599 && (TARGET_SHIFT1 || optimize_size)
12600 && ix86_match_ccmode (insn, CCGOCmode)
12601 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12603 [(set_attr "type" "ishift")
12604 (set (attr "length")
12605 (if_then_else (match_operand:DI 0 "register_operand" "")
12607 (const_string "*")))])
12609 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const1_operand" ""))
12615 (clobber (match_scratch:DI 0 "=r"))]
12617 && (TARGET_SHIFT1 || optimize_size)
12618 && ix86_match_ccmode (insn, CCGOCmode)
12619 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621 [(set_attr "type" "ishift")
12622 (set_attr "length" "2")])
12624 ;; This pattern can't accept a variable shift count, since shifts by
12625 ;; zero don't affect the flags. We assume that shifts by constant
12626 ;; zero are optimized away.
12627 (define_insn "*lshrdi3_cmp_rex64"
12628 [(set (reg FLAGS_REG)
12630 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12631 (match_operand:QI 2 "const_int_operand" "e"))
12633 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12634 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12636 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12637 && ix86_match_ccmode (insn, CCGOCmode)
12638 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12639 "shr{q}\t{%2, %0|%0, %2}"
12640 [(set_attr "type" "ishift")
12641 (set_attr "mode" "DI")])
12643 (define_insn "*lshrdi3_cconly_rex64"
12644 [(set (reg FLAGS_REG)
12646 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647 (match_operand:QI 2 "const_int_operand" "e"))
12649 (clobber (match_scratch:DI 0 "=r"))]
12651 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12652 && ix86_match_ccmode (insn, CCGOCmode)
12653 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12654 "shr{q}\t{%2, %0|%0, %2}"
12655 [(set_attr "type" "ishift")
12656 (set_attr "mode" "DI")])
12658 (define_insn "*lshrdi3_1"
12659 [(set (match_operand:DI 0 "register_operand" "=r")
12660 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12661 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12662 (clobber (reg:CC FLAGS_REG))]
12665 [(set_attr "type" "multi")])
12667 ;; By default we don't ask for a scratch register, because when DImode
12668 ;; values are manipulated, registers are already at a premium. But if
12669 ;; we have one handy, we won't turn it away.
12671 [(match_scratch:SI 3 "r")
12672 (parallel [(set (match_operand:DI 0 "register_operand" "")
12673 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12674 (match_operand:QI 2 "nonmemory_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))])
12677 "!TARGET_64BIT && TARGET_CMOVE"
12679 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12682 [(set (match_operand:DI 0 "register_operand" "")
12683 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12684 (match_operand:QI 2 "nonmemory_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12687 ? epilogue_completed : reload_completed)"
12689 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12691 (define_expand "lshrsi3"
12692 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12693 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12694 (match_operand:QI 2 "nonmemory_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12697 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12699 (define_insn "*lshrsi3_1_one_bit"
12700 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12701 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const1_operand" "")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "(TARGET_SHIFT1 || optimize_size)
12705 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707 [(set_attr "type" "ishift")
12708 (set (attr "length")
12709 (if_then_else (match_operand:SI 0 "register_operand" "")
12711 (const_string "*")))])
12713 (define_insn "*lshrsi3_1_one_bit_zext"
12714 [(set (match_operand:DI 0 "register_operand" "=r")
12715 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12716 (match_operand:QI 2 "const1_operand" "")))
12717 (clobber (reg:CC FLAGS_REG))]
12719 && (TARGET_SHIFT1 || optimize_size)
12720 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12722 [(set_attr "type" "ishift")
12723 (set_attr "length" "2")])
12725 (define_insn "*lshrsi3_1"
12726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12728 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12729 (clobber (reg:CC FLAGS_REG))]
12730 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732 shr{l}\t{%2, %0|%0, %2}
12733 shr{l}\t{%b2, %0|%0, %b2}"
12734 [(set_attr "type" "ishift")
12735 (set_attr "mode" "SI")])
12737 (define_insn "*lshrsi3_1_zext"
12738 [(set (match_operand:DI 0 "register_operand" "=r,r")
12740 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12741 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12742 (clobber (reg:CC FLAGS_REG))]
12743 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12745 shr{l}\t{%2, %k0|%k0, %2}
12746 shr{l}\t{%b2, %k0|%k0, %b2}"
12747 [(set_attr "type" "ishift")
12748 (set_attr "mode" "SI")])
12750 ;; This pattern can't accept a variable shift count, since shifts by
12751 ;; zero don't affect the flags. We assume that shifts by constant
12752 ;; zero are optimized away.
12753 (define_insn "*lshrsi3_one_bit_cmp"
12754 [(set (reg FLAGS_REG)
12756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12757 (match_operand:QI 2 "const1_operand" ""))
12759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12761 "(TARGET_SHIFT1 || optimize_size)
12762 && ix86_match_ccmode (insn, CCGOCmode)
12763 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12765 [(set_attr "type" "ishift")
12766 (set (attr "length")
12767 (if_then_else (match_operand:SI 0 "register_operand" "")
12769 (const_string "*")))])
12771 (define_insn "*lshrsi3_one_bit_cconly"
12772 [(set (reg FLAGS_REG)
12774 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12775 (match_operand:QI 2 "const1_operand" ""))
12777 (clobber (match_scratch:SI 0 "=r"))]
12778 "(TARGET_SHIFT1 || optimize_size)
12779 && ix86_match_ccmode (insn, CCGOCmode)
12780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set_attr "length" "2")])
12785 (define_insn "*lshrsi3_cmp_one_bit_zext"
12786 [(set (reg FLAGS_REG)
12788 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12789 (match_operand:QI 2 "const1_operand" ""))
12791 (set (match_operand:DI 0 "register_operand" "=r")
12792 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12794 && (TARGET_SHIFT1 || optimize_size)
12795 && ix86_match_ccmode (insn, CCGOCmode)
12796 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12798 [(set_attr "type" "ishift")
12799 (set_attr "length" "2")])
12801 ;; This pattern can't accept a variable shift count, since shifts by
12802 ;; zero don't affect the flags. We assume that shifts by constant
12803 ;; zero are optimized away.
12804 (define_insn "*lshrsi3_cmp"
12805 [(set (reg FLAGS_REG)
12807 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12811 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12812 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12813 && ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12815 "shr{l}\t{%2, %0|%0, %2}"
12816 [(set_attr "type" "ishift")
12817 (set_attr "mode" "SI")])
12819 (define_insn "*lshrsi3_cconly"
12820 [(set (reg FLAGS_REG)
12822 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12823 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12825 (clobber (match_scratch:SI 0 "=r"))]
12826 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12827 && ix86_match_ccmode (insn, CCGOCmode)
12828 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12829 "shr{l}\t{%2, %0|%0, %2}"
12830 [(set_attr "type" "ishift")
12831 (set_attr "mode" "SI")])
12833 (define_insn "*lshrsi3_cmp_zext"
12834 [(set (reg FLAGS_REG)
12836 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12837 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12839 (set (match_operand:DI 0 "register_operand" "=r")
12840 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12842 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12843 && ix86_match_ccmode (insn, CCGOCmode)
12844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845 "shr{l}\t{%2, %k0|%k0, %2}"
12846 [(set_attr "type" "ishift")
12847 (set_attr "mode" "SI")])
12849 (define_expand "lshrhi3"
12850 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12851 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_HIMODE_MATH"
12855 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12857 (define_insn "*lshrhi3_1_one_bit"
12858 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12859 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12862 "(TARGET_SHIFT1 || optimize_size)
12863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 [(set_attr "type" "ishift")
12866 (set (attr "length")
12867 (if_then_else (match_operand 0 "register_operand" "")
12869 (const_string "*")))])
12871 (define_insn "*lshrhi3_1"
12872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{w}\t{%2, %0|%0, %2}
12879 shr{w}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "HI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags. We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrhi3_one_bit_cmp"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const1_operand" ""))
12892 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894 "(TARGET_SHIFT1 || optimize_size)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898 [(set_attr "type" "ishift")
12899 (set (attr "length")
12900 (if_then_else (match_operand:SI 0 "register_operand" "")
12902 (const_string "*")))])
12904 (define_insn "*lshrhi3_one_bit_cconly"
12905 [(set (reg FLAGS_REG)
12907 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12908 (match_operand:QI 2 "const1_operand" ""))
12910 (clobber (match_scratch:HI 0 "=r"))]
12911 "(TARGET_SHIFT1 || optimize_size)
12912 && ix86_match_ccmode (insn, CCGOCmode)
12913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12915 [(set_attr "type" "ishift")
12916 (set_attr "length" "2")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags. We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*lshrhi3_cmp"
12922 [(set (reg FLAGS_REG)
12924 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12927 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12929 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12930 && ix86_match_ccmode (insn, CCGOCmode)
12931 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932 "shr{w}\t{%2, %0|%0, %2}"
12933 [(set_attr "type" "ishift")
12934 (set_attr "mode" "HI")])
12936 (define_insn "*lshrhi3_cconly"
12937 [(set (reg FLAGS_REG)
12939 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12942 (clobber (match_scratch:HI 0 "=r"))]
12943 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12944 && ix86_match_ccmode (insn, CCGOCmode)
12945 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12946 "shr{w}\t{%2, %0|%0, %2}"
12947 [(set_attr "type" "ishift")
12948 (set_attr "mode" "HI")])
12950 (define_expand "lshrqi3"
12951 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12952 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12953 (match_operand:QI 2 "nonmemory_operand" "")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "TARGET_QIMODE_MATH"
12956 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12958 (define_insn "*lshrqi3_1_one_bit"
12959 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12960 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12961 (match_operand:QI 2 "const1_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "(TARGET_SHIFT1 || optimize_size)
12964 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12966 [(set_attr "type" "ishift")
12967 (set (attr "length")
12968 (if_then_else (match_operand 0 "register_operand" "")
12970 (const_string "*")))])
12972 (define_insn "*lshrqi3_1_one_bit_slp"
12973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12974 (lshiftrt:QI (match_dup 0)
12975 (match_operand:QI 1 "const1_operand" "")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12978 && (TARGET_SHIFT1 || optimize_size)"
12980 [(set_attr "type" "ishift1")
12981 (set (attr "length")
12982 (if_then_else (match_operand 0 "register_operand" "")
12984 (const_string "*")))])
12986 (define_insn "*lshrqi3_1"
12987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12988 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12990 (clobber (reg:CC FLAGS_REG))]
12991 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12993 shr{b}\t{%2, %0|%0, %2}
12994 shr{b}\t{%b2, %0|%0, %b2}"
12995 [(set_attr "type" "ishift")
12996 (set_attr "mode" "QI")])
12998 (define_insn "*lshrqi3_1_slp"
12999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13000 (lshiftrt:QI (match_dup 0)
13001 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13002 (clobber (reg:CC FLAGS_REG))]
13003 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13006 shr{b}\t{%1, %0|%0, %1}
13007 shr{b}\t{%b1, %0|%0, %b1}"
13008 [(set_attr "type" "ishift1")
13009 (set_attr "mode" "QI")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags. We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrqi2_one_bit_cmp"
13015 [(set (reg FLAGS_REG)
13017 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13018 (match_operand:QI 2 "const1_operand" ""))
13020 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13021 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13022 "(TARGET_SHIFT1 || optimize_size)
13023 && ix86_match_ccmode (insn, CCGOCmode)
13024 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13026 [(set_attr "type" "ishift")
13027 (set (attr "length")
13028 (if_then_else (match_operand:SI 0 "register_operand" "")
13030 (const_string "*")))])
13032 (define_insn "*lshrqi2_one_bit_cconly"
13033 [(set (reg FLAGS_REG)
13035 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13036 (match_operand:QI 2 "const1_operand" ""))
13038 (clobber (match_scratch:QI 0 "=q"))]
13039 "(TARGET_SHIFT1 || optimize_size)
13040 && ix86_match_ccmode (insn, CCGOCmode)
13041 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13043 [(set_attr "type" "ishift")
13044 (set_attr "length" "2")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags. We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrqi2_cmp"
13050 [(set (reg FLAGS_REG)
13052 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13055 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13056 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13057 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13060 "shr{b}\t{%2, %0|%0, %2}"
13061 [(set_attr "type" "ishift")
13062 (set_attr "mode" "QI")])
13064 (define_insn "*lshrqi2_cconly"
13065 [(set (reg FLAGS_REG)
13067 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13070 (clobber (match_scratch:QI 0 "=q"))]
13071 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13072 && ix86_match_ccmode (insn, CCGOCmode)
13073 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13074 "shr{b}\t{%2, %0|%0, %2}"
13075 [(set_attr "type" "ishift")
13076 (set_attr "mode" "QI")])
13078 ;; Rotate instructions
13080 (define_expand "rotldi3"
13081 [(set (match_operand:DI 0 "shiftdi_operand" "")
13082 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13083 (match_operand:QI 2 "nonmemory_operand" "")))
13084 (clobber (reg:CC FLAGS_REG))]
13089 ix86_expand_binary_operator (ROTATE, DImode, operands);
13092 if (!const_1_to_31_operand (operands[2], VOIDmode))
13094 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13098 ;; Implement rotation using two double-precision shift instructions
13099 ;; and a scratch register.
13100 (define_insn_and_split "ix86_rotldi3"
13101 [(set (match_operand:DI 0 "register_operand" "=r")
13102 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13104 (clobber (reg:CC FLAGS_REG))
13105 (clobber (match_scratch:SI 3 "=&r"))]
13108 "&& reload_completed"
13109 [(set (match_dup 3) (match_dup 4))
13111 [(set (match_dup 4)
13112 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13113 (lshiftrt:SI (match_dup 5)
13114 (minus:QI (const_int 32) (match_dup 2)))))
13115 (clobber (reg:CC FLAGS_REG))])
13117 [(set (match_dup 5)
13118 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13119 (lshiftrt:SI (match_dup 3)
13120 (minus:QI (const_int 32) (match_dup 2)))))
13121 (clobber (reg:CC FLAGS_REG))])]
13122 "split_di (operands, 1, operands + 4, operands + 5);")
13124 (define_insn "*rotlsi3_1_one_bit_rex64"
13125 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13126 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13127 (match_operand:QI 2 "const1_operand" "")))
13128 (clobber (reg:CC FLAGS_REG))]
13130 && (TARGET_SHIFT1 || optimize_size)
13131 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13133 [(set_attr "type" "rotate")
13134 (set (attr "length")
13135 (if_then_else (match_operand:DI 0 "register_operand" "")
13137 (const_string "*")))])
13139 (define_insn "*rotldi3_1_rex64"
13140 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13141 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13142 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13143 (clobber (reg:CC FLAGS_REG))]
13144 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13146 rol{q}\t{%2, %0|%0, %2}
13147 rol{q}\t{%b2, %0|%0, %b2}"
13148 [(set_attr "type" "rotate")
13149 (set_attr "mode" "DI")])
13151 (define_expand "rotlsi3"
13152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13153 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13154 (match_operand:QI 2 "nonmemory_operand" "")))
13155 (clobber (reg:CC FLAGS_REG))]
13157 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13159 (define_insn "*rotlsi3_1_one_bit"
13160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13161 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162 (match_operand:QI 2 "const1_operand" "")))
13163 (clobber (reg:CC FLAGS_REG))]
13164 "(TARGET_SHIFT1 || optimize_size)
13165 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13167 [(set_attr "type" "rotate")
13168 (set (attr "length")
13169 (if_then_else (match_operand:SI 0 "register_operand" "")
13171 (const_string "*")))])
13173 (define_insn "*rotlsi3_1_one_bit_zext"
13174 [(set (match_operand:DI 0 "register_operand" "=r")
13176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13177 (match_operand:QI 2 "const1_operand" ""))))
13178 (clobber (reg:CC FLAGS_REG))]
13180 && (TARGET_SHIFT1 || optimize_size)
13181 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13183 [(set_attr "type" "rotate")
13184 (set_attr "length" "2")])
13186 (define_insn "*rotlsi3_1"
13187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13188 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190 (clobber (reg:CC FLAGS_REG))]
13191 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13193 rol{l}\t{%2, %0|%0, %2}
13194 rol{l}\t{%b2, %0|%0, %b2}"
13195 [(set_attr "type" "rotate")
13196 (set_attr "mode" "SI")])
13198 (define_insn "*rotlsi3_1_zext"
13199 [(set (match_operand:DI 0 "register_operand" "=r,r")
13201 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13206 rol{l}\t{%2, %k0|%k0, %2}
13207 rol{l}\t{%b2, %k0|%k0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "SI")])
13211 (define_expand "rotlhi3"
13212 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13213 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13214 (match_operand:QI 2 "nonmemory_operand" "")))
13215 (clobber (reg:CC FLAGS_REG))]
13216 "TARGET_HIMODE_MATH"
13217 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13219 (define_insn "*rotlhi3_1_one_bit"
13220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_size)
13225 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set (attr "length")
13229 (if_then_else (match_operand 0 "register_operand" "")
13231 (const_string "*")))])
13233 (define_insn "*rotlhi3_1"
13234 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13235 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13236 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13237 (clobber (reg:CC FLAGS_REG))]
13238 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13240 rol{w}\t{%2, %0|%0, %2}
13241 rol{w}\t{%b2, %0|%0, %b2}"
13242 [(set_attr "type" "rotate")
13243 (set_attr "mode" "HI")])
13246 [(set (match_operand:HI 0 "register_operand" "")
13247 (rotate:HI (match_dup 0) (const_int 8)))
13248 (clobber (reg:CC FLAGS_REG))]
13250 [(parallel [(set (strict_low_part (match_dup 0))
13251 (bswap:HI (match_dup 0)))
13252 (clobber (reg:CC FLAGS_REG))])]
13255 (define_expand "rotlqi3"
13256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13258 (match_operand:QI 2 "nonmemory_operand" "")))
13259 (clobber (reg:CC FLAGS_REG))]
13260 "TARGET_QIMODE_MATH"
13261 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13263 (define_insn "*rotlqi3_1_one_bit_slp"
13264 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13265 (rotate:QI (match_dup 0)
13266 (match_operand:QI 1 "const1_operand" "")))
13267 (clobber (reg:CC FLAGS_REG))]
13268 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13269 && (TARGET_SHIFT1 || optimize_size)"
13271 [(set_attr "type" "rotate1")
13272 (set (attr "length")
13273 (if_then_else (match_operand 0 "register_operand" "")
13275 (const_string "*")))])
13277 (define_insn "*rotlqi3_1_one_bit"
13278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13279 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13280 (match_operand:QI 2 "const1_operand" "")))
13281 (clobber (reg:CC FLAGS_REG))]
13282 "(TARGET_SHIFT1 || optimize_size)
13283 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13285 [(set_attr "type" "rotate")
13286 (set (attr "length")
13287 (if_then_else (match_operand 0 "register_operand" "")
13289 (const_string "*")))])
13291 (define_insn "*rotlqi3_1_slp"
13292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293 (rotate:QI (match_dup 0)
13294 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295 (clobber (reg:CC FLAGS_REG))]
13296 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13297 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 rol{b}\t{%1, %0|%0, %1}
13300 rol{b}\t{%b1, %0|%0, %b1}"
13301 [(set_attr "type" "rotate1")
13302 (set_attr "mode" "QI")])
13304 (define_insn "*rotlqi3_1"
13305 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13306 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13307 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13308 (clobber (reg:CC FLAGS_REG))]
13309 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13311 rol{b}\t{%2, %0|%0, %2}
13312 rol{b}\t{%b2, %0|%0, %b2}"
13313 [(set_attr "type" "rotate")
13314 (set_attr "mode" "QI")])
13316 (define_expand "rotrdi3"
13317 [(set (match_operand:DI 0 "shiftdi_operand" "")
13318 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13319 (match_operand:QI 2 "nonmemory_operand" "")))
13320 (clobber (reg:CC FLAGS_REG))]
13325 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13328 if (!const_1_to_31_operand (operands[2], VOIDmode))
13330 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13334 ;; Implement rotation using two double-precision shift instructions
13335 ;; and a scratch register.
13336 (define_insn_and_split "ix86_rotrdi3"
13337 [(set (match_operand:DI 0 "register_operand" "=r")
13338 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13339 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13340 (clobber (reg:CC FLAGS_REG))
13341 (clobber (match_scratch:SI 3 "=&r"))]
13344 "&& reload_completed"
13345 [(set (match_dup 3) (match_dup 4))
13347 [(set (match_dup 4)
13348 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13349 (ashift:SI (match_dup 5)
13350 (minus:QI (const_int 32) (match_dup 2)))))
13351 (clobber (reg:CC FLAGS_REG))])
13353 [(set (match_dup 5)
13354 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13355 (ashift:SI (match_dup 3)
13356 (minus:QI (const_int 32) (match_dup 2)))))
13357 (clobber (reg:CC FLAGS_REG))])]
13358 "split_di (operands, 1, operands + 4, operands + 5);")
13360 (define_insn "*rotrdi3_1_one_bit_rex64"
13361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13362 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13363 (match_operand:QI 2 "const1_operand" "")))
13364 (clobber (reg:CC FLAGS_REG))]
13366 && (TARGET_SHIFT1 || optimize_size)
13367 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13369 [(set_attr "type" "rotate")
13370 (set (attr "length")
13371 (if_then_else (match_operand:DI 0 "register_operand" "")
13373 (const_string "*")))])
13375 (define_insn "*rotrdi3_1_rex64"
13376 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13377 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13378 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13382 ror{q}\t{%2, %0|%0, %2}
13383 ror{q}\t{%b2, %0|%0, %b2}"
13384 [(set_attr "type" "rotate")
13385 (set_attr "mode" "DI")])
13387 (define_expand "rotrsi3"
13388 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13389 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13390 (match_operand:QI 2 "nonmemory_operand" "")))
13391 (clobber (reg:CC FLAGS_REG))]
13393 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13395 (define_insn "*rotrsi3_1_one_bit"
13396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13397 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13398 (match_operand:QI 2 "const1_operand" "")))
13399 (clobber (reg:CC FLAGS_REG))]
13400 "(TARGET_SHIFT1 || optimize_size)
13401 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13403 [(set_attr "type" "rotate")
13404 (set (attr "length")
13405 (if_then_else (match_operand:SI 0 "register_operand" "")
13407 (const_string "*")))])
13409 (define_insn "*rotrsi3_1_one_bit_zext"
13410 [(set (match_operand:DI 0 "register_operand" "=r")
13412 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13413 (match_operand:QI 2 "const1_operand" ""))))
13414 (clobber (reg:CC FLAGS_REG))]
13416 && (TARGET_SHIFT1 || optimize_size)
13417 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13419 [(set_attr "type" "rotate")
13420 (set (attr "length")
13421 (if_then_else (match_operand:SI 0 "register_operand" "")
13423 (const_string "*")))])
13425 (define_insn "*rotrsi3_1"
13426 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13427 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13428 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13429 (clobber (reg:CC FLAGS_REG))]
13430 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13432 ror{l}\t{%2, %0|%0, %2}
13433 ror{l}\t{%b2, %0|%0, %b2}"
13434 [(set_attr "type" "rotate")
13435 (set_attr "mode" "SI")])
13437 (define_insn "*rotrsi3_1_zext"
13438 [(set (match_operand:DI 0 "register_operand" "=r,r")
13440 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13441 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13442 (clobber (reg:CC FLAGS_REG))]
13443 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13445 ror{l}\t{%2, %k0|%k0, %2}
13446 ror{l}\t{%b2, %k0|%k0, %b2}"
13447 [(set_attr "type" "rotate")
13448 (set_attr "mode" "SI")])
13450 (define_expand "rotrhi3"
13451 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13452 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13453 (match_operand:QI 2 "nonmemory_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "TARGET_HIMODE_MATH"
13456 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13458 (define_insn "*rotrhi3_one_bit"
13459 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13460 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13461 (match_operand:QI 2 "const1_operand" "")))
13462 (clobber (reg:CC FLAGS_REG))]
13463 "(TARGET_SHIFT1 || optimize_size)
13464 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13466 [(set_attr "type" "rotate")
13467 (set (attr "length")
13468 (if_then_else (match_operand 0 "register_operand" "")
13470 (const_string "*")))])
13472 (define_insn "*rotrhi3_1"
13473 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13474 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13475 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13479 ror{w}\t{%2, %0|%0, %2}
13480 ror{w}\t{%b2, %0|%0, %b2}"
13481 [(set_attr "type" "rotate")
13482 (set_attr "mode" "HI")])
13485 [(set (match_operand:HI 0 "register_operand" "")
13486 (rotatert:HI (match_dup 0) (const_int 8)))
13487 (clobber (reg:CC FLAGS_REG))]
13489 [(parallel [(set (strict_low_part (match_dup 0))
13490 (bswap:HI (match_dup 0)))
13491 (clobber (reg:CC FLAGS_REG))])]
13494 (define_expand "rotrqi3"
13495 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13496 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13497 (match_operand:QI 2 "nonmemory_operand" "")))
13498 (clobber (reg:CC FLAGS_REG))]
13499 "TARGET_QIMODE_MATH"
13500 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13502 (define_insn "*rotrqi3_1_one_bit"
13503 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13504 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13505 (match_operand:QI 2 "const1_operand" "")))
13506 (clobber (reg:CC FLAGS_REG))]
13507 "(TARGET_SHIFT1 || optimize_size)
13508 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13510 [(set_attr "type" "rotate")
13511 (set (attr "length")
13512 (if_then_else (match_operand 0 "register_operand" "")
13514 (const_string "*")))])
13516 (define_insn "*rotrqi3_1_one_bit_slp"
13517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518 (rotatert:QI (match_dup 0)
13519 (match_operand:QI 1 "const1_operand" "")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13522 && (TARGET_SHIFT1 || optimize_size)"
13524 [(set_attr "type" "rotate1")
13525 (set (attr "length")
13526 (if_then_else (match_operand 0 "register_operand" "")
13528 (const_string "*")))])
13530 (define_insn "*rotrqi3_1"
13531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13532 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13534 (clobber (reg:CC FLAGS_REG))]
13535 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13537 ror{b}\t{%2, %0|%0, %2}
13538 ror{b}\t{%b2, %0|%0, %b2}"
13539 [(set_attr "type" "rotate")
13540 (set_attr "mode" "QI")])
13542 (define_insn "*rotrqi3_1_slp"
13543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13544 (rotatert:QI (match_dup 0)
13545 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13546 (clobber (reg:CC FLAGS_REG))]
13547 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13550 ror{b}\t{%1, %0|%0, %1}
13551 ror{b}\t{%b1, %0|%0, %b1}"
13552 [(set_attr "type" "rotate1")
13553 (set_attr "mode" "QI")])
13555 ;; Bit set / bit test instructions
13557 (define_expand "extv"
13558 [(set (match_operand:SI 0 "register_operand" "")
13559 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13560 (match_operand:SI 2 "const8_operand" "")
13561 (match_operand:SI 3 "const8_operand" "")))]
13564 /* Handle extractions from %ah et al. */
13565 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13568 /* From mips.md: extract_bit_field doesn't verify that our source
13569 matches the predicate, so check it again here. */
13570 if (! ext_register_operand (operands[1], VOIDmode))
13574 (define_expand "extzv"
13575 [(set (match_operand:SI 0 "register_operand" "")
13576 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13577 (match_operand:SI 2 "const8_operand" "")
13578 (match_operand:SI 3 "const8_operand" "")))]
13581 /* Handle extractions from %ah et al. */
13582 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13585 /* From mips.md: extract_bit_field doesn't verify that our source
13586 matches the predicate, so check it again here. */
13587 if (! ext_register_operand (operands[1], VOIDmode))
13591 (define_expand "insv"
13592 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13593 (match_operand 1 "const8_operand" "")
13594 (match_operand 2 "const8_operand" ""))
13595 (match_operand 3 "register_operand" ""))]
13598 /* Handle insertions to %ah et al. */
13599 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13602 /* From mips.md: insert_bit_field doesn't verify that our source
13603 matches the predicate, so check it again here. */
13604 if (! ext_register_operand (operands[0], VOIDmode))
13608 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13610 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13615 ;; %%% bts, btr, btc, bt.
13616 ;; In general these instructions are *slow* when applied to memory,
13617 ;; since they enforce atomic operation. When applied to registers,
13618 ;; it depends on the cpu implementation. They're never faster than
13619 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13620 ;; no point. But in 64-bit, we can't hold the relevant immediates
13621 ;; within the instruction itself, so operating on bits in the high
13622 ;; 32-bits of a register becomes easier.
13624 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13625 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13626 ;; negdf respectively, so they can never be disabled entirely.
13628 (define_insn "*btsq"
13629 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13631 (match_operand:DI 1 "const_0_to_63_operand" ""))
13633 (clobber (reg:CC FLAGS_REG))]
13634 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13636 [(set_attr "type" "alu1")])
13638 (define_insn "*btrq"
13639 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13641 (match_operand:DI 1 "const_0_to_63_operand" ""))
13643 (clobber (reg:CC FLAGS_REG))]
13644 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13646 [(set_attr "type" "alu1")])
13648 (define_insn "*btcq"
13649 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13651 (match_operand:DI 1 "const_0_to_63_operand" ""))
13652 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13653 (clobber (reg:CC FLAGS_REG))]
13654 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13656 [(set_attr "type" "alu1")])
13658 ;; Allow Nocona to avoid these instructions if a register is available.
13661 [(match_scratch:DI 2 "r")
13662 (parallel [(set (zero_extract:DI
13663 (match_operand:DI 0 "register_operand" "")
13665 (match_operand:DI 1 "const_0_to_63_operand" ""))
13667 (clobber (reg:CC FLAGS_REG))])]
13668 "TARGET_64BIT && !TARGET_USE_BT"
13671 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13674 if (HOST_BITS_PER_WIDE_INT >= 64)
13675 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13676 else if (i < HOST_BITS_PER_WIDE_INT)
13677 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13679 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13681 op1 = immed_double_const (lo, hi, DImode);
13684 emit_move_insn (operands[2], op1);
13688 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13693 [(match_scratch:DI 2 "r")
13694 (parallel [(set (zero_extract:DI
13695 (match_operand:DI 0 "register_operand" "")
13697 (match_operand:DI 1 "const_0_to_63_operand" ""))
13699 (clobber (reg:CC FLAGS_REG))])]
13700 "TARGET_64BIT && !TARGET_USE_BT"
13703 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13706 if (HOST_BITS_PER_WIDE_INT >= 64)
13707 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13708 else if (i < HOST_BITS_PER_WIDE_INT)
13709 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13711 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13713 op1 = immed_double_const (~lo, ~hi, DImode);
13716 emit_move_insn (operands[2], op1);
13720 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13725 [(match_scratch:DI 2 "r")
13726 (parallel [(set (zero_extract:DI
13727 (match_operand:DI 0 "register_operand" "")
13729 (match_operand:DI 1 "const_0_to_63_operand" ""))
13730 (not:DI (zero_extract:DI
13731 (match_dup 0) (const_int 1) (match_dup 1))))
13732 (clobber (reg:CC FLAGS_REG))])]
13733 "TARGET_64BIT && !TARGET_USE_BT"
13736 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13739 if (HOST_BITS_PER_WIDE_INT >= 64)
13740 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13741 else if (i < HOST_BITS_PER_WIDE_INT)
13742 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13744 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13746 op1 = immed_double_const (lo, hi, DImode);
13749 emit_move_insn (operands[2], op1);
13753 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13757 ;; Store-flag instructions.
13759 ;; For all sCOND expanders, also expand the compare or test insn that
13760 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13762 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13763 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13764 ;; way, which can later delete the movzx if only QImode is needed.
13766 (define_expand "seq"
13767 [(set (match_operand:QI 0 "register_operand" "")
13768 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13770 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13772 (define_expand "sne"
13773 [(set (match_operand:QI 0 "register_operand" "")
13774 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13776 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13778 (define_expand "sgt"
13779 [(set (match_operand:QI 0 "register_operand" "")
13780 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13782 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13784 (define_expand "sgtu"
13785 [(set (match_operand:QI 0 "register_operand" "")
13786 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13788 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13790 (define_expand "slt"
13791 [(set (match_operand:QI 0 "register_operand" "")
13792 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13794 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13796 (define_expand "sltu"
13797 [(set (match_operand:QI 0 "register_operand" "")
13798 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13800 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13802 (define_expand "sge"
13803 [(set (match_operand:QI 0 "register_operand" "")
13804 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13806 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13808 (define_expand "sgeu"
13809 [(set (match_operand:QI 0 "register_operand" "")
13810 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13812 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13814 (define_expand "sle"
13815 [(set (match_operand:QI 0 "register_operand" "")
13816 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13818 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13820 (define_expand "sleu"
13821 [(set (match_operand:QI 0 "register_operand" "")
13822 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13824 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13826 (define_expand "sunordered"
13827 [(set (match_operand:QI 0 "register_operand" "")
13828 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13829 "TARGET_80387 || TARGET_SSE"
13830 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13832 (define_expand "sordered"
13833 [(set (match_operand:QI 0 "register_operand" "")
13834 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13836 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13838 (define_expand "suneq"
13839 [(set (match_operand:QI 0 "register_operand" "")
13840 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841 "TARGET_80387 || TARGET_SSE"
13842 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13844 (define_expand "sunge"
13845 [(set (match_operand:QI 0 "register_operand" "")
13846 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13847 "TARGET_80387 || TARGET_SSE"
13848 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13850 (define_expand "sungt"
13851 [(set (match_operand:QI 0 "register_operand" "")
13852 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13853 "TARGET_80387 || TARGET_SSE"
13854 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13856 (define_expand "sunle"
13857 [(set (match_operand:QI 0 "register_operand" "")
13858 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13859 "TARGET_80387 || TARGET_SSE"
13860 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13862 (define_expand "sunlt"
13863 [(set (match_operand:QI 0 "register_operand" "")
13864 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13865 "TARGET_80387 || TARGET_SSE"
13866 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13868 (define_expand "sltgt"
13869 [(set (match_operand:QI 0 "register_operand" "")
13870 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13871 "TARGET_80387 || TARGET_SSE"
13872 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13874 (define_insn "*setcc_1"
13875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13876 (match_operator:QI 1 "ix86_comparison_operator"
13877 [(reg FLAGS_REG) (const_int 0)]))]
13880 [(set_attr "type" "setcc")
13881 (set_attr "mode" "QI")])
13883 (define_insn "*setcc_2"
13884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13885 (match_operator:QI 1 "ix86_comparison_operator"
13886 [(reg FLAGS_REG) (const_int 0)]))]
13889 [(set_attr "type" "setcc")
13890 (set_attr "mode" "QI")])
13892 ;; In general it is not safe to assume too much about CCmode registers,
13893 ;; so simplify-rtx stops when it sees a second one. Under certain
13894 ;; conditions this is safe on x86, so help combine not create
13901 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13902 (ne:QI (match_operator 1 "ix86_comparison_operator"
13903 [(reg FLAGS_REG) (const_int 0)])
13906 [(set (match_dup 0) (match_dup 1))]
13908 PUT_MODE (operands[1], QImode);
13912 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13913 (ne:QI (match_operator 1 "ix86_comparison_operator"
13914 [(reg FLAGS_REG) (const_int 0)])
13917 [(set (match_dup 0) (match_dup 1))]
13919 PUT_MODE (operands[1], QImode);
13923 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13924 (eq:QI (match_operator 1 "ix86_comparison_operator"
13925 [(reg FLAGS_REG) (const_int 0)])
13928 [(set (match_dup 0) (match_dup 1))]
13930 rtx new_op1 = copy_rtx (operands[1]);
13931 operands[1] = new_op1;
13932 PUT_MODE (new_op1, QImode);
13933 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13934 GET_MODE (XEXP (new_op1, 0))));
13936 /* Make sure that (a) the CCmode we have for the flags is strong
13937 enough for the reversed compare or (b) we have a valid FP compare. */
13938 if (! ix86_comparison_operator (new_op1, VOIDmode))
13943 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13944 (eq:QI (match_operator 1 "ix86_comparison_operator"
13945 [(reg FLAGS_REG) (const_int 0)])
13948 [(set (match_dup 0) (match_dup 1))]
13950 rtx new_op1 = copy_rtx (operands[1]);
13951 operands[1] = new_op1;
13952 PUT_MODE (new_op1, QImode);
13953 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13954 GET_MODE (XEXP (new_op1, 0))));
13956 /* Make sure that (a) the CCmode we have for the flags is strong
13957 enough for the reversed compare or (b) we have a valid FP compare. */
13958 if (! ix86_comparison_operator (new_op1, VOIDmode))
13962 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13963 ;; subsequent logical operations are used to imitate conditional moves.
13964 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13967 (define_insn "*sse_setcc<mode>"
13968 [(set (match_operand:MODEF 0 "register_operand" "=x")
13969 (match_operator:MODEF 1 "sse_comparison_operator"
13970 [(match_operand:MODEF 2 "register_operand" "0")
13971 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13972 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13973 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13974 [(set_attr "type" "ssecmp")
13975 (set_attr "mode" "<MODE>")])
13977 (define_insn "*sse5_setcc<mode>"
13978 [(set (match_operand:MODEF 0 "register_operand" "=x")
13979 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13980 [(match_operand:MODEF 2 "register_operand" "x")
13981 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13983 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13984 [(set_attr "type" "sse4arg")
13985 (set_attr "mode" "<MODE>")])
13988 ;; Basic conditional jump instructions.
13989 ;; We ignore the overflow flag for signed branch instructions.
13991 ;; For all bCOND expanders, also expand the compare or test insn that
13992 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13994 (define_expand "beq"
13996 (if_then_else (match_dup 1)
13997 (label_ref (match_operand 0 "" ""))
14000 "ix86_expand_branch (EQ, operands[0]); DONE;")
14002 (define_expand "bne"
14004 (if_then_else (match_dup 1)
14005 (label_ref (match_operand 0 "" ""))
14008 "ix86_expand_branch (NE, operands[0]); DONE;")
14010 (define_expand "bgt"
14012 (if_then_else (match_dup 1)
14013 (label_ref (match_operand 0 "" ""))
14016 "ix86_expand_branch (GT, operands[0]); DONE;")
14018 (define_expand "bgtu"
14020 (if_then_else (match_dup 1)
14021 (label_ref (match_operand 0 "" ""))
14024 "ix86_expand_branch (GTU, operands[0]); DONE;")
14026 (define_expand "blt"
14028 (if_then_else (match_dup 1)
14029 (label_ref (match_operand 0 "" ""))
14032 "ix86_expand_branch (LT, operands[0]); DONE;")
14034 (define_expand "bltu"
14036 (if_then_else (match_dup 1)
14037 (label_ref (match_operand 0 "" ""))
14040 "ix86_expand_branch (LTU, operands[0]); DONE;")
14042 (define_expand "bge"
14044 (if_then_else (match_dup 1)
14045 (label_ref (match_operand 0 "" ""))
14048 "ix86_expand_branch (GE, operands[0]); DONE;")
14050 (define_expand "bgeu"
14052 (if_then_else (match_dup 1)
14053 (label_ref (match_operand 0 "" ""))
14056 "ix86_expand_branch (GEU, operands[0]); DONE;")
14058 (define_expand "ble"
14060 (if_then_else (match_dup 1)
14061 (label_ref (match_operand 0 "" ""))
14064 "ix86_expand_branch (LE, operands[0]); DONE;")
14066 (define_expand "bleu"
14068 (if_then_else (match_dup 1)
14069 (label_ref (match_operand 0 "" ""))
14072 "ix86_expand_branch (LEU, operands[0]); DONE;")
14074 (define_expand "bunordered"
14076 (if_then_else (match_dup 1)
14077 (label_ref (match_operand 0 "" ""))
14079 "TARGET_80387 || TARGET_SSE_MATH"
14080 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14082 (define_expand "bordered"
14084 (if_then_else (match_dup 1)
14085 (label_ref (match_operand 0 "" ""))
14087 "TARGET_80387 || TARGET_SSE_MATH"
14088 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14090 (define_expand "buneq"
14092 (if_then_else (match_dup 1)
14093 (label_ref (match_operand 0 "" ""))
14095 "TARGET_80387 || TARGET_SSE_MATH"
14096 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14098 (define_expand "bunge"
14100 (if_then_else (match_dup 1)
14101 (label_ref (match_operand 0 "" ""))
14103 "TARGET_80387 || TARGET_SSE_MATH"
14104 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14106 (define_expand "bungt"
14108 (if_then_else (match_dup 1)
14109 (label_ref (match_operand 0 "" ""))
14111 "TARGET_80387 || TARGET_SSE_MATH"
14112 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14114 (define_expand "bunle"
14116 (if_then_else (match_dup 1)
14117 (label_ref (match_operand 0 "" ""))
14119 "TARGET_80387 || TARGET_SSE_MATH"
14120 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14122 (define_expand "bunlt"
14124 (if_then_else (match_dup 1)
14125 (label_ref (match_operand 0 "" ""))
14127 "TARGET_80387 || TARGET_SSE_MATH"
14128 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14130 (define_expand "bltgt"
14132 (if_then_else (match_dup 1)
14133 (label_ref (match_operand 0 "" ""))
14135 "TARGET_80387 || TARGET_SSE_MATH"
14136 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14138 (define_insn "*jcc_1"
14140 (if_then_else (match_operator 1 "ix86_comparison_operator"
14141 [(reg FLAGS_REG) (const_int 0)])
14142 (label_ref (match_operand 0 "" ""))
14146 [(set_attr "type" "ibr")
14147 (set_attr "modrm" "0")
14148 (set (attr "length")
14149 (if_then_else (and (ge (minus (match_dup 0) (pc))
14151 (lt (minus (match_dup 0) (pc))
14156 (define_insn "*jcc_2"
14158 (if_then_else (match_operator 1 "ix86_comparison_operator"
14159 [(reg FLAGS_REG) (const_int 0)])
14161 (label_ref (match_operand 0 "" ""))))]
14164 [(set_attr "type" "ibr")
14165 (set_attr "modrm" "0")
14166 (set (attr "length")
14167 (if_then_else (and (ge (minus (match_dup 0) (pc))
14169 (lt (minus (match_dup 0) (pc))
14174 ;; In general it is not safe to assume too much about CCmode registers,
14175 ;; so simplify-rtx stops when it sees a second one. Under certain
14176 ;; conditions this is safe on x86, so help combine not create
14184 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14185 [(reg FLAGS_REG) (const_int 0)])
14187 (label_ref (match_operand 1 "" ""))
14191 (if_then_else (match_dup 0)
14192 (label_ref (match_dup 1))
14195 PUT_MODE (operands[0], VOIDmode);
14200 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14201 [(reg FLAGS_REG) (const_int 0)])
14203 (label_ref (match_operand 1 "" ""))
14207 (if_then_else (match_dup 0)
14208 (label_ref (match_dup 1))
14211 rtx new_op0 = copy_rtx (operands[0]);
14212 operands[0] = new_op0;
14213 PUT_MODE (new_op0, VOIDmode);
14214 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14215 GET_MODE (XEXP (new_op0, 0))));
14217 /* Make sure that (a) the CCmode we have for the flags is strong
14218 enough for the reversed compare or (b) we have a valid FP compare. */
14219 if (! ix86_comparison_operator (new_op0, VOIDmode))
14223 ;; Define combination compare-and-branch fp compare instructions to use
14224 ;; during early optimization. Splitting the operation apart early makes
14225 ;; for bad code when we want to reverse the operation.
14227 (define_insn "*fp_jcc_1_mixed"
14229 (if_then_else (match_operator 0 "comparison_operator"
14230 [(match_operand 1 "register_operand" "f,x")
14231 (match_operand 2 "nonimmediate_operand" "f,xm")])
14232 (label_ref (match_operand 3 "" ""))
14234 (clobber (reg:CCFP FPSR_REG))
14235 (clobber (reg:CCFP FLAGS_REG))]
14236 "TARGET_MIX_SSE_I387
14237 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14238 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14239 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14242 (define_insn "*fp_jcc_1_sse"
14244 (if_then_else (match_operator 0 "comparison_operator"
14245 [(match_operand 1 "register_operand" "x")
14246 (match_operand 2 "nonimmediate_operand" "xm")])
14247 (label_ref (match_operand 3 "" ""))
14249 (clobber (reg:CCFP FPSR_REG))
14250 (clobber (reg:CCFP FLAGS_REG))]
14252 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14253 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14254 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14257 (define_insn "*fp_jcc_1_387"
14259 (if_then_else (match_operator 0 "comparison_operator"
14260 [(match_operand 1 "register_operand" "f")
14261 (match_operand 2 "register_operand" "f")])
14262 (label_ref (match_operand 3 "" ""))
14264 (clobber (reg:CCFP FPSR_REG))
14265 (clobber (reg:CCFP FLAGS_REG))]
14266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14268 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14272 (define_insn "*fp_jcc_2_mixed"
14274 (if_then_else (match_operator 0 "comparison_operator"
14275 [(match_operand 1 "register_operand" "f,x")
14276 (match_operand 2 "nonimmediate_operand" "f,xm")])
14278 (label_ref (match_operand 3 "" ""))))
14279 (clobber (reg:CCFP FPSR_REG))
14280 (clobber (reg:CCFP FLAGS_REG))]
14281 "TARGET_MIX_SSE_I387
14282 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14283 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14284 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14287 (define_insn "*fp_jcc_2_sse"
14289 (if_then_else (match_operator 0 "comparison_operator"
14290 [(match_operand 1 "register_operand" "x")
14291 (match_operand 2 "nonimmediate_operand" "xm")])
14293 (label_ref (match_operand 3 "" ""))))
14294 (clobber (reg:CCFP FPSR_REG))
14295 (clobber (reg:CCFP FLAGS_REG))]
14297 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14298 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14299 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14302 (define_insn "*fp_jcc_2_387"
14304 (if_then_else (match_operator 0 "comparison_operator"
14305 [(match_operand 1 "register_operand" "f")
14306 (match_operand 2 "register_operand" "f")])
14308 (label_ref (match_operand 3 "" ""))))
14309 (clobber (reg:CCFP FPSR_REG))
14310 (clobber (reg:CCFP FLAGS_REG))]
14311 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14314 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14317 (define_insn "*fp_jcc_3_387"
14319 (if_then_else (match_operator 0 "comparison_operator"
14320 [(match_operand 1 "register_operand" "f")
14321 (match_operand 2 "nonimmediate_operand" "fm")])
14322 (label_ref (match_operand 3 "" ""))
14324 (clobber (reg:CCFP FPSR_REG))
14325 (clobber (reg:CCFP FLAGS_REG))
14326 (clobber (match_scratch:HI 4 "=a"))]
14328 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14329 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14330 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14331 && SELECT_CC_MODE (GET_CODE (operands[0]),
14332 operands[1], operands[2]) == CCFPmode
14333 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14336 (define_insn "*fp_jcc_4_387"
14338 (if_then_else (match_operator 0 "comparison_operator"
14339 [(match_operand 1 "register_operand" "f")
14340 (match_operand 2 "nonimmediate_operand" "fm")])
14342 (label_ref (match_operand 3 "" ""))))
14343 (clobber (reg:CCFP FPSR_REG))
14344 (clobber (reg:CCFP FLAGS_REG))
14345 (clobber (match_scratch:HI 4 "=a"))]
14347 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14348 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14349 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14350 && SELECT_CC_MODE (GET_CODE (operands[0]),
14351 operands[1], operands[2]) == CCFPmode
14352 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14355 (define_insn "*fp_jcc_5_387"
14357 (if_then_else (match_operator 0 "comparison_operator"
14358 [(match_operand 1 "register_operand" "f")
14359 (match_operand 2 "register_operand" "f")])
14360 (label_ref (match_operand 3 "" ""))
14362 (clobber (reg:CCFP FPSR_REG))
14363 (clobber (reg:CCFP FLAGS_REG))
14364 (clobber (match_scratch:HI 4 "=a"))]
14365 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14366 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14367 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14370 (define_insn "*fp_jcc_6_387"
14372 (if_then_else (match_operator 0 "comparison_operator"
14373 [(match_operand 1 "register_operand" "f")
14374 (match_operand 2 "register_operand" "f")])
14376 (label_ref (match_operand 3 "" ""))))
14377 (clobber (reg:CCFP FPSR_REG))
14378 (clobber (reg:CCFP FLAGS_REG))
14379 (clobber (match_scratch:HI 4 "=a"))]
14380 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14381 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14382 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14385 (define_insn "*fp_jcc_7_387"
14387 (if_then_else (match_operator 0 "comparison_operator"
14388 [(match_operand 1 "register_operand" "f")
14389 (match_operand 2 "const0_operand" "X")])
14390 (label_ref (match_operand 3 "" ""))
14392 (clobber (reg:CCFP FPSR_REG))
14393 (clobber (reg:CCFP FLAGS_REG))
14394 (clobber (match_scratch:HI 4 "=a"))]
14395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14396 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14397 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14398 && SELECT_CC_MODE (GET_CODE (operands[0]),
14399 operands[1], operands[2]) == CCFPmode
14400 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14403 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14404 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14405 ;; with a precedence over other operators and is always put in the first
14406 ;; place. Swap condition and operands to match ficom instruction.
14408 (define_insn "*fp_jcc_8<mode>_387"
14410 (if_then_else (match_operator 0 "comparison_operator"
14411 [(match_operator 1 "float_operator"
14412 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14413 (match_operand 3 "register_operand" "f,f")])
14414 (label_ref (match_operand 4 "" ""))
14416 (clobber (reg:CCFP FPSR_REG))
14417 (clobber (reg:CCFP FLAGS_REG))
14418 (clobber (match_scratch:HI 5 "=a,a"))]
14419 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14420 && TARGET_USE_<MODE>MODE_FIOP
14421 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14422 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14423 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14424 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14429 (if_then_else (match_operator 0 "comparison_operator"
14430 [(match_operand 1 "register_operand" "")
14431 (match_operand 2 "nonimmediate_operand" "")])
14432 (match_operand 3 "" "")
14433 (match_operand 4 "" "")))
14434 (clobber (reg:CCFP FPSR_REG))
14435 (clobber (reg:CCFP FLAGS_REG))]
14439 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14440 operands[3], operands[4], NULL_RTX, NULL_RTX);
14446 (if_then_else (match_operator 0 "comparison_operator"
14447 [(match_operand 1 "register_operand" "")
14448 (match_operand 2 "general_operand" "")])
14449 (match_operand 3 "" "")
14450 (match_operand 4 "" "")))
14451 (clobber (reg:CCFP FPSR_REG))
14452 (clobber (reg:CCFP FLAGS_REG))
14453 (clobber (match_scratch:HI 5 "=a"))]
14457 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14458 operands[3], operands[4], operands[5], NULL_RTX);
14464 (if_then_else (match_operator 0 "comparison_operator"
14465 [(match_operator 1 "float_operator"
14466 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14467 (match_operand 3 "register_operand" "")])
14468 (match_operand 4 "" "")
14469 (match_operand 5 "" "")))
14470 (clobber (reg:CCFP FPSR_REG))
14471 (clobber (reg:CCFP FLAGS_REG))
14472 (clobber (match_scratch:HI 6 "=a"))]
14476 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14477 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14478 operands[3], operands[7],
14479 operands[4], operands[5], operands[6], NULL_RTX);
14483 ;; %%% Kill this when reload knows how to do it.
14486 (if_then_else (match_operator 0 "comparison_operator"
14487 [(match_operator 1 "float_operator"
14488 [(match_operand:X87MODEI12 2 "register_operand" "")])
14489 (match_operand 3 "register_operand" "")])
14490 (match_operand 4 "" "")
14491 (match_operand 5 "" "")))
14492 (clobber (reg:CCFP FPSR_REG))
14493 (clobber (reg:CCFP FLAGS_REG))
14494 (clobber (match_scratch:HI 6 "=a"))]
14498 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14499 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14500 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14501 operands[3], operands[7],
14502 operands[4], operands[5], operands[6], operands[2]);
14506 ;; Unconditional and other jump instructions
14508 (define_insn "jump"
14510 (label_ref (match_operand 0 "" "")))]
14513 [(set_attr "type" "ibr")
14514 (set (attr "length")
14515 (if_then_else (and (ge (minus (match_dup 0) (pc))
14517 (lt (minus (match_dup 0) (pc))
14521 (set_attr "modrm" "0")])
14523 (define_expand "indirect_jump"
14524 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14528 (define_insn "*indirect_jump"
14529 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14532 [(set_attr "type" "ibr")
14533 (set_attr "length_immediate" "0")])
14535 (define_insn "*indirect_jump_rtx64"
14536 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14539 [(set_attr "type" "ibr")
14540 (set_attr "length_immediate" "0")])
14542 (define_expand "tablejump"
14543 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14544 (use (label_ref (match_operand 1 "" "")))])]
14547 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14548 relative. Convert the relative address to an absolute address. */
14552 enum rtx_code code;
14554 /* We can't use @GOTOFF for text labels on VxWorks;
14555 see gotoff_operand. */
14556 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14560 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14562 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14566 op1 = pic_offset_table_rtx;
14571 op0 = pic_offset_table_rtx;
14575 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14580 (define_insn "*tablejump_1"
14581 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14582 (use (label_ref (match_operand 1 "" "")))]
14585 [(set_attr "type" "ibr")
14586 (set_attr "length_immediate" "0")])
14588 (define_insn "*tablejump_1_rtx64"
14589 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14590 (use (label_ref (match_operand 1 "" "")))]
14593 [(set_attr "type" "ibr")
14594 (set_attr "length_immediate" "0")])
14596 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14599 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14600 (set (match_operand:QI 1 "register_operand" "")
14601 (match_operator:QI 2 "ix86_comparison_operator"
14602 [(reg FLAGS_REG) (const_int 0)]))
14603 (set (match_operand 3 "q_regs_operand" "")
14604 (zero_extend (match_dup 1)))]
14605 "(peep2_reg_dead_p (3, operands[1])
14606 || operands_match_p (operands[1], operands[3]))
14607 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14608 [(set (match_dup 4) (match_dup 0))
14609 (set (strict_low_part (match_dup 5))
14612 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14613 operands[5] = gen_lowpart (QImode, operands[3]);
14614 ix86_expand_clear (operands[3]);
14617 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14620 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14621 (set (match_operand:QI 1 "register_operand" "")
14622 (match_operator:QI 2 "ix86_comparison_operator"
14623 [(reg FLAGS_REG) (const_int 0)]))
14624 (parallel [(set (match_operand 3 "q_regs_operand" "")
14625 (zero_extend (match_dup 1)))
14626 (clobber (reg:CC FLAGS_REG))])]
14627 "(peep2_reg_dead_p (3, operands[1])
14628 || operands_match_p (operands[1], operands[3]))
14629 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14630 [(set (match_dup 4) (match_dup 0))
14631 (set (strict_low_part (match_dup 5))
14634 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14635 operands[5] = gen_lowpart (QImode, operands[3]);
14636 ix86_expand_clear (operands[3]);
14639 ;; Call instructions.
14641 ;; The predicates normally associated with named expanders are not properly
14642 ;; checked for calls. This is a bug in the generic code, but it isn't that
14643 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14645 ;; Call subroutine returning no value.
14647 (define_expand "call_pop"
14648 [(parallel [(call (match_operand:QI 0 "" "")
14649 (match_operand:SI 1 "" ""))
14650 (set (reg:SI SP_REG)
14651 (plus:SI (reg:SI SP_REG)
14652 (match_operand:SI 3 "" "")))])]
14655 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14659 (define_insn "*call_pop_0"
14660 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14661 (match_operand:SI 1 "" ""))
14662 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14663 (match_operand:SI 2 "immediate_operand" "")))]
14666 if (SIBLING_CALL_P (insn))
14669 return "call\t%P0";
14671 [(set_attr "type" "call")])
14673 (define_insn "*call_pop_1"
14674 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14675 (match_operand:SI 1 "" ""))
14676 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14677 (match_operand:SI 2 "immediate_operand" "i")))]
14680 if (constant_call_address_operand (operands[0], Pmode))
14682 if (SIBLING_CALL_P (insn))
14685 return "call\t%P0";
14687 if (SIBLING_CALL_P (insn))
14690 return "call\t%A0";
14692 [(set_attr "type" "call")])
14694 (define_expand "call"
14695 [(call (match_operand:QI 0 "" "")
14696 (match_operand 1 "" ""))
14697 (use (match_operand 2 "" ""))]
14700 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14704 (define_expand "sibcall"
14705 [(call (match_operand:QI 0 "" "")
14706 (match_operand 1 "" ""))
14707 (use (match_operand 2 "" ""))]
14710 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14714 (define_insn "*call_0"
14715 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14716 (match_operand 1 "" ""))]
14719 if (SIBLING_CALL_P (insn))
14722 return "call\t%P0";
14724 [(set_attr "type" "call")])
14726 (define_insn "*call_1"
14727 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14728 (match_operand 1 "" ""))]
14729 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14731 if (constant_call_address_operand (operands[0], Pmode))
14732 return "call\t%P0";
14733 return "call\t%A0";
14735 [(set_attr "type" "call")])
14737 (define_insn "*sibcall_1"
14738 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14739 (match_operand 1 "" ""))]
14740 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14742 if (constant_call_address_operand (operands[0], Pmode))
14746 [(set_attr "type" "call")])
14748 (define_insn "*call_1_rex64"
14749 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14750 (match_operand 1 "" ""))]
14751 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14752 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14754 if (constant_call_address_operand (operands[0], Pmode))
14755 return "call\t%P0";
14756 return "call\t%A0";
14758 [(set_attr "type" "call")])
14760 (define_insn "*call_1_rex64_large"
14761 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14762 (match_operand 1 "" ""))]
14763 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14765 [(set_attr "type" "call")])
14767 (define_insn "*sibcall_1_rex64"
14768 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14769 (match_operand 1 "" ""))]
14770 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14772 [(set_attr "type" "call")])
14774 (define_insn "*sibcall_1_rex64_v"
14775 [(call (mem:QI (reg:DI R11_REG))
14776 (match_operand 0 "" ""))]
14777 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14779 [(set_attr "type" "call")])
14782 ;; Call subroutine, returning value in operand 0
14784 (define_expand "call_value_pop"
14785 [(parallel [(set (match_operand 0 "" "")
14786 (call (match_operand:QI 1 "" "")
14787 (match_operand:SI 2 "" "")))
14788 (set (reg:SI SP_REG)
14789 (plus:SI (reg:SI SP_REG)
14790 (match_operand:SI 4 "" "")))])]
14793 ix86_expand_call (operands[0], operands[1], operands[2],
14794 operands[3], operands[4], 0);
14798 (define_expand "call_value"
14799 [(set (match_operand 0 "" "")
14800 (call (match_operand:QI 1 "" "")
14801 (match_operand:SI 2 "" "")))
14802 (use (match_operand:SI 3 "" ""))]
14803 ;; Operand 2 not used on the i386.
14806 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14810 (define_expand "sibcall_value"
14811 [(set (match_operand 0 "" "")
14812 (call (match_operand:QI 1 "" "")
14813 (match_operand:SI 2 "" "")))
14814 (use (match_operand:SI 3 "" ""))]
14815 ;; Operand 2 not used on the i386.
14818 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14822 ;; Call subroutine returning any type.
14824 (define_expand "untyped_call"
14825 [(parallel [(call (match_operand 0 "" "")
14827 (match_operand 1 "" "")
14828 (match_operand 2 "" "")])]
14833 /* In order to give reg-stack an easier job in validating two
14834 coprocessor registers as containing a possible return value,
14835 simply pretend the untyped call returns a complex long double
14838 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14839 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14840 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14843 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14845 rtx set = XVECEXP (operands[2], 0, i);
14846 emit_move_insn (SET_DEST (set), SET_SRC (set));
14849 /* The optimizer does not know that the call sets the function value
14850 registers we stored in the result block. We avoid problems by
14851 claiming that all hard registers are used and clobbered at this
14853 emit_insn (gen_blockage ());
14858 ;; Prologue and epilogue instructions
14860 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14861 ;; all of memory. This blocks insns from being moved across this point.
14863 (define_insn "blockage"
14864 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14867 [(set_attr "length" "0")])
14869 ;; As USE insns aren't meaningful after reload, this is used instead
14870 ;; to prevent deleting instructions setting registers for PIC code
14871 (define_insn "prologue_use"
14872 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14875 [(set_attr "length" "0")])
14877 ;; Insn emitted into the body of a function to return from a function.
14878 ;; This is only done if the function's epilogue is known to be simple.
14879 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14881 (define_expand "return"
14883 "ix86_can_use_return_insn_p ()"
14885 if (current_function_pops_args)
14887 rtx popc = GEN_INT (current_function_pops_args);
14888 emit_jump_insn (gen_return_pop_internal (popc));
14893 (define_insn "return_internal"
14897 [(set_attr "length" "1")
14898 (set_attr "length_immediate" "0")
14899 (set_attr "modrm" "0")])
14901 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14902 ;; instruction Athlon and K8 have.
14904 (define_insn "return_internal_long"
14906 (unspec [(const_int 0)] UNSPEC_REP)]
14909 [(set_attr "length" "1")
14910 (set_attr "length_immediate" "0")
14911 (set_attr "prefix_rep" "1")
14912 (set_attr "modrm" "0")])
14914 (define_insn "return_pop_internal"
14916 (use (match_operand:SI 0 "const_int_operand" ""))]
14919 [(set_attr "length" "3")
14920 (set_attr "length_immediate" "2")
14921 (set_attr "modrm" "0")])
14923 (define_insn "return_indirect_internal"
14925 (use (match_operand:SI 0 "register_operand" "r"))]
14928 [(set_attr "type" "ibr")
14929 (set_attr "length_immediate" "0")])
14935 [(set_attr "length" "1")
14936 (set_attr "length_immediate" "0")
14937 (set_attr "modrm" "0")])
14939 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14940 ;; branch prediction penalty for the third jump in a 16-byte
14943 (define_insn "align"
14944 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14947 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14948 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14950 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14951 The align insn is used to avoid 3 jump instructions in the row to improve
14952 branch prediction and the benefits hardly outweigh the cost of extra 8
14953 nops on the average inserted by full alignment pseudo operation. */
14957 [(set_attr "length" "16")])
14959 (define_expand "prologue"
14962 "ix86_expand_prologue (); DONE;")
14964 (define_insn "set_got"
14965 [(set (match_operand:SI 0 "register_operand" "=r")
14966 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14967 (clobber (reg:CC FLAGS_REG))]
14969 { return output_set_got (operands[0], NULL_RTX); }
14970 [(set_attr "type" "multi")
14971 (set_attr "length" "12")])
14973 (define_insn "set_got_labelled"
14974 [(set (match_operand:SI 0 "register_operand" "=r")
14975 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14977 (clobber (reg:CC FLAGS_REG))]
14979 { return output_set_got (operands[0], operands[1]); }
14980 [(set_attr "type" "multi")
14981 (set_attr "length" "12")])
14983 (define_insn "set_got_rex64"
14984 [(set (match_operand:DI 0 "register_operand" "=r")
14985 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14987 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14988 [(set_attr "type" "lea")
14989 (set_attr "length" "6")])
14991 (define_insn "set_rip_rex64"
14992 [(set (match_operand:DI 0 "register_operand" "=r")
14993 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14995 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14996 [(set_attr "type" "lea")
14997 (set_attr "length" "6")])
14999 (define_insn "set_got_offset_rex64"
15000 [(set (match_operand:DI 0 "register_operand" "=r")
15001 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15003 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15004 [(set_attr "type" "imov")
15005 (set_attr "length" "11")])
15007 (define_expand "epilogue"
15010 "ix86_expand_epilogue (1); DONE;")
15012 (define_expand "sibcall_epilogue"
15015 "ix86_expand_epilogue (0); DONE;")
15017 (define_expand "eh_return"
15018 [(use (match_operand 0 "register_operand" ""))]
15021 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15023 /* Tricky bit: we write the address of the handler to which we will
15024 be returning into someone else's stack frame, one word below the
15025 stack address we wish to restore. */
15026 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15027 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15028 tmp = gen_rtx_MEM (Pmode, tmp);
15029 emit_move_insn (tmp, ra);
15031 if (Pmode == SImode)
15032 emit_jump_insn (gen_eh_return_si (sa));
15034 emit_jump_insn (gen_eh_return_di (sa));
15039 (define_insn_and_split "eh_return_si"
15041 (unspec [(match_operand:SI 0 "register_operand" "c")]
15042 UNSPEC_EH_RETURN))]
15047 "ix86_expand_epilogue (2); DONE;")
15049 (define_insn_and_split "eh_return_di"
15051 (unspec [(match_operand:DI 0 "register_operand" "c")]
15052 UNSPEC_EH_RETURN))]
15057 "ix86_expand_epilogue (2); DONE;")
15059 (define_insn "leave"
15060 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15061 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15062 (clobber (mem:BLK (scratch)))]
15065 [(set_attr "type" "leave")])
15067 (define_insn "leave_rex64"
15068 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15069 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15070 (clobber (mem:BLK (scratch)))]
15073 [(set_attr "type" "leave")])
15075 (define_expand "ffssi2"
15077 [(set (match_operand:SI 0 "register_operand" "")
15078 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15079 (clobber (match_scratch:SI 2 ""))
15080 (clobber (reg:CC FLAGS_REG))])]
15085 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15090 (define_expand "ffs_cmove"
15091 [(set (match_dup 2) (const_int -1))
15092 (parallel [(set (reg:CCZ FLAGS_REG)
15093 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15095 (set (match_operand:SI 0 "nonimmediate_operand" "")
15096 (ctz:SI (match_dup 1)))])
15097 (set (match_dup 0) (if_then_else:SI
15098 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15101 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15102 (clobber (reg:CC FLAGS_REG))])]
15104 "operands[2] = gen_reg_rtx (SImode);")
15106 (define_insn_and_split "*ffs_no_cmove"
15107 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15108 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15109 (clobber (match_scratch:SI 2 "=&q"))
15110 (clobber (reg:CC FLAGS_REG))]
15113 "&& reload_completed"
15114 [(parallel [(set (reg:CCZ FLAGS_REG)
15115 (compare:CCZ (match_dup 1) (const_int 0)))
15116 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15117 (set (strict_low_part (match_dup 3))
15118 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15119 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15120 (clobber (reg:CC FLAGS_REG))])
15121 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15122 (clobber (reg:CC FLAGS_REG))])
15123 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15124 (clobber (reg:CC FLAGS_REG))])]
15126 operands[3] = gen_lowpart (QImode, operands[2]);
15127 ix86_expand_clear (operands[2]);
15130 (define_insn "*ffssi_1"
15131 [(set (reg:CCZ FLAGS_REG)
15132 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15134 (set (match_operand:SI 0 "register_operand" "=r")
15135 (ctz:SI (match_dup 1)))]
15137 "bsf{l}\t{%1, %0|%0, %1}"
15138 [(set_attr "prefix_0f" "1")])
15140 (define_expand "ffsdi2"
15141 [(set (match_dup 2) (const_int -1))
15142 (parallel [(set (reg:CCZ FLAGS_REG)
15143 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15145 (set (match_operand:DI 0 "nonimmediate_operand" "")
15146 (ctz:DI (match_dup 1)))])
15147 (set (match_dup 0) (if_then_else:DI
15148 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15151 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15152 (clobber (reg:CC FLAGS_REG))])]
15154 "operands[2] = gen_reg_rtx (DImode);")
15156 (define_insn "*ffsdi_1"
15157 [(set (reg:CCZ FLAGS_REG)
15158 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15160 (set (match_operand:DI 0 "register_operand" "=r")
15161 (ctz:DI (match_dup 1)))]
15163 "bsf{q}\t{%1, %0|%0, %1}"
15164 [(set_attr "prefix_0f" "1")])
15166 (define_insn "ctzsi2"
15167 [(set (match_operand:SI 0 "register_operand" "=r")
15168 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15169 (clobber (reg:CC FLAGS_REG))]
15171 "bsf{l}\t{%1, %0|%0, %1}"
15172 [(set_attr "prefix_0f" "1")])
15174 (define_insn "ctzdi2"
15175 [(set (match_operand:DI 0 "register_operand" "=r")
15176 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15177 (clobber (reg:CC FLAGS_REG))]
15179 "bsf{q}\t{%1, %0|%0, %1}"
15180 [(set_attr "prefix_0f" "1")])
15182 (define_expand "clzsi2"
15184 [(set (match_operand:SI 0 "register_operand" "")
15185 (minus:SI (const_int 31)
15186 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15187 (clobber (reg:CC FLAGS_REG))])
15189 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15190 (clobber (reg:CC FLAGS_REG))])]
15195 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15200 (define_insn "clzsi2_abm"
15201 [(set (match_operand:SI 0 "register_operand" "=r")
15202 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15203 (clobber (reg:CC FLAGS_REG))]
15205 "lzcnt{l}\t{%1, %0|%0, %1}"
15206 [(set_attr "prefix_rep" "1")
15207 (set_attr "type" "bitmanip")
15208 (set_attr "mode" "SI")])
15210 (define_insn "*bsr"
15211 [(set (match_operand:SI 0 "register_operand" "=r")
15212 (minus:SI (const_int 31)
15213 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15214 (clobber (reg:CC FLAGS_REG))]
15216 "bsr{l}\t{%1, %0|%0, %1}"
15217 [(set_attr "prefix_0f" "1")
15218 (set_attr "mode" "SI")])
15220 (define_insn "popcountsi2"
15221 [(set (match_operand:SI 0 "register_operand" "=r")
15222 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15223 (clobber (reg:CC FLAGS_REG))]
15225 "popcnt{l}\t{%1, %0|%0, %1}"
15226 [(set_attr "prefix_rep" "1")
15227 (set_attr "type" "bitmanip")
15228 (set_attr "mode" "SI")])
15230 (define_insn "*popcountsi2_cmp"
15231 [(set (reg FLAGS_REG)
15233 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15235 (set (match_operand:SI 0 "register_operand" "=r")
15236 (popcount:SI (match_dup 1)))]
15237 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15238 "popcnt{l}\t{%1, %0|%0, %1}"
15239 [(set_attr "prefix_rep" "1")
15240 (set_attr "type" "bitmanip")
15241 (set_attr "mode" "SI")])
15243 (define_insn "*popcountsi2_cmp_zext"
15244 [(set (reg FLAGS_REG)
15246 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15248 (set (match_operand:DI 0 "register_operand" "=r")
15249 (zero_extend:DI(popcount:SI (match_dup 1))))]
15250 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15251 "popcnt{l}\t{%1, %0|%0, %1}"
15252 [(set_attr "prefix_rep" "1")
15253 (set_attr "type" "bitmanip")
15254 (set_attr "mode" "SI")])
15256 (define_expand "bswapsi2"
15257 [(set (match_operand:SI 0 "register_operand" "")
15258 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15263 rtx x = operands[0];
15265 emit_move_insn (x, operands[1]);
15266 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15267 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15268 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15273 (define_insn "*bswapsi_1"
15274 [(set (match_operand:SI 0 "register_operand" "=r")
15275 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15278 [(set_attr "prefix_0f" "1")
15279 (set_attr "length" "2")])
15281 (define_insn "*bswaphi_lowpart_1"
15282 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15283 (bswap:HI (match_dup 0)))
15284 (clobber (reg:CC FLAGS_REG))]
15285 "TARGET_USE_XCHGB || optimize_size"
15287 xchg{b}\t{%h0, %b0|%b0, %h0}
15288 rol{w}\t{$8, %0|%0, 8}"
15289 [(set_attr "length" "2,4")
15290 (set_attr "mode" "QI,HI")])
15292 (define_insn "bswaphi_lowpart"
15293 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15294 (bswap:HI (match_dup 0)))
15295 (clobber (reg:CC FLAGS_REG))]
15297 "rol{w}\t{$8, %0|%0, 8}"
15298 [(set_attr "length" "4")
15299 (set_attr "mode" "HI")])
15301 (define_insn "bswapdi2"
15302 [(set (match_operand:DI 0 "register_operand" "=r")
15303 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15306 [(set_attr "prefix_0f" "1")
15307 (set_attr "length" "3")])
15309 (define_expand "clzdi2"
15311 [(set (match_operand:DI 0 "register_operand" "")
15312 (minus:DI (const_int 63)
15313 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15314 (clobber (reg:CC FLAGS_REG))])
15316 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15317 (clobber (reg:CC FLAGS_REG))])]
15322 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15327 (define_insn "clzdi2_abm"
15328 [(set (match_operand:DI 0 "register_operand" "=r")
15329 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15330 (clobber (reg:CC FLAGS_REG))]
15331 "TARGET_64BIT && TARGET_ABM"
15332 "lzcnt{q}\t{%1, %0|%0, %1}"
15333 [(set_attr "prefix_rep" "1")
15334 (set_attr "type" "bitmanip")
15335 (set_attr "mode" "DI")])
15337 (define_insn "*bsr_rex64"
15338 [(set (match_operand:DI 0 "register_operand" "=r")
15339 (minus:DI (const_int 63)
15340 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15341 (clobber (reg:CC FLAGS_REG))]
15343 "bsr{q}\t{%1, %0|%0, %1}"
15344 [(set_attr "prefix_0f" "1")
15345 (set_attr "mode" "DI")])
15347 (define_insn "popcountdi2"
15348 [(set (match_operand:DI 0 "register_operand" "=r")
15349 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15350 (clobber (reg:CC FLAGS_REG))]
15351 "TARGET_64BIT && TARGET_POPCNT"
15352 "popcnt{q}\t{%1, %0|%0, %1}"
15353 [(set_attr "prefix_rep" "1")
15354 (set_attr "type" "bitmanip")
15355 (set_attr "mode" "DI")])
15357 (define_insn "*popcountdi2_cmp"
15358 [(set (reg FLAGS_REG)
15360 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15362 (set (match_operand:DI 0 "register_operand" "=r")
15363 (popcount:DI (match_dup 1)))]
15364 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15365 "popcnt{q}\t{%1, %0|%0, %1}"
15366 [(set_attr "prefix_rep" "1")
15367 (set_attr "type" "bitmanip")
15368 (set_attr "mode" "DI")])
15370 (define_expand "clzhi2"
15372 [(set (match_operand:HI 0 "register_operand" "")
15373 (minus:HI (const_int 15)
15374 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15375 (clobber (reg:CC FLAGS_REG))])
15377 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15378 (clobber (reg:CC FLAGS_REG))])]
15383 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15388 (define_insn "clzhi2_abm"
15389 [(set (match_operand:HI 0 "register_operand" "=r")
15390 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15391 (clobber (reg:CC FLAGS_REG))]
15393 "lzcnt{w}\t{%1, %0|%0, %1}"
15394 [(set_attr "prefix_rep" "1")
15395 (set_attr "type" "bitmanip")
15396 (set_attr "mode" "HI")])
15398 (define_insn "*bsrhi"
15399 [(set (match_operand:HI 0 "register_operand" "=r")
15400 (minus:HI (const_int 15)
15401 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15402 (clobber (reg:CC FLAGS_REG))]
15404 "bsr{w}\t{%1, %0|%0, %1}"
15405 [(set_attr "prefix_0f" "1")
15406 (set_attr "mode" "HI")])
15408 (define_insn "popcounthi2"
15409 [(set (match_operand:HI 0 "register_operand" "=r")
15410 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15411 (clobber (reg:CC FLAGS_REG))]
15413 "popcnt{w}\t{%1, %0|%0, %1}"
15414 [(set_attr "prefix_rep" "1")
15415 (set_attr "type" "bitmanip")
15416 (set_attr "mode" "HI")])
15418 (define_insn "*popcounthi2_cmp"
15419 [(set (reg FLAGS_REG)
15421 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15423 (set (match_operand:HI 0 "register_operand" "=r")
15424 (popcount:HI (match_dup 1)))]
15425 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15426 "popcnt{w}\t{%1, %0|%0, %1}"
15427 [(set_attr "prefix_rep" "1")
15428 (set_attr "type" "bitmanip")
15429 (set_attr "mode" "HI")])
15431 (define_expand "paritydi2"
15432 [(set (match_operand:DI 0 "register_operand" "")
15433 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15436 rtx scratch = gen_reg_rtx (QImode);
15439 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15440 NULL_RTX, operands[1]));
15442 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15443 gen_rtx_REG (CCmode, FLAGS_REG),
15445 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15448 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15451 rtx tmp = gen_reg_rtx (SImode);
15453 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15454 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15459 (define_insn_and_split "paritydi2_cmp"
15460 [(set (reg:CC FLAGS_REG)
15461 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15462 (clobber (match_scratch:DI 0 "=r,X"))
15463 (clobber (match_scratch:SI 1 "=r,r"))
15464 (clobber (match_scratch:HI 2 "=Q,Q"))]
15467 "&& reload_completed"
15469 [(set (match_dup 1)
15470 (xor:SI (match_dup 1) (match_dup 4)))
15471 (clobber (reg:CC FLAGS_REG))])
15473 [(set (reg:CC FLAGS_REG)
15474 (parity:CC (match_dup 1)))
15475 (clobber (match_dup 1))
15476 (clobber (match_dup 2))])]
15478 operands[4] = gen_lowpart (SImode, operands[3]);
15480 if (MEM_P (operands[3]))
15481 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15482 else if (! TARGET_64BIT)
15483 operands[1] = gen_highpart (SImode, operands[3]);
15486 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15487 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15491 (define_expand "paritysi2"
15492 [(set (match_operand:SI 0 "register_operand" "")
15493 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15496 rtx scratch = gen_reg_rtx (QImode);
15499 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15501 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15502 gen_rtx_REG (CCmode, FLAGS_REG),
15504 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15506 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15510 (define_insn_and_split "paritysi2_cmp"
15511 [(set (reg:CC FLAGS_REG)
15512 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15513 (clobber (match_scratch:SI 0 "=r,X"))
15514 (clobber (match_scratch:HI 1 "=Q,Q"))]
15517 "&& reload_completed"
15519 [(set (match_dup 1)
15520 (xor:HI (match_dup 1) (match_dup 3)))
15521 (clobber (reg:CC FLAGS_REG))])
15523 [(set (reg:CC FLAGS_REG)
15524 (parity:CC (match_dup 1)))
15525 (clobber (match_dup 1))])]
15527 operands[3] = gen_lowpart (HImode, operands[2]);
15529 if (MEM_P (operands[2]))
15530 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15533 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15534 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15538 (define_insn "*parityhi2_cmp"
15539 [(set (reg:CC FLAGS_REG)
15540 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15541 (clobber (match_scratch:HI 0 "=Q"))]
15543 "xor{b}\t{%h0, %b0|%b0, %h0}"
15544 [(set_attr "length" "2")
15545 (set_attr "mode" "HI")])
15547 (define_insn "*parityqi2_cmp"
15548 [(set (reg:CC FLAGS_REG)
15549 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15552 [(set_attr "length" "2")
15553 (set_attr "mode" "QI")])
15555 ;; Thread-local storage patterns for ELF.
15557 ;; Note that these code sequences must appear exactly as shown
15558 ;; in order to allow linker relaxation.
15560 (define_insn "*tls_global_dynamic_32_gnu"
15561 [(set (match_operand:SI 0 "register_operand" "=a")
15562 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15563 (match_operand:SI 2 "tls_symbolic_operand" "")
15564 (match_operand:SI 3 "call_insn_operand" "")]
15566 (clobber (match_scratch:SI 4 "=d"))
15567 (clobber (match_scratch:SI 5 "=c"))
15568 (clobber (reg:CC FLAGS_REG))]
15569 "!TARGET_64BIT && TARGET_GNU_TLS"
15570 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15571 [(set_attr "type" "multi")
15572 (set_attr "length" "12")])
15574 (define_insn "*tls_global_dynamic_32_sun"
15575 [(set (match_operand:SI 0 "register_operand" "=a")
15576 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15577 (match_operand:SI 2 "tls_symbolic_operand" "")
15578 (match_operand:SI 3 "call_insn_operand" "")]
15580 (clobber (match_scratch:SI 4 "=d"))
15581 (clobber (match_scratch:SI 5 "=c"))
15582 (clobber (reg:CC FLAGS_REG))]
15583 "!TARGET_64BIT && TARGET_SUN_TLS"
15584 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15585 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15586 [(set_attr "type" "multi")
15587 (set_attr "length" "14")])
15589 (define_expand "tls_global_dynamic_32"
15590 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15593 (match_operand:SI 1 "tls_symbolic_operand" "")
15596 (clobber (match_scratch:SI 4 ""))
15597 (clobber (match_scratch:SI 5 ""))
15598 (clobber (reg:CC FLAGS_REG))])]
15602 operands[2] = pic_offset_table_rtx;
15605 operands[2] = gen_reg_rtx (Pmode);
15606 emit_insn (gen_set_got (operands[2]));
15608 if (TARGET_GNU2_TLS)
15610 emit_insn (gen_tls_dynamic_gnu2_32
15611 (operands[0], operands[1], operands[2]));
15614 operands[3] = ix86_tls_get_addr ();
15617 (define_insn "*tls_global_dynamic_64"
15618 [(set (match_operand:DI 0 "register_operand" "=a")
15619 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15620 (match_operand:DI 3 "" "")))
15621 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15624 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15625 [(set_attr "type" "multi")
15626 (set_attr "length" "16")])
15628 (define_expand "tls_global_dynamic_64"
15629 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15630 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15631 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15635 if (TARGET_GNU2_TLS)
15637 emit_insn (gen_tls_dynamic_gnu2_64
15638 (operands[0], operands[1]));
15641 operands[2] = ix86_tls_get_addr ();
15644 (define_insn "*tls_local_dynamic_base_32_gnu"
15645 [(set (match_operand:SI 0 "register_operand" "=a")
15646 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15647 (match_operand:SI 2 "call_insn_operand" "")]
15648 UNSPEC_TLS_LD_BASE))
15649 (clobber (match_scratch:SI 3 "=d"))
15650 (clobber (match_scratch:SI 4 "=c"))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "!TARGET_64BIT && TARGET_GNU_TLS"
15653 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15654 [(set_attr "type" "multi")
15655 (set_attr "length" "11")])
15657 (define_insn "*tls_local_dynamic_base_32_sun"
15658 [(set (match_operand:SI 0 "register_operand" "=a")
15659 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15660 (match_operand:SI 2 "call_insn_operand" "")]
15661 UNSPEC_TLS_LD_BASE))
15662 (clobber (match_scratch:SI 3 "=d"))
15663 (clobber (match_scratch:SI 4 "=c"))
15664 (clobber (reg:CC FLAGS_REG))]
15665 "!TARGET_64BIT && TARGET_SUN_TLS"
15666 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15667 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15668 [(set_attr "type" "multi")
15669 (set_attr "length" "13")])
15671 (define_expand "tls_local_dynamic_base_32"
15672 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15673 (unspec:SI [(match_dup 1) (match_dup 2)]
15674 UNSPEC_TLS_LD_BASE))
15675 (clobber (match_scratch:SI 3 ""))
15676 (clobber (match_scratch:SI 4 ""))
15677 (clobber (reg:CC FLAGS_REG))])]
15681 operands[1] = pic_offset_table_rtx;
15684 operands[1] = gen_reg_rtx (Pmode);
15685 emit_insn (gen_set_got (operands[1]));
15687 if (TARGET_GNU2_TLS)
15689 emit_insn (gen_tls_dynamic_gnu2_32
15690 (operands[0], ix86_tls_module_base (), operands[1]));
15693 operands[2] = ix86_tls_get_addr ();
15696 (define_insn "*tls_local_dynamic_base_64"
15697 [(set (match_operand:DI 0 "register_operand" "=a")
15698 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15699 (match_operand:DI 2 "" "")))
15700 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15702 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15703 [(set_attr "type" "multi")
15704 (set_attr "length" "12")])
15706 (define_expand "tls_local_dynamic_base_64"
15707 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15708 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15709 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15712 if (TARGET_GNU2_TLS)
15714 emit_insn (gen_tls_dynamic_gnu2_64
15715 (operands[0], ix86_tls_module_base ()));
15718 operands[1] = ix86_tls_get_addr ();
15721 ;; Local dynamic of a single variable is a lose. Show combine how
15722 ;; to convert that back to global dynamic.
15724 (define_insn_and_split "*tls_local_dynamic_32_once"
15725 [(set (match_operand:SI 0 "register_operand" "=a")
15726 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15727 (match_operand:SI 2 "call_insn_operand" "")]
15728 UNSPEC_TLS_LD_BASE)
15729 (const:SI (unspec:SI
15730 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15732 (clobber (match_scratch:SI 4 "=d"))
15733 (clobber (match_scratch:SI 5 "=c"))
15734 (clobber (reg:CC FLAGS_REG))]
15738 [(parallel [(set (match_dup 0)
15739 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15741 (clobber (match_dup 4))
15742 (clobber (match_dup 5))
15743 (clobber (reg:CC FLAGS_REG))])]
15746 ;; Load and add the thread base pointer from %gs:0.
15748 (define_insn "*load_tp_si"
15749 [(set (match_operand:SI 0 "register_operand" "=r")
15750 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15752 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15753 [(set_attr "type" "imov")
15754 (set_attr "modrm" "0")
15755 (set_attr "length" "7")
15756 (set_attr "memory" "load")
15757 (set_attr "imm_disp" "false")])
15759 (define_insn "*add_tp_si"
15760 [(set (match_operand:SI 0 "register_operand" "=r")
15761 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15762 (match_operand:SI 1 "register_operand" "0")))
15763 (clobber (reg:CC FLAGS_REG))]
15765 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15766 [(set_attr "type" "alu")
15767 (set_attr "modrm" "0")
15768 (set_attr "length" "7")
15769 (set_attr "memory" "load")
15770 (set_attr "imm_disp" "false")])
15772 (define_insn "*load_tp_di"
15773 [(set (match_operand:DI 0 "register_operand" "=r")
15774 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15776 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15777 [(set_attr "type" "imov")
15778 (set_attr "modrm" "0")
15779 (set_attr "length" "7")
15780 (set_attr "memory" "load")
15781 (set_attr "imm_disp" "false")])
15783 (define_insn "*add_tp_di"
15784 [(set (match_operand:DI 0 "register_operand" "=r")
15785 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15786 (match_operand:DI 1 "register_operand" "0")))
15787 (clobber (reg:CC FLAGS_REG))]
15789 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15790 [(set_attr "type" "alu")
15791 (set_attr "modrm" "0")
15792 (set_attr "length" "7")
15793 (set_attr "memory" "load")
15794 (set_attr "imm_disp" "false")])
15796 ;; GNU2 TLS patterns can be split.
15798 (define_expand "tls_dynamic_gnu2_32"
15799 [(set (match_dup 3)
15800 (plus:SI (match_operand:SI 2 "register_operand" "")
15802 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15805 [(set (match_operand:SI 0 "register_operand" "")
15806 (unspec:SI [(match_dup 1) (match_dup 3)
15807 (match_dup 2) (reg:SI SP_REG)]
15809 (clobber (reg:CC FLAGS_REG))])]
15810 "!TARGET_64BIT && TARGET_GNU2_TLS"
15812 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15813 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15816 (define_insn "*tls_dynamic_lea_32"
15817 [(set (match_operand:SI 0 "register_operand" "=r")
15818 (plus:SI (match_operand:SI 1 "register_operand" "b")
15820 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15821 UNSPEC_TLSDESC))))]
15822 "!TARGET_64BIT && TARGET_GNU2_TLS"
15823 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15824 [(set_attr "type" "lea")
15825 (set_attr "mode" "SI")
15826 (set_attr "length" "6")
15827 (set_attr "length_address" "4")])
15829 (define_insn "*tls_dynamic_call_32"
15830 [(set (match_operand:SI 0 "register_operand" "=a")
15831 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15832 (match_operand:SI 2 "register_operand" "0")
15833 ;; we have to make sure %ebx still points to the GOT
15834 (match_operand:SI 3 "register_operand" "b")
15837 (clobber (reg:CC FLAGS_REG))]
15838 "!TARGET_64BIT && TARGET_GNU2_TLS"
15839 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15840 [(set_attr "type" "call")
15841 (set_attr "length" "2")
15842 (set_attr "length_address" "0")])
15844 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15845 [(set (match_operand:SI 0 "register_operand" "=&a")
15847 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15848 (match_operand:SI 4 "" "")
15849 (match_operand:SI 2 "register_operand" "b")
15852 (const:SI (unspec:SI
15853 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15855 (clobber (reg:CC FLAGS_REG))]
15856 "!TARGET_64BIT && TARGET_GNU2_TLS"
15859 [(set (match_dup 0) (match_dup 5))]
15861 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15862 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15865 (define_expand "tls_dynamic_gnu2_64"
15866 [(set (match_dup 2)
15867 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15870 [(set (match_operand:DI 0 "register_operand" "")
15871 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15873 (clobber (reg:CC FLAGS_REG))])]
15874 "TARGET_64BIT && TARGET_GNU2_TLS"
15876 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15877 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15880 (define_insn "*tls_dynamic_lea_64"
15881 [(set (match_operand:DI 0 "register_operand" "=r")
15882 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15884 "TARGET_64BIT && TARGET_GNU2_TLS"
15885 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15886 [(set_attr "type" "lea")
15887 (set_attr "mode" "DI")
15888 (set_attr "length" "7")
15889 (set_attr "length_address" "4")])
15891 (define_insn "*tls_dynamic_call_64"
15892 [(set (match_operand:DI 0 "register_operand" "=a")
15893 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15894 (match_operand:DI 2 "register_operand" "0")
15897 (clobber (reg:CC FLAGS_REG))]
15898 "TARGET_64BIT && TARGET_GNU2_TLS"
15899 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15900 [(set_attr "type" "call")
15901 (set_attr "length" "2")
15902 (set_attr "length_address" "0")])
15904 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15905 [(set (match_operand:DI 0 "register_operand" "=&a")
15907 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15908 (match_operand:DI 3 "" "")
15911 (const:DI (unspec:DI
15912 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15914 (clobber (reg:CC FLAGS_REG))]
15915 "TARGET_64BIT && TARGET_GNU2_TLS"
15918 [(set (match_dup 0) (match_dup 4))]
15920 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15921 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15926 ;; These patterns match the binary 387 instructions for addM3, subM3,
15927 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15928 ;; SFmode. The first is the normal insn, the second the same insn but
15929 ;; with one operand a conversion, and the third the same insn but with
15930 ;; the other operand a conversion. The conversion may be SFmode or
15931 ;; SImode if the target mode DFmode, but only SImode if the target mode
15934 ;; Gcc is slightly more smart about handling normal two address instructions
15935 ;; so use special patterns for add and mull.
15937 (define_insn "*fop_sf_comm_mixed"
15938 [(set (match_operand:SF 0 "register_operand" "=f,x")
15939 (match_operator:SF 3 "binary_fp_operator"
15940 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15941 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15942 "TARGET_MIX_SSE_I387
15943 && COMMUTATIVE_ARITH_P (operands[3])
15944 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15945 "* return output_387_binary_op (insn, operands);"
15946 [(set (attr "type")
15947 (if_then_else (eq_attr "alternative" "1")
15948 (if_then_else (match_operand:SF 3 "mult_operator" "")
15949 (const_string "ssemul")
15950 (const_string "sseadd"))
15951 (if_then_else (match_operand:SF 3 "mult_operator" "")
15952 (const_string "fmul")
15953 (const_string "fop"))))
15954 (set_attr "mode" "SF")])
15956 (define_insn "*fop_sf_comm_sse"
15957 [(set (match_operand:SF 0 "register_operand" "=x")
15958 (match_operator:SF 3 "binary_fp_operator"
15959 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15960 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15962 && COMMUTATIVE_ARITH_P (operands[3])
15963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15964 "* return output_387_binary_op (insn, operands);"
15965 [(set (attr "type")
15966 (if_then_else (match_operand:SF 3 "mult_operator" "")
15967 (const_string "ssemul")
15968 (const_string "sseadd")))
15969 (set_attr "mode" "SF")])
15971 (define_insn "*fop_sf_comm_i387"
15972 [(set (match_operand:SF 0 "register_operand" "=f")
15973 (match_operator:SF 3 "binary_fp_operator"
15974 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15975 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15977 && COMMUTATIVE_ARITH_P (operands[3])
15978 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15979 "* return output_387_binary_op (insn, operands);"
15980 [(set (attr "type")
15981 (if_then_else (match_operand:SF 3 "mult_operator" "")
15982 (const_string "fmul")
15983 (const_string "fop")))
15984 (set_attr "mode" "SF")])
15986 (define_insn "*fop_sf_1_mixed"
15987 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15988 (match_operator:SF 3 "binary_fp_operator"
15989 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15990 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15991 "TARGET_MIX_SSE_I387
15992 && !COMMUTATIVE_ARITH_P (operands[3])
15993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15994 "* return output_387_binary_op (insn, operands);"
15995 [(set (attr "type")
15996 (cond [(and (eq_attr "alternative" "2")
15997 (match_operand:SF 3 "mult_operator" ""))
15998 (const_string "ssemul")
15999 (and (eq_attr "alternative" "2")
16000 (match_operand:SF 3 "div_operator" ""))
16001 (const_string "ssediv")
16002 (eq_attr "alternative" "2")
16003 (const_string "sseadd")
16004 (match_operand:SF 3 "mult_operator" "")
16005 (const_string "fmul")
16006 (match_operand:SF 3 "div_operator" "")
16007 (const_string "fdiv")
16009 (const_string "fop")))
16010 (set_attr "mode" "SF")])
16012 (define_insn "*rcpsf2_sse"
16013 [(set (match_operand:SF 0 "register_operand" "=x")
16014 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16017 "rcpss\t{%1, %0|%0, %1}"
16018 [(set_attr "type" "sse")
16019 (set_attr "mode" "SF")])
16021 (define_insn "*fop_sf_1_sse"
16022 [(set (match_operand:SF 0 "register_operand" "=x")
16023 (match_operator:SF 3 "binary_fp_operator"
16024 [(match_operand:SF 1 "register_operand" "0")
16025 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16027 && !COMMUTATIVE_ARITH_P (operands[3])"
16028 "* return output_387_binary_op (insn, operands);"
16029 [(set (attr "type")
16030 (cond [(match_operand:SF 3 "mult_operator" "")
16031 (const_string "ssemul")
16032 (match_operand:SF 3 "div_operator" "")
16033 (const_string "ssediv")
16035 (const_string "sseadd")))
16036 (set_attr "mode" "SF")])
16038 ;; This pattern is not fully shadowed by the pattern above.
16039 (define_insn "*fop_sf_1_i387"
16040 [(set (match_operand:SF 0 "register_operand" "=f,f")
16041 (match_operator:SF 3 "binary_fp_operator"
16042 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16043 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16044 "TARGET_80387 && !TARGET_SSE_MATH
16045 && !COMMUTATIVE_ARITH_P (operands[3])
16046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16047 "* return output_387_binary_op (insn, operands);"
16048 [(set (attr "type")
16049 (cond [(match_operand:SF 3 "mult_operator" "")
16050 (const_string "fmul")
16051 (match_operand:SF 3 "div_operator" "")
16052 (const_string "fdiv")
16054 (const_string "fop")))
16055 (set_attr "mode" "SF")])
16057 ;; ??? Add SSE splitters for these!
16058 (define_insn "*fop_sf_2<mode>_i387"
16059 [(set (match_operand:SF 0 "register_operand" "=f,f")
16060 (match_operator:SF 3 "binary_fp_operator"
16061 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16062 (match_operand:SF 2 "register_operand" "0,0")]))]
16063 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16064 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16065 [(set (attr "type")
16066 (cond [(match_operand:SF 3 "mult_operator" "")
16067 (const_string "fmul")
16068 (match_operand:SF 3 "div_operator" "")
16069 (const_string "fdiv")
16071 (const_string "fop")))
16072 (set_attr "fp_int_src" "true")
16073 (set_attr "mode" "<MODE>")])
16075 (define_insn "*fop_sf_3<mode>_i387"
16076 [(set (match_operand:SF 0 "register_operand" "=f,f")
16077 (match_operator:SF 3 "binary_fp_operator"
16078 [(match_operand:SF 1 "register_operand" "0,0")
16079 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16080 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16081 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16082 [(set (attr "type")
16083 (cond [(match_operand:SF 3 "mult_operator" "")
16084 (const_string "fmul")
16085 (match_operand:SF 3 "div_operator" "")
16086 (const_string "fdiv")
16088 (const_string "fop")))
16089 (set_attr "fp_int_src" "true")
16090 (set_attr "mode" "<MODE>")])
16092 (define_insn "*fop_df_comm_mixed"
16093 [(set (match_operand:DF 0 "register_operand" "=f,x")
16094 (match_operator:DF 3 "binary_fp_operator"
16095 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16096 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16097 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16098 && COMMUTATIVE_ARITH_P (operands[3])
16099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16100 "* return output_387_binary_op (insn, operands);"
16101 [(set (attr "type")
16102 (if_then_else (eq_attr "alternative" "1")
16103 (if_then_else (match_operand:DF 3 "mult_operator" "")
16104 (const_string "ssemul")
16105 (const_string "sseadd"))
16106 (if_then_else (match_operand:DF 3 "mult_operator" "")
16107 (const_string "fmul")
16108 (const_string "fop"))))
16109 (set_attr "mode" "DF")])
16111 (define_insn "*fop_df_comm_sse"
16112 [(set (match_operand:DF 0 "register_operand" "=x")
16113 (match_operator:DF 3 "binary_fp_operator"
16114 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16115 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16116 "TARGET_SSE2 && TARGET_SSE_MATH
16117 && COMMUTATIVE_ARITH_P (operands[3])
16118 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16119 "* return output_387_binary_op (insn, operands);"
16120 [(set (attr "type")
16121 (if_then_else (match_operand:DF 3 "mult_operator" "")
16122 (const_string "ssemul")
16123 (const_string "sseadd")))
16124 (set_attr "mode" "DF")])
16126 (define_insn "*fop_df_comm_i387"
16127 [(set (match_operand:DF 0 "register_operand" "=f")
16128 (match_operator:DF 3 "binary_fp_operator"
16129 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16130 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16132 && COMMUTATIVE_ARITH_P (operands[3])
16133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134 "* return output_387_binary_op (insn, operands);"
16135 [(set (attr "type")
16136 (if_then_else (match_operand:DF 3 "mult_operator" "")
16137 (const_string "fmul")
16138 (const_string "fop")))
16139 (set_attr "mode" "DF")])
16141 (define_insn "*fop_df_1_mixed"
16142 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16143 (match_operator:DF 3 "binary_fp_operator"
16144 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16145 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16146 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16147 && !COMMUTATIVE_ARITH_P (operands[3])
16148 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16149 "* return output_387_binary_op (insn, operands);"
16150 [(set (attr "type")
16151 (cond [(and (eq_attr "alternative" "2")
16152 (match_operand:DF 3 "mult_operator" ""))
16153 (const_string "ssemul")
16154 (and (eq_attr "alternative" "2")
16155 (match_operand:DF 3 "div_operator" ""))
16156 (const_string "ssediv")
16157 (eq_attr "alternative" "2")
16158 (const_string "sseadd")
16159 (match_operand:DF 3 "mult_operator" "")
16160 (const_string "fmul")
16161 (match_operand:DF 3 "div_operator" "")
16162 (const_string "fdiv")
16164 (const_string "fop")))
16165 (set_attr "mode" "DF")])
16167 (define_insn "*fop_df_1_sse"
16168 [(set (match_operand:DF 0 "register_operand" "=x")
16169 (match_operator:DF 3 "binary_fp_operator"
16170 [(match_operand:DF 1 "register_operand" "0")
16171 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16172 "TARGET_SSE2 && TARGET_SSE_MATH
16173 && !COMMUTATIVE_ARITH_P (operands[3])"
16174 "* return output_387_binary_op (insn, operands);"
16175 [(set_attr "mode" "DF")
16177 (cond [(match_operand:DF 3 "mult_operator" "")
16178 (const_string "ssemul")
16179 (match_operand:DF 3 "div_operator" "")
16180 (const_string "ssediv")
16182 (const_string "sseadd")))])
16184 ;; This pattern is not fully shadowed by the pattern above.
16185 (define_insn "*fop_df_1_i387"
16186 [(set (match_operand:DF 0 "register_operand" "=f,f")
16187 (match_operator:DF 3 "binary_fp_operator"
16188 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16189 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16190 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16191 && !COMMUTATIVE_ARITH_P (operands[3])
16192 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16193 "* return output_387_binary_op (insn, operands);"
16194 [(set (attr "type")
16195 (cond [(match_operand:DF 3 "mult_operator" "")
16196 (const_string "fmul")
16197 (match_operand:DF 3 "div_operator" "")
16198 (const_string "fdiv")
16200 (const_string "fop")))
16201 (set_attr "mode" "DF")])
16203 ;; ??? Add SSE splitters for these!
16204 (define_insn "*fop_df_2<mode>_i387"
16205 [(set (match_operand:DF 0 "register_operand" "=f,f")
16206 (match_operator:DF 3 "binary_fp_operator"
16207 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16208 (match_operand:DF 2 "register_operand" "0,0")]))]
16209 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16210 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16211 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16212 [(set (attr "type")
16213 (cond [(match_operand:DF 3 "mult_operator" "")
16214 (const_string "fmul")
16215 (match_operand:DF 3 "div_operator" "")
16216 (const_string "fdiv")
16218 (const_string "fop")))
16219 (set_attr "fp_int_src" "true")
16220 (set_attr "mode" "<MODE>")])
16222 (define_insn "*fop_df_3<mode>_i387"
16223 [(set (match_operand:DF 0 "register_operand" "=f,f")
16224 (match_operator:DF 3 "binary_fp_operator"
16225 [(match_operand:DF 1 "register_operand" "0,0")
16226 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16227 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16228 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16229 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16230 [(set (attr "type")
16231 (cond [(match_operand:DF 3 "mult_operator" "")
16232 (const_string "fmul")
16233 (match_operand:DF 3 "div_operator" "")
16234 (const_string "fdiv")
16236 (const_string "fop")))
16237 (set_attr "fp_int_src" "true")
16238 (set_attr "mode" "<MODE>")])
16240 (define_insn "*fop_df_4_i387"
16241 [(set (match_operand:DF 0 "register_operand" "=f,f")
16242 (match_operator:DF 3 "binary_fp_operator"
16243 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16244 (match_operand:DF 2 "register_operand" "0,f")]))]
16245 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16247 "* return output_387_binary_op (insn, operands);"
16248 [(set (attr "type")
16249 (cond [(match_operand:DF 3 "mult_operator" "")
16250 (const_string "fmul")
16251 (match_operand:DF 3 "div_operator" "")
16252 (const_string "fdiv")
16254 (const_string "fop")))
16255 (set_attr "mode" "SF")])
16257 (define_insn "*fop_df_5_i387"
16258 [(set (match_operand:DF 0 "register_operand" "=f,f")
16259 (match_operator:DF 3 "binary_fp_operator"
16260 [(match_operand:DF 1 "register_operand" "0,f")
16262 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16263 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16264 "* return output_387_binary_op (insn, operands);"
16265 [(set (attr "type")
16266 (cond [(match_operand:DF 3 "mult_operator" "")
16267 (const_string "fmul")
16268 (match_operand:DF 3 "div_operator" "")
16269 (const_string "fdiv")
16271 (const_string "fop")))
16272 (set_attr "mode" "SF")])
16274 (define_insn "*fop_df_6_i387"
16275 [(set (match_operand:DF 0 "register_operand" "=f,f")
16276 (match_operator:DF 3 "binary_fp_operator"
16278 (match_operand:SF 1 "register_operand" "0,f"))
16280 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16281 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16282 "* return output_387_binary_op (insn, operands);"
16283 [(set (attr "type")
16284 (cond [(match_operand:DF 3 "mult_operator" "")
16285 (const_string "fmul")
16286 (match_operand:DF 3 "div_operator" "")
16287 (const_string "fdiv")
16289 (const_string "fop")))
16290 (set_attr "mode" "SF")])
16292 (define_insn "*fop_xf_comm_i387"
16293 [(set (match_operand:XF 0 "register_operand" "=f")
16294 (match_operator:XF 3 "binary_fp_operator"
16295 [(match_operand:XF 1 "register_operand" "%0")
16296 (match_operand:XF 2 "register_operand" "f")]))]
16298 && COMMUTATIVE_ARITH_P (operands[3])"
16299 "* return output_387_binary_op (insn, operands);"
16300 [(set (attr "type")
16301 (if_then_else (match_operand:XF 3 "mult_operator" "")
16302 (const_string "fmul")
16303 (const_string "fop")))
16304 (set_attr "mode" "XF")])
16306 (define_insn "*fop_xf_1_i387"
16307 [(set (match_operand:XF 0 "register_operand" "=f,f")
16308 (match_operator:XF 3 "binary_fp_operator"
16309 [(match_operand:XF 1 "register_operand" "0,f")
16310 (match_operand:XF 2 "register_operand" "f,0")]))]
16312 && !COMMUTATIVE_ARITH_P (operands[3])"
16313 "* return output_387_binary_op (insn, operands);"
16314 [(set (attr "type")
16315 (cond [(match_operand:XF 3 "mult_operator" "")
16316 (const_string "fmul")
16317 (match_operand:XF 3 "div_operator" "")
16318 (const_string "fdiv")
16320 (const_string "fop")))
16321 (set_attr "mode" "XF")])
16323 (define_insn "*fop_xf_2<mode>_i387"
16324 [(set (match_operand:XF 0 "register_operand" "=f,f")
16325 (match_operator:XF 3 "binary_fp_operator"
16326 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16327 (match_operand:XF 2 "register_operand" "0,0")]))]
16328 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16329 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16330 [(set (attr "type")
16331 (cond [(match_operand:XF 3 "mult_operator" "")
16332 (const_string "fmul")
16333 (match_operand:XF 3 "div_operator" "")
16334 (const_string "fdiv")
16336 (const_string "fop")))
16337 (set_attr "fp_int_src" "true")
16338 (set_attr "mode" "<MODE>")])
16340 (define_insn "*fop_xf_3<mode>_i387"
16341 [(set (match_operand:XF 0 "register_operand" "=f,f")
16342 (match_operator:XF 3 "binary_fp_operator"
16343 [(match_operand:XF 1 "register_operand" "0,0")
16344 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16345 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16346 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16347 [(set (attr "type")
16348 (cond [(match_operand:XF 3 "mult_operator" "")
16349 (const_string "fmul")
16350 (match_operand:XF 3 "div_operator" "")
16351 (const_string "fdiv")
16353 (const_string "fop")))
16354 (set_attr "fp_int_src" "true")
16355 (set_attr "mode" "<MODE>")])
16357 (define_insn "*fop_xf_4_i387"
16358 [(set (match_operand:XF 0 "register_operand" "=f,f")
16359 (match_operator:XF 3 "binary_fp_operator"
16361 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16362 (match_operand:XF 2 "register_operand" "0,f")]))]
16364 "* return output_387_binary_op (insn, operands);"
16365 [(set (attr "type")
16366 (cond [(match_operand:XF 3 "mult_operator" "")
16367 (const_string "fmul")
16368 (match_operand:XF 3 "div_operator" "")
16369 (const_string "fdiv")
16371 (const_string "fop")))
16372 (set_attr "mode" "SF")])
16374 (define_insn "*fop_xf_5_i387"
16375 [(set (match_operand:XF 0 "register_operand" "=f,f")
16376 (match_operator:XF 3 "binary_fp_operator"
16377 [(match_operand:XF 1 "register_operand" "0,f")
16379 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16381 "* return output_387_binary_op (insn, operands);"
16382 [(set (attr "type")
16383 (cond [(match_operand:XF 3 "mult_operator" "")
16384 (const_string "fmul")
16385 (match_operand:XF 3 "div_operator" "")
16386 (const_string "fdiv")
16388 (const_string "fop")))
16389 (set_attr "mode" "SF")])
16391 (define_insn "*fop_xf_6_i387"
16392 [(set (match_operand:XF 0 "register_operand" "=f,f")
16393 (match_operator:XF 3 "binary_fp_operator"
16395 (match_operand:MODEF 1 "register_operand" "0,f"))
16397 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16399 "* return output_387_binary_op (insn, operands);"
16400 [(set (attr "type")
16401 (cond [(match_operand:XF 3 "mult_operator" "")
16402 (const_string "fmul")
16403 (match_operand:XF 3 "div_operator" "")
16404 (const_string "fdiv")
16406 (const_string "fop")))
16407 (set_attr "mode" "SF")])
16410 [(set (match_operand 0 "register_operand" "")
16411 (match_operator 3 "binary_fp_operator"
16412 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16413 (match_operand 2 "register_operand" "")]))]
16415 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16418 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16419 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16420 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16421 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16422 GET_MODE (operands[3]),
16425 ix86_free_from_memory (GET_MODE (operands[1]));
16430 [(set (match_operand 0 "register_operand" "")
16431 (match_operator 3 "binary_fp_operator"
16432 [(match_operand 1 "register_operand" "")
16433 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16435 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16438 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16439 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16440 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16441 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16442 GET_MODE (operands[3]),
16445 ix86_free_from_memory (GET_MODE (operands[2]));
16449 ;; FPU special functions.
16451 ;; This pattern implements a no-op XFmode truncation for
16452 ;; all fancy i386 XFmode math functions.
16454 (define_insn "truncxf<mode>2_i387_noop_unspec"
16455 [(set (match_operand:MODEF 0 "register_operand" "=f")
16456 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16457 UNSPEC_TRUNC_NOOP))]
16458 "TARGET_USE_FANCY_MATH_387"
16459 "* return output_387_reg_move (insn, operands);"
16460 [(set_attr "type" "fmov")
16461 (set_attr "mode" "<MODE>")])
16463 (define_insn "sqrtxf2"
16464 [(set (match_operand:XF 0 "register_operand" "=f")
16465 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16466 "TARGET_USE_FANCY_MATH_387"
16468 [(set_attr "type" "fpspc")
16469 (set_attr "mode" "XF")
16470 (set_attr "athlon_decode" "direct")
16471 (set_attr "amdfam10_decode" "direct")])
16473 (define_insn "sqrt_extend<mode>xf2_i387"
16474 [(set (match_operand:XF 0 "register_operand" "=f")
16477 (match_operand:MODEF 1 "register_operand" "0"))))]
16478 "TARGET_USE_FANCY_MATH_387"
16480 [(set_attr "type" "fpspc")
16481 (set_attr "mode" "XF")
16482 (set_attr "athlon_decode" "direct")
16483 (set_attr "amdfam10_decode" "direct")])
16485 (define_insn "*rsqrtsf2_sse"
16486 [(set (match_operand:SF 0 "register_operand" "=x")
16487 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16490 "rsqrtss\t{%1, %0|%0, %1}"
16491 [(set_attr "type" "sse")
16492 (set_attr "mode" "SF")])
16494 (define_expand "rsqrtsf2"
16495 [(set (match_operand:SF 0 "register_operand" "")
16496 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16500 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16504 (define_insn "*sqrt<mode>2_sse"
16505 [(set (match_operand:MODEF 0 "register_operand" "=x")
16507 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16508 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16509 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16510 [(set_attr "type" "sse")
16511 (set_attr "mode" "<MODE>")
16512 (set_attr "athlon_decode" "*")
16513 (set_attr "amdfam10_decode" "*")])
16515 (define_expand "sqrt<mode>2"
16516 [(set (match_operand:MODEF 0 "register_operand" "")
16518 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16519 "TARGET_USE_FANCY_MATH_387
16520 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16522 if (<MODE>mode == SFmode
16523 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16524 && flag_finite_math_only && !flag_trapping_math
16525 && flag_unsafe_math_optimizations)
16527 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16531 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16533 rtx op0 = gen_reg_rtx (XFmode);
16534 rtx op1 = force_reg (<MODE>mode, operands[1]);
16536 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16537 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16542 (define_insn "fpremxf4_i387"
16543 [(set (match_operand:XF 0 "register_operand" "=f")
16544 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16545 (match_operand:XF 3 "register_operand" "1")]
16547 (set (match_operand:XF 1 "register_operand" "=u")
16548 (unspec:XF [(match_dup 2) (match_dup 3)]
16550 (set (reg:CCFP FPSR_REG)
16551 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16553 "TARGET_USE_FANCY_MATH_387"
16555 [(set_attr "type" "fpspc")
16556 (set_attr "mode" "XF")])
16558 (define_expand "fmodxf3"
16559 [(use (match_operand:XF 0 "register_operand" ""))
16560 (use (match_operand:XF 1 "register_operand" ""))
16561 (use (match_operand:XF 2 "register_operand" ""))]
16562 "TARGET_USE_FANCY_MATH_387"
16564 rtx label = gen_label_rtx ();
16568 if (rtx_equal_p (operands[1], operands[2]))
16570 op2 = gen_reg_rtx (XFmode);
16571 emit_move_insn (op2, operands[2]);
16576 emit_label (label);
16577 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16578 ix86_emit_fp_unordered_jump (label);
16579 LABEL_NUSES (label) = 1;
16581 emit_move_insn (operands[0], operands[1]);
16585 (define_expand "fmod<mode>3"
16586 [(use (match_operand:MODEF 0 "register_operand" ""))
16587 (use (match_operand:MODEF 1 "general_operand" ""))
16588 (use (match_operand:MODEF 2 "general_operand" ""))]
16589 "TARGET_USE_FANCY_MATH_387"
16591 rtx label = gen_label_rtx ();
16593 rtx op1 = gen_reg_rtx (XFmode);
16594 rtx op2 = gen_reg_rtx (XFmode);
16596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16597 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16599 emit_label (label);
16600 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16601 ix86_emit_fp_unordered_jump (label);
16602 LABEL_NUSES (label) = 1;
16604 /* Truncate the result properly for strict SSE math. */
16605 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16606 && !TARGET_MIX_SSE_I387)
16607 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16609 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16614 (define_insn "fprem1xf4_i387"
16615 [(set (match_operand:XF 0 "register_operand" "=f")
16616 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16617 (match_operand:XF 3 "register_operand" "1")]
16619 (set (match_operand:XF 1 "register_operand" "=u")
16620 (unspec:XF [(match_dup 2) (match_dup 3)]
16622 (set (reg:CCFP FPSR_REG)
16623 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16625 "TARGET_USE_FANCY_MATH_387"
16627 [(set_attr "type" "fpspc")
16628 (set_attr "mode" "XF")])
16630 (define_expand "remainderxf3"
16631 [(use (match_operand:XF 0 "register_operand" ""))
16632 (use (match_operand:XF 1 "register_operand" ""))
16633 (use (match_operand:XF 2 "register_operand" ""))]
16634 "TARGET_USE_FANCY_MATH_387"
16636 rtx label = gen_label_rtx ();
16640 if (rtx_equal_p (operands[1], operands[2]))
16642 op2 = gen_reg_rtx (XFmode);
16643 emit_move_insn (op2, operands[2]);
16648 emit_label (label);
16649 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16650 ix86_emit_fp_unordered_jump (label);
16651 LABEL_NUSES (label) = 1;
16653 emit_move_insn (operands[0], operands[1]);
16657 (define_expand "remainder<mode>3"
16658 [(use (match_operand:MODEF 0 "register_operand" ""))
16659 (use (match_operand:MODEF 1 "general_operand" ""))
16660 (use (match_operand:MODEF 2 "general_operand" ""))]
16661 "TARGET_USE_FANCY_MATH_387"
16663 rtx label = gen_label_rtx ();
16665 rtx op1 = gen_reg_rtx (XFmode);
16666 rtx op2 = gen_reg_rtx (XFmode);
16668 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16669 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16671 emit_label (label);
16673 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16674 ix86_emit_fp_unordered_jump (label);
16675 LABEL_NUSES (label) = 1;
16677 /* Truncate the result properly for strict SSE math. */
16678 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16679 && !TARGET_MIX_SSE_I387)
16680 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16682 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16687 (define_insn "*sinxf2_i387"
16688 [(set (match_operand:XF 0 "register_operand" "=f")
16689 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && flag_unsafe_math_optimizations"
16693 [(set_attr "type" "fpspc")
16694 (set_attr "mode" "XF")])
16696 (define_insn "*sin_extend<mode>xf2_i387"
16697 [(set (match_operand:XF 0 "register_operand" "=f")
16698 (unspec:XF [(float_extend:XF
16699 (match_operand:MODEF 1 "register_operand" "0"))]
16701 "TARGET_USE_FANCY_MATH_387
16702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16703 || TARGET_MIX_SSE_I387)
16704 && flag_unsafe_math_optimizations"
16706 [(set_attr "type" "fpspc")
16707 (set_attr "mode" "XF")])
16709 (define_insn "*cosxf2_i387"
16710 [(set (match_operand:XF 0 "register_operand" "=f")
16711 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16712 "TARGET_USE_FANCY_MATH_387
16713 && flag_unsafe_math_optimizations"
16715 [(set_attr "type" "fpspc")
16716 (set_attr "mode" "XF")])
16718 (define_insn "*cos_extend<mode>xf2_i387"
16719 [(set (match_operand:XF 0 "register_operand" "=f")
16720 (unspec:XF [(float_extend:XF
16721 (match_operand:MODEF 1 "register_operand" "0"))]
16723 "TARGET_USE_FANCY_MATH_387
16724 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16725 || TARGET_MIX_SSE_I387)
16726 && flag_unsafe_math_optimizations"
16728 [(set_attr "type" "fpspc")
16729 (set_attr "mode" "XF")])
16731 ;; When sincos pattern is defined, sin and cos builtin functions will be
16732 ;; expanded to sincos pattern with one of its outputs left unused.
16733 ;; CSE pass will figure out if two sincos patterns can be combined,
16734 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16735 ;; depending on the unused output.
16737 (define_insn "sincosxf3"
16738 [(set (match_operand:XF 0 "register_operand" "=f")
16739 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16740 UNSPEC_SINCOS_COS))
16741 (set (match_operand:XF 1 "register_operand" "=u")
16742 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && flag_unsafe_math_optimizations"
16746 [(set_attr "type" "fpspc")
16747 (set_attr "mode" "XF")])
16750 [(set (match_operand:XF 0 "register_operand" "")
16751 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16752 UNSPEC_SINCOS_COS))
16753 (set (match_operand:XF 1 "register_operand" "")
16754 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16755 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16756 && !(reload_completed || reload_in_progress)"
16757 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16761 [(set (match_operand:XF 0 "register_operand" "")
16762 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16763 UNSPEC_SINCOS_COS))
16764 (set (match_operand:XF 1 "register_operand" "")
16765 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16766 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16767 && !(reload_completed || reload_in_progress)"
16768 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16771 (define_insn "sincos_extend<mode>xf3_i387"
16772 [(set (match_operand:XF 0 "register_operand" "=f")
16773 (unspec:XF [(float_extend:XF
16774 (match_operand:MODEF 2 "register_operand" "0"))]
16775 UNSPEC_SINCOS_COS))
16776 (set (match_operand:XF 1 "register_operand" "=u")
16777 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16778 "TARGET_USE_FANCY_MATH_387
16779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16780 || TARGET_MIX_SSE_I387)
16781 && flag_unsafe_math_optimizations"
16783 [(set_attr "type" "fpspc")
16784 (set_attr "mode" "XF")])
16787 [(set (match_operand:XF 0 "register_operand" "")
16788 (unspec:XF [(float_extend:XF
16789 (match_operand:MODEF 2 "register_operand" ""))]
16790 UNSPEC_SINCOS_COS))
16791 (set (match_operand:XF 1 "register_operand" "")
16792 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16793 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16794 && !(reload_completed || reload_in_progress)"
16795 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16799 [(set (match_operand:XF 0 "register_operand" "")
16800 (unspec:XF [(float_extend:XF
16801 (match_operand:MODEF 2 "register_operand" ""))]
16802 UNSPEC_SINCOS_COS))
16803 (set (match_operand:XF 1 "register_operand" "")
16804 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16805 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16806 && !(reload_completed || reload_in_progress)"
16807 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16810 (define_expand "sincos<mode>3"
16811 [(use (match_operand:MODEF 0 "register_operand" ""))
16812 (use (match_operand:MODEF 1 "register_operand" ""))
16813 (use (match_operand:MODEF 2 "register_operand" ""))]
16814 "TARGET_USE_FANCY_MATH_387
16815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16816 || TARGET_MIX_SSE_I387)
16817 && flag_unsafe_math_optimizations"
16819 rtx op0 = gen_reg_rtx (XFmode);
16820 rtx op1 = gen_reg_rtx (XFmode);
16822 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16823 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16824 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16828 (define_insn "fptanxf4_i387"
16829 [(set (match_operand:XF 0 "register_operand" "=f")
16830 (match_operand:XF 3 "const_double_operand" "F"))
16831 (set (match_operand:XF 1 "register_operand" "=u")
16832 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16834 "TARGET_USE_FANCY_MATH_387
16835 && flag_unsafe_math_optimizations
16836 && standard_80387_constant_p (operands[3]) == 2"
16838 [(set_attr "type" "fpspc")
16839 (set_attr "mode" "XF")])
16841 (define_insn "fptan_extend<mode>xf4_i387"
16842 [(set (match_operand:MODEF 0 "register_operand" "=f")
16843 (match_operand:MODEF 3 "const_double_operand" "F"))
16844 (set (match_operand:XF 1 "register_operand" "=u")
16845 (unspec:XF [(float_extend:XF
16846 (match_operand:MODEF 2 "register_operand" "0"))]
16848 "TARGET_USE_FANCY_MATH_387
16849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16850 || TARGET_MIX_SSE_I387)
16851 && flag_unsafe_math_optimizations
16852 && standard_80387_constant_p (operands[3]) == 2"
16854 [(set_attr "type" "fpspc")
16855 (set_attr "mode" "XF")])
16857 (define_expand "tanxf2"
16858 [(use (match_operand:XF 0 "register_operand" ""))
16859 (use (match_operand:XF 1 "register_operand" ""))]
16860 "TARGET_USE_FANCY_MATH_387
16861 && flag_unsafe_math_optimizations"
16863 rtx one = gen_reg_rtx (XFmode);
16864 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16866 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16870 (define_expand "tan<mode>2"
16871 [(use (match_operand:MODEF 0 "register_operand" ""))
16872 (use (match_operand:MODEF 1 "register_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16875 || TARGET_MIX_SSE_I387)
16876 && flag_unsafe_math_optimizations"
16878 rtx op0 = gen_reg_rtx (XFmode);
16880 rtx one = gen_reg_rtx (<MODE>mode);
16881 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16883 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16884 operands[1], op2));
16885 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16889 (define_insn "*fpatanxf3_i387"
16890 [(set (match_operand:XF 0 "register_operand" "=f")
16891 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16892 (match_operand:XF 2 "register_operand" "u")]
16894 (clobber (match_scratch:XF 3 "=2"))]
16895 "TARGET_USE_FANCY_MATH_387
16896 && flag_unsafe_math_optimizations"
16898 [(set_attr "type" "fpspc")
16899 (set_attr "mode" "XF")])
16901 (define_insn "fpatan_extend<mode>xf3_i387"
16902 [(set (match_operand:XF 0 "register_operand" "=f")
16903 (unspec:XF [(float_extend:XF
16904 (match_operand:MODEF 1 "register_operand" "0"))
16906 (match_operand:MODEF 2 "register_operand" "u"))]
16908 (clobber (match_scratch:XF 3 "=2"))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16911 || TARGET_MIX_SSE_I387)
16912 && flag_unsafe_math_optimizations"
16914 [(set_attr "type" "fpspc")
16915 (set_attr "mode" "XF")])
16917 (define_expand "atan2xf3"
16918 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16919 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16920 (match_operand:XF 1 "register_operand" "")]
16922 (clobber (match_scratch:XF 3 ""))])]
16923 "TARGET_USE_FANCY_MATH_387
16924 && flag_unsafe_math_optimizations"
16927 (define_expand "atan2<mode>3"
16928 [(use (match_operand:MODEF 0 "register_operand" ""))
16929 (use (match_operand:MODEF 1 "register_operand" ""))
16930 (use (match_operand:MODEF 2 "register_operand" ""))]
16931 "TARGET_USE_FANCY_MATH_387
16932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16933 || TARGET_MIX_SSE_I387)
16934 && flag_unsafe_math_optimizations"
16936 rtx op0 = gen_reg_rtx (XFmode);
16938 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16943 (define_expand "atanxf2"
16944 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16945 (unspec:XF [(match_dup 2)
16946 (match_operand:XF 1 "register_operand" "")]
16948 (clobber (match_scratch:XF 3 ""))])]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations"
16952 operands[2] = gen_reg_rtx (XFmode);
16953 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16956 (define_expand "atan<mode>2"
16957 [(use (match_operand:MODEF 0 "register_operand" ""))
16958 (use (match_operand:MODEF 1 "register_operand" ""))]
16959 "TARGET_USE_FANCY_MATH_387
16960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16961 || TARGET_MIX_SSE_I387)
16962 && flag_unsafe_math_optimizations"
16964 rtx op0 = gen_reg_rtx (XFmode);
16966 rtx op2 = gen_reg_rtx (<MODE>mode);
16967 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16969 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16970 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16974 (define_expand "asinxf2"
16975 [(set (match_dup 2)
16976 (mult:XF (match_operand:XF 1 "register_operand" "")
16978 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16979 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16980 (parallel [(set (match_operand:XF 0 "register_operand" "")
16981 (unspec:XF [(match_dup 5) (match_dup 1)]
16983 (clobber (match_scratch:XF 6 ""))])]
16984 "TARGET_USE_FANCY_MATH_387
16985 && flag_unsafe_math_optimizations && !optimize_size"
16989 for (i = 2; i < 6; i++)
16990 operands[i] = gen_reg_rtx (XFmode);
16992 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16995 (define_expand "asin<mode>2"
16996 [(use (match_operand:MODEF 0 "register_operand" ""))
16997 (use (match_operand:MODEF 1 "general_operand" ""))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000 || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations && !optimize_size"
17003 rtx op0 = gen_reg_rtx (XFmode);
17004 rtx op1 = gen_reg_rtx (XFmode);
17006 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17007 emit_insn (gen_asinxf2 (op0, op1));
17008 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17012 (define_expand "acosxf2"
17013 [(set (match_dup 2)
17014 (mult:XF (match_operand:XF 1 "register_operand" "")
17016 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17017 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17018 (parallel [(set (match_operand:XF 0 "register_operand" "")
17019 (unspec:XF [(match_dup 1) (match_dup 5)]
17021 (clobber (match_scratch:XF 6 ""))])]
17022 "TARGET_USE_FANCY_MATH_387
17023 && flag_unsafe_math_optimizations && !optimize_size"
17027 for (i = 2; i < 6; i++)
17028 operands[i] = gen_reg_rtx (XFmode);
17030 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17033 (define_expand "acos<mode>2"
17034 [(use (match_operand:MODEF 0 "register_operand" ""))
17035 (use (match_operand:MODEF 1 "general_operand" ""))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038 || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations && !optimize_size"
17041 rtx op0 = gen_reg_rtx (XFmode);
17042 rtx op1 = gen_reg_rtx (XFmode);
17044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17045 emit_insn (gen_acosxf2 (op0, op1));
17046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17050 (define_insn "fyl2xxf3_i387"
17051 [(set (match_operand:XF 0 "register_operand" "=f")
17052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17053 (match_operand:XF 2 "register_operand" "u")]
17055 (clobber (match_scratch:XF 3 "=2"))]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations"
17059 [(set_attr "type" "fpspc")
17060 (set_attr "mode" "XF")])
17062 (define_insn "fyl2x_extend<mode>xf3_i387"
17063 [(set (match_operand:XF 0 "register_operand" "=f")
17064 (unspec:XF [(float_extend:XF
17065 (match_operand:MODEF 1 "register_operand" "0"))
17066 (match_operand:XF 2 "register_operand" "u")]
17068 (clobber (match_scratch:XF 3 "=2"))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071 || TARGET_MIX_SSE_I387)
17072 && flag_unsafe_math_optimizations"
17074 [(set_attr "type" "fpspc")
17075 (set_attr "mode" "XF")])
17077 (define_expand "logxf2"
17078 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17079 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17080 (match_dup 2)] UNSPEC_FYL2X))
17081 (clobber (match_scratch:XF 3 ""))])]
17082 "TARGET_USE_FANCY_MATH_387
17083 && flag_unsafe_math_optimizations"
17085 operands[2] = gen_reg_rtx (XFmode);
17086 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17089 (define_expand "log<mode>2"
17090 [(use (match_operand:MODEF 0 "register_operand" ""))
17091 (use (match_operand:MODEF 1 "register_operand" ""))]
17092 "TARGET_USE_FANCY_MATH_387
17093 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17094 || TARGET_MIX_SSE_I387)
17095 && flag_unsafe_math_optimizations"
17097 rtx op0 = gen_reg_rtx (XFmode);
17099 rtx op2 = gen_reg_rtx (XFmode);
17100 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17102 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17107 (define_expand "log10xf2"
17108 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17109 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17110 (match_dup 2)] UNSPEC_FYL2X))
17111 (clobber (match_scratch:XF 3 ""))])]
17112 "TARGET_USE_FANCY_MATH_387
17113 && flag_unsafe_math_optimizations"
17115 operands[2] = gen_reg_rtx (XFmode);
17116 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17119 (define_expand "log10<mode>2"
17120 [(use (match_operand:MODEF 0 "register_operand" ""))
17121 (use (match_operand:MODEF 1 "register_operand" ""))]
17122 "TARGET_USE_FANCY_MATH_387
17123 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17124 || TARGET_MIX_SSE_I387)
17125 && flag_unsafe_math_optimizations"
17127 rtx op0 = gen_reg_rtx (XFmode);
17129 rtx op2 = gen_reg_rtx (XFmode);
17130 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17132 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17133 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17137 (define_expand "log2xf2"
17138 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17139 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17140 (match_dup 2)] UNSPEC_FYL2X))
17141 (clobber (match_scratch:XF 3 ""))])]
17142 "TARGET_USE_FANCY_MATH_387
17143 && flag_unsafe_math_optimizations"
17145 operands[2] = gen_reg_rtx (XFmode);
17146 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17149 (define_expand "log2<mode>2"
17150 [(use (match_operand:MODEF 0 "register_operand" ""))
17151 (use (match_operand:MODEF 1 "register_operand" ""))]
17152 "TARGET_USE_FANCY_MATH_387
17153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17154 || TARGET_MIX_SSE_I387)
17155 && flag_unsafe_math_optimizations"
17157 rtx op0 = gen_reg_rtx (XFmode);
17159 rtx op2 = gen_reg_rtx (XFmode);
17160 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17162 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17163 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17167 (define_insn "fyl2xp1xf3_i387"
17168 [(set (match_operand:XF 0 "register_operand" "=f")
17169 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17170 (match_operand:XF 2 "register_operand" "u")]
17172 (clobber (match_scratch:XF 3 "=2"))]
17173 "TARGET_USE_FANCY_MATH_387
17174 && flag_unsafe_math_optimizations"
17176 [(set_attr "type" "fpspc")
17177 (set_attr "mode" "XF")])
17179 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17180 [(set (match_operand:XF 0 "register_operand" "=f")
17181 (unspec:XF [(float_extend:XF
17182 (match_operand:MODEF 1 "register_operand" "0"))
17183 (match_operand:XF 2 "register_operand" "u")]
17185 (clobber (match_scratch:XF 3 "=2"))]
17186 "TARGET_USE_FANCY_MATH_387
17187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17188 || TARGET_MIX_SSE_I387)
17189 && flag_unsafe_math_optimizations"
17191 [(set_attr "type" "fpspc")
17192 (set_attr "mode" "XF")])
17194 (define_expand "log1pxf2"
17195 [(use (match_operand:XF 0 "register_operand" ""))
17196 (use (match_operand:XF 1 "register_operand" ""))]
17197 "TARGET_USE_FANCY_MATH_387
17198 && flag_unsafe_math_optimizations && !optimize_size"
17200 ix86_emit_i387_log1p (operands[0], operands[1]);
17204 (define_expand "log1p<mode>2"
17205 [(use (match_operand:MODEF 0 "register_operand" ""))
17206 (use (match_operand:MODEF 1 "register_operand" ""))]
17207 "TARGET_USE_FANCY_MATH_387
17208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17209 || TARGET_MIX_SSE_I387)
17210 && flag_unsafe_math_optimizations && !optimize_size"
17212 rtx op0 = gen_reg_rtx (XFmode);
17214 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17216 ix86_emit_i387_log1p (op0, operands[1]);
17217 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17221 (define_insn "fxtractxf3_i387"
17222 [(set (match_operand:XF 0 "register_operand" "=f")
17223 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17224 UNSPEC_XTRACT_FRACT))
17225 (set (match_operand:XF 1 "register_operand" "=u")
17226 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17227 "TARGET_USE_FANCY_MATH_387
17228 && flag_unsafe_math_optimizations"
17230 [(set_attr "type" "fpspc")
17231 (set_attr "mode" "XF")])
17233 (define_insn "fxtract_extend<mode>xf3_i387"
17234 [(set (match_operand:XF 0 "register_operand" "=f")
17235 (unspec:XF [(float_extend:XF
17236 (match_operand:MODEF 2 "register_operand" "0"))]
17237 UNSPEC_XTRACT_FRACT))
17238 (set (match_operand:XF 1 "register_operand" "=u")
17239 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17240 "TARGET_USE_FANCY_MATH_387
17241 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17242 || TARGET_MIX_SSE_I387)
17243 && flag_unsafe_math_optimizations"
17245 [(set_attr "type" "fpspc")
17246 (set_attr "mode" "XF")])
17248 (define_expand "logbxf2"
17249 [(parallel [(set (match_dup 2)
17250 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17251 UNSPEC_XTRACT_FRACT))
17252 (set (match_operand:XF 0 "register_operand" "")
17253 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17254 "TARGET_USE_FANCY_MATH_387
17255 && flag_unsafe_math_optimizations"
17257 operands[2] = gen_reg_rtx (XFmode);
17260 (define_expand "logb<mode>2"
17261 [(use (match_operand:MODEF 0 "register_operand" ""))
17262 (use (match_operand:MODEF 1 "register_operand" ""))]
17263 "TARGET_USE_FANCY_MATH_387
17264 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17265 || TARGET_MIX_SSE_I387)
17266 && flag_unsafe_math_optimizations"
17268 rtx op0 = gen_reg_rtx (XFmode);
17269 rtx op1 = gen_reg_rtx (XFmode);
17271 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17272 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17276 (define_expand "ilogbxf2"
17277 [(use (match_operand:SI 0 "register_operand" ""))
17278 (use (match_operand:XF 1 "register_operand" ""))]
17279 "TARGET_USE_FANCY_MATH_387
17280 && flag_unsafe_math_optimizations && !optimize_size"
17282 rtx op0 = gen_reg_rtx (XFmode);
17283 rtx op1 = gen_reg_rtx (XFmode);
17285 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17286 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17290 (define_expand "ilogb<mode>2"
17291 [(use (match_operand:SI 0 "register_operand" ""))
17292 (use (match_operand:MODEF 1 "register_operand" ""))]
17293 "TARGET_USE_FANCY_MATH_387
17294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17295 || TARGET_MIX_SSE_I387)
17296 && flag_unsafe_math_optimizations && !optimize_size"
17298 rtx op0 = gen_reg_rtx (XFmode);
17299 rtx op1 = gen_reg_rtx (XFmode);
17301 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17302 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17306 (define_insn "*f2xm1xf2_i387"
17307 [(set (match_operand:XF 0 "register_operand" "=f")
17308 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations"
17313 [(set_attr "type" "fpspc")
17314 (set_attr "mode" "XF")])
17316 (define_insn "*fscalexf4_i387"
17317 [(set (match_operand:XF 0 "register_operand" "=f")
17318 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17319 (match_operand:XF 3 "register_operand" "1")]
17320 UNSPEC_FSCALE_FRACT))
17321 (set (match_operand:XF 1 "register_operand" "=u")
17322 (unspec:XF [(match_dup 2) (match_dup 3)]
17323 UNSPEC_FSCALE_EXP))]
17324 "TARGET_USE_FANCY_MATH_387
17325 && flag_unsafe_math_optimizations"
17327 [(set_attr "type" "fpspc")
17328 (set_attr "mode" "XF")])
17330 (define_expand "expNcorexf3"
17331 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17332 (match_operand:XF 2 "register_operand" "")))
17333 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17334 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17335 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17336 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17337 (parallel [(set (match_operand:XF 0 "register_operand" "")
17338 (unspec:XF [(match_dup 8) (match_dup 4)]
17339 UNSPEC_FSCALE_FRACT))
17341 (unspec:XF [(match_dup 8) (match_dup 4)]
17342 UNSPEC_FSCALE_EXP))])]
17343 "TARGET_USE_FANCY_MATH_387
17344 && flag_unsafe_math_optimizations && !optimize_size"
17348 for (i = 3; i < 10; i++)
17349 operands[i] = gen_reg_rtx (XFmode);
17351 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17354 (define_expand "expxf2"
17355 [(use (match_operand:XF 0 "register_operand" ""))
17356 (use (match_operand:XF 1 "register_operand" ""))]
17357 "TARGET_USE_FANCY_MATH_387
17358 && flag_unsafe_math_optimizations && !optimize_size"
17360 rtx op2 = gen_reg_rtx (XFmode);
17361 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17363 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17367 (define_expand "exp<mode>2"
17368 [(use (match_operand:MODEF 0 "register_operand" ""))
17369 (use (match_operand:MODEF 1 "general_operand" ""))]
17370 "TARGET_USE_FANCY_MATH_387
17371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17372 || TARGET_MIX_SSE_I387)
17373 && flag_unsafe_math_optimizations && !optimize_size"
17375 rtx op0 = gen_reg_rtx (XFmode);
17376 rtx op1 = gen_reg_rtx (XFmode);
17378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17379 emit_insn (gen_expxf2 (op0, op1));
17380 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17384 (define_expand "exp10xf2"
17385 [(use (match_operand:XF 0 "register_operand" ""))
17386 (use (match_operand:XF 1 "register_operand" ""))]
17387 "TARGET_USE_FANCY_MATH_387
17388 && flag_unsafe_math_optimizations && !optimize_size"
17390 rtx op2 = gen_reg_rtx (XFmode);
17391 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17393 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17397 (define_expand "exp10<mode>2"
17398 [(use (match_operand:MODEF 0 "register_operand" ""))
17399 (use (match_operand:MODEF 1 "general_operand" ""))]
17400 "TARGET_USE_FANCY_MATH_387
17401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17402 || TARGET_MIX_SSE_I387)
17403 && flag_unsafe_math_optimizations && !optimize_size"
17405 rtx op0 = gen_reg_rtx (XFmode);
17406 rtx op1 = gen_reg_rtx (XFmode);
17408 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17409 emit_insn (gen_exp10xf2 (op0, op1));
17410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17414 (define_expand "exp2xf2"
17415 [(use (match_operand:XF 0 "register_operand" ""))
17416 (use (match_operand:XF 1 "register_operand" ""))]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations && !optimize_size"
17420 rtx op2 = gen_reg_rtx (XFmode);
17421 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17423 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17427 (define_expand "exp2<mode>2"
17428 [(use (match_operand:MODEF 0 "register_operand" ""))
17429 (use (match_operand:MODEF 1 "general_operand" ""))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17432 || TARGET_MIX_SSE_I387)
17433 && flag_unsafe_math_optimizations && !optimize_size"
17435 rtx op0 = gen_reg_rtx (XFmode);
17436 rtx op1 = gen_reg_rtx (XFmode);
17438 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17439 emit_insn (gen_exp2xf2 (op0, op1));
17440 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17444 (define_expand "expm1xf2"
17445 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17447 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17448 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17449 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17450 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17451 (parallel [(set (match_dup 7)
17452 (unspec:XF [(match_dup 6) (match_dup 4)]
17453 UNSPEC_FSCALE_FRACT))
17455 (unspec:XF [(match_dup 6) (match_dup 4)]
17456 UNSPEC_FSCALE_EXP))])
17457 (parallel [(set (match_dup 10)
17458 (unspec:XF [(match_dup 9) (match_dup 8)]
17459 UNSPEC_FSCALE_FRACT))
17460 (set (match_dup 11)
17461 (unspec:XF [(match_dup 9) (match_dup 8)]
17462 UNSPEC_FSCALE_EXP))])
17463 (set (match_dup 12) (minus:XF (match_dup 10)
17464 (float_extend:XF (match_dup 13))))
17465 (set (match_operand:XF 0 "register_operand" "")
17466 (plus:XF (match_dup 12) (match_dup 7)))]
17467 "TARGET_USE_FANCY_MATH_387
17468 && flag_unsafe_math_optimizations && !optimize_size"
17472 for (i = 2; i < 13; i++)
17473 operands[i] = gen_reg_rtx (XFmode);
17476 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17478 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17481 (define_expand "expm1<mode>2"
17482 [(use (match_operand:MODEF 0 "register_operand" ""))
17483 (use (match_operand:MODEF 1 "general_operand" ""))]
17484 "TARGET_USE_FANCY_MATH_387
17485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17486 || TARGET_MIX_SSE_I387)
17487 && flag_unsafe_math_optimizations && !optimize_size"
17489 rtx op0 = gen_reg_rtx (XFmode);
17490 rtx op1 = gen_reg_rtx (XFmode);
17492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17493 emit_insn (gen_expm1xf2 (op0, op1));
17494 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17498 (define_expand "ldexpxf3"
17499 [(set (match_dup 3)
17500 (float:XF (match_operand:SI 2 "register_operand" "")))
17501 (parallel [(set (match_operand:XF 0 " register_operand" "")
17502 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17504 UNSPEC_FSCALE_FRACT))
17506 (unspec:XF [(match_dup 1) (match_dup 3)]
17507 UNSPEC_FSCALE_EXP))])]
17508 "TARGET_USE_FANCY_MATH_387
17509 && flag_unsafe_math_optimizations && !optimize_size"
17511 operands[3] = gen_reg_rtx (XFmode);
17512 operands[4] = gen_reg_rtx (XFmode);
17515 (define_expand "ldexp<mode>3"
17516 [(use (match_operand:MODEF 0 "register_operand" ""))
17517 (use (match_operand:MODEF 1 "general_operand" ""))
17518 (use (match_operand:SI 2 "register_operand" ""))]
17519 "TARGET_USE_FANCY_MATH_387
17520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17521 || TARGET_MIX_SSE_I387)
17522 && flag_unsafe_math_optimizations && !optimize_size"
17524 rtx op0 = gen_reg_rtx (XFmode);
17525 rtx op1 = gen_reg_rtx (XFmode);
17527 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17528 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17529 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17533 (define_expand "scalbxf3"
17534 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17535 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17536 (match_operand:XF 2 "register_operand" "")]
17537 UNSPEC_FSCALE_FRACT))
17539 (unspec:XF [(match_dup 1) (match_dup 2)]
17540 UNSPEC_FSCALE_EXP))])]
17541 "TARGET_USE_FANCY_MATH_387
17542 && flag_unsafe_math_optimizations && !optimize_size"
17544 operands[3] = gen_reg_rtx (XFmode);
17547 (define_expand "scalb<mode>3"
17548 [(use (match_operand:MODEF 0 "register_operand" ""))
17549 (use (match_operand:MODEF 1 "general_operand" ""))
17550 (use (match_operand:MODEF 2 "register_operand" ""))]
17551 "TARGET_USE_FANCY_MATH_387
17552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17553 || TARGET_MIX_SSE_I387)
17554 && flag_unsafe_math_optimizations && !optimize_size"
17556 rtx op0 = gen_reg_rtx (XFmode);
17557 rtx op1 = gen_reg_rtx (XFmode);
17558 rtx op2 = gen_reg_rtx (XFmode);
17560 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17561 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17562 emit_insn (gen_scalbxf3 (op0, op1, op2));
17563 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17568 (define_insn "sse4_1_round<mode>2"
17569 [(set (match_operand:MODEF 0 "register_operand" "=x")
17570 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17571 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17574 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17575 [(set_attr "type" "ssecvt")
17576 (set_attr "prefix_extra" "1")
17577 (set_attr "mode" "<MODE>")])
17579 (define_insn "rintxf2"
17580 [(set (match_operand:XF 0 "register_operand" "=f")
17581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17583 "TARGET_USE_FANCY_MATH_387
17584 && flag_unsafe_math_optimizations"
17586 [(set_attr "type" "fpspc")
17587 (set_attr "mode" "XF")])
17589 (define_expand "rint<mode>2"
17590 [(use (match_operand:MODEF 0 "register_operand" ""))
17591 (use (match_operand:MODEF 1 "register_operand" ""))]
17592 "(TARGET_USE_FANCY_MATH_387
17593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17594 || TARGET_MIX_SSE_I387)
17595 && flag_unsafe_math_optimizations)
17596 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17597 && !flag_trapping_math
17598 && (TARGET_ROUND || !optimize_size))"
17600 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17601 && !flag_trapping_math
17602 && (TARGET_ROUND || !optimize_size))
17605 emit_insn (gen_sse4_1_round<mode>2
17606 (operands[0], operands[1], GEN_INT (0x04)));
17608 ix86_expand_rint (operand0, operand1);
17612 rtx op0 = gen_reg_rtx (XFmode);
17613 rtx op1 = gen_reg_rtx (XFmode);
17615 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17616 emit_insn (gen_rintxf2 (op0, op1));
17618 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17623 (define_expand "round<mode>2"
17624 [(match_operand:MODEF 0 "register_operand" "")
17625 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17626 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17627 && !flag_trapping_math && !flag_rounding_math
17630 if (TARGET_64BIT || (<MODE>mode != DFmode))
17631 ix86_expand_round (operand0, operand1);
17633 ix86_expand_rounddf_32 (operand0, operand1);
17637 (define_insn_and_split "*fistdi2_1"
17638 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17639 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17641 "TARGET_USE_FANCY_MATH_387
17642 && !(reload_completed || reload_in_progress)"
17647 if (memory_operand (operands[0], VOIDmode))
17648 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17651 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17652 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17657 [(set_attr "type" "fpspc")
17658 (set_attr "mode" "DI")])
17660 (define_insn "fistdi2"
17661 [(set (match_operand:DI 0 "memory_operand" "=m")
17662 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17664 (clobber (match_scratch:XF 2 "=&1f"))]
17665 "TARGET_USE_FANCY_MATH_387"
17666 "* return output_fix_trunc (insn, operands, 0);"
17667 [(set_attr "type" "fpspc")
17668 (set_attr "mode" "DI")])
17670 (define_insn "fistdi2_with_temp"
17671 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17672 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17674 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17675 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17676 "TARGET_USE_FANCY_MATH_387"
17678 [(set_attr "type" "fpspc")
17679 (set_attr "mode" "DI")])
17682 [(set (match_operand:DI 0 "register_operand" "")
17683 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17685 (clobber (match_operand:DI 2 "memory_operand" ""))
17686 (clobber (match_scratch 3 ""))]
17688 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17689 (clobber (match_dup 3))])
17690 (set (match_dup 0) (match_dup 2))]
17694 [(set (match_operand:DI 0 "memory_operand" "")
17695 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17697 (clobber (match_operand:DI 2 "memory_operand" ""))
17698 (clobber (match_scratch 3 ""))]
17700 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17701 (clobber (match_dup 3))])]
17704 (define_insn_and_split "*fist<mode>2_1"
17705 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17706 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17708 "TARGET_USE_FANCY_MATH_387
17709 && !(reload_completed || reload_in_progress)"
17714 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17715 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17719 [(set_attr "type" "fpspc")
17720 (set_attr "mode" "<MODE>")])
17722 (define_insn "fist<mode>2"
17723 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17724 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17726 "TARGET_USE_FANCY_MATH_387"
17727 "* return output_fix_trunc (insn, operands, 0);"
17728 [(set_attr "type" "fpspc")
17729 (set_attr "mode" "<MODE>")])
17731 (define_insn "fist<mode>2_with_temp"
17732 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17733 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17735 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17736 "TARGET_USE_FANCY_MATH_387"
17738 [(set_attr "type" "fpspc")
17739 (set_attr "mode" "<MODE>")])
17742 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17743 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17745 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17747 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17748 (set (match_dup 0) (match_dup 2))]
17752 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17753 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17755 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17757 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17760 (define_expand "lrintxf<mode>2"
17761 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17762 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17764 "TARGET_USE_FANCY_MATH_387"
17767 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17768 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17769 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17770 UNSPEC_FIX_NOTRUNC))]
17771 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17772 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17775 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17776 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17777 (match_operand:MODEF 1 "register_operand" "")]
17778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17779 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17780 && !flag_trapping_math && !flag_rounding_math
17783 ix86_expand_lround (operand0, operand1);
17787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17788 (define_insn_and_split "frndintxf2_floor"
17789 [(set (match_operand:XF 0 "register_operand" "")
17790 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17791 UNSPEC_FRNDINT_FLOOR))
17792 (clobber (reg:CC FLAGS_REG))]
17793 "TARGET_USE_FANCY_MATH_387
17794 && flag_unsafe_math_optimizations
17795 && !(reload_completed || reload_in_progress)"
17800 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17805 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17806 operands[2], operands[3]));
17809 [(set_attr "type" "frndint")
17810 (set_attr "i387_cw" "floor")
17811 (set_attr "mode" "XF")])
17813 (define_insn "frndintxf2_floor_i387"
17814 [(set (match_operand:XF 0 "register_operand" "=f")
17815 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17816 UNSPEC_FRNDINT_FLOOR))
17817 (use (match_operand:HI 2 "memory_operand" "m"))
17818 (use (match_operand:HI 3 "memory_operand" "m"))]
17819 "TARGET_USE_FANCY_MATH_387
17820 && flag_unsafe_math_optimizations"
17821 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17822 [(set_attr "type" "frndint")
17823 (set_attr "i387_cw" "floor")
17824 (set_attr "mode" "XF")])
17826 (define_expand "floorxf2"
17827 [(use (match_operand:XF 0 "register_operand" ""))
17828 (use (match_operand:XF 1 "register_operand" ""))]
17829 "TARGET_USE_FANCY_MATH_387
17830 && flag_unsafe_math_optimizations && !optimize_size"
17832 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17836 (define_expand "floor<mode>2"
17837 [(use (match_operand:MODEF 0 "register_operand" ""))
17838 (use (match_operand:MODEF 1 "register_operand" ""))]
17839 "(TARGET_USE_FANCY_MATH_387
17840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17841 || TARGET_MIX_SSE_I387)
17842 && flag_unsafe_math_optimizations && !optimize_size)
17843 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17844 && !flag_trapping_math
17845 && (TARGET_ROUND || !optimize_size))"
17847 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17848 && !flag_trapping_math
17849 && (TARGET_ROUND || !optimize_size))
17852 emit_insn (gen_sse4_1_round<mode>2
17853 (operands[0], operands[1], GEN_INT (0x01)));
17854 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17855 ix86_expand_floorceil (operand0, operand1, true);
17857 ix86_expand_floorceildf_32 (operand0, operand1, true);
17861 rtx op0 = gen_reg_rtx (XFmode);
17862 rtx op1 = gen_reg_rtx (XFmode);
17864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17865 emit_insn (gen_frndintxf2_floor (op0, op1));
17867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17872 (define_insn_and_split "*fist<mode>2_floor_1"
17873 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17874 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17875 UNSPEC_FIST_FLOOR))
17876 (clobber (reg:CC FLAGS_REG))]
17877 "TARGET_USE_FANCY_MATH_387
17878 && flag_unsafe_math_optimizations
17879 && !(reload_completed || reload_in_progress)"
17884 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17886 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17887 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17888 if (memory_operand (operands[0], VOIDmode))
17889 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17890 operands[2], operands[3]));
17893 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17894 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17895 operands[2], operands[3],
17900 [(set_attr "type" "fistp")
17901 (set_attr "i387_cw" "floor")
17902 (set_attr "mode" "<MODE>")])
17904 (define_insn "fistdi2_floor"
17905 [(set (match_operand:DI 0 "memory_operand" "=m")
17906 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17907 UNSPEC_FIST_FLOOR))
17908 (use (match_operand:HI 2 "memory_operand" "m"))
17909 (use (match_operand:HI 3 "memory_operand" "m"))
17910 (clobber (match_scratch:XF 4 "=&1f"))]
17911 "TARGET_USE_FANCY_MATH_387
17912 && flag_unsafe_math_optimizations"
17913 "* return output_fix_trunc (insn, operands, 0);"
17914 [(set_attr "type" "fistp")
17915 (set_attr "i387_cw" "floor")
17916 (set_attr "mode" "DI")])
17918 (define_insn "fistdi2_floor_with_temp"
17919 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17920 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17921 UNSPEC_FIST_FLOOR))
17922 (use (match_operand:HI 2 "memory_operand" "m,m"))
17923 (use (match_operand:HI 3 "memory_operand" "m,m"))
17924 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17925 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17926 "TARGET_USE_FANCY_MATH_387
17927 && flag_unsafe_math_optimizations"
17929 [(set_attr "type" "fistp")
17930 (set_attr "i387_cw" "floor")
17931 (set_attr "mode" "DI")])
17934 [(set (match_operand:DI 0 "register_operand" "")
17935 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17936 UNSPEC_FIST_FLOOR))
17937 (use (match_operand:HI 2 "memory_operand" ""))
17938 (use (match_operand:HI 3 "memory_operand" ""))
17939 (clobber (match_operand:DI 4 "memory_operand" ""))
17940 (clobber (match_scratch 5 ""))]
17942 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17943 (use (match_dup 2))
17944 (use (match_dup 3))
17945 (clobber (match_dup 5))])
17946 (set (match_dup 0) (match_dup 4))]
17950 [(set (match_operand:DI 0 "memory_operand" "")
17951 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17952 UNSPEC_FIST_FLOOR))
17953 (use (match_operand:HI 2 "memory_operand" ""))
17954 (use (match_operand:HI 3 "memory_operand" ""))
17955 (clobber (match_operand:DI 4 "memory_operand" ""))
17956 (clobber (match_scratch 5 ""))]
17958 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17959 (use (match_dup 2))
17960 (use (match_dup 3))
17961 (clobber (match_dup 5))])]
17964 (define_insn "fist<mode>2_floor"
17965 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17966 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17967 UNSPEC_FIST_FLOOR))
17968 (use (match_operand:HI 2 "memory_operand" "m"))
17969 (use (match_operand:HI 3 "memory_operand" "m"))]
17970 "TARGET_USE_FANCY_MATH_387
17971 && flag_unsafe_math_optimizations"
17972 "* return output_fix_trunc (insn, operands, 0);"
17973 [(set_attr "type" "fistp")
17974 (set_attr "i387_cw" "floor")
17975 (set_attr "mode" "<MODE>")])
17977 (define_insn "fist<mode>2_floor_with_temp"
17978 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17979 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17980 UNSPEC_FIST_FLOOR))
17981 (use (match_operand:HI 2 "memory_operand" "m,m"))
17982 (use (match_operand:HI 3 "memory_operand" "m,m"))
17983 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17984 "TARGET_USE_FANCY_MATH_387
17985 && flag_unsafe_math_optimizations"
17987 [(set_attr "type" "fistp")
17988 (set_attr "i387_cw" "floor")
17989 (set_attr "mode" "<MODE>")])
17992 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17993 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17994 UNSPEC_FIST_FLOOR))
17995 (use (match_operand:HI 2 "memory_operand" ""))
17996 (use (match_operand:HI 3 "memory_operand" ""))
17997 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17999 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18000 UNSPEC_FIST_FLOOR))
18001 (use (match_dup 2))
18002 (use (match_dup 3))])
18003 (set (match_dup 0) (match_dup 4))]
18007 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18008 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18009 UNSPEC_FIST_FLOOR))
18010 (use (match_operand:HI 2 "memory_operand" ""))
18011 (use (match_operand:HI 3 "memory_operand" ""))
18012 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18014 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18015 UNSPEC_FIST_FLOOR))
18016 (use (match_dup 2))
18017 (use (match_dup 3))])]
18020 (define_expand "lfloorxf<mode>2"
18021 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18022 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18023 UNSPEC_FIST_FLOOR))
18024 (clobber (reg:CC FLAGS_REG))])]
18025 "TARGET_USE_FANCY_MATH_387
18026 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18027 && flag_unsafe_math_optimizations"
18030 (define_expand "lfloor<mode>di2"
18031 [(match_operand:DI 0 "nonimmediate_operand" "")
18032 (match_operand:MODEF 1 "register_operand" "")]
18033 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18034 && !flag_trapping_math
18037 ix86_expand_lfloorceil (operand0, operand1, true);
18041 (define_expand "lfloor<mode>si2"
18042 [(match_operand:SI 0 "nonimmediate_operand" "")
18043 (match_operand:MODEF 1 "register_operand" "")]
18044 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18045 && !flag_trapping_math
18046 && (!optimize_size || !TARGET_64BIT)"
18048 ix86_expand_lfloorceil (operand0, operand1, true);
18052 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18053 (define_insn_and_split "frndintxf2_ceil"
18054 [(set (match_operand:XF 0 "register_operand" "")
18055 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18056 UNSPEC_FRNDINT_CEIL))
18057 (clobber (reg:CC FLAGS_REG))]
18058 "TARGET_USE_FANCY_MATH_387
18059 && flag_unsafe_math_optimizations
18060 && !(reload_completed || reload_in_progress)"
18065 ix86_optimize_mode_switching[I387_CEIL] = 1;
18067 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18068 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18070 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18071 operands[2], operands[3]));
18074 [(set_attr "type" "frndint")
18075 (set_attr "i387_cw" "ceil")
18076 (set_attr "mode" "XF")])
18078 (define_insn "frndintxf2_ceil_i387"
18079 [(set (match_operand:XF 0 "register_operand" "=f")
18080 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18081 UNSPEC_FRNDINT_CEIL))
18082 (use (match_operand:HI 2 "memory_operand" "m"))
18083 (use (match_operand:HI 3 "memory_operand" "m"))]
18084 "TARGET_USE_FANCY_MATH_387
18085 && flag_unsafe_math_optimizations"
18086 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18087 [(set_attr "type" "frndint")
18088 (set_attr "i387_cw" "ceil")
18089 (set_attr "mode" "XF")])
18091 (define_expand "ceilxf2"
18092 [(use (match_operand:XF 0 "register_operand" ""))
18093 (use (match_operand:XF 1 "register_operand" ""))]
18094 "TARGET_USE_FANCY_MATH_387
18095 && flag_unsafe_math_optimizations && !optimize_size"
18097 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18101 (define_expand "ceil<mode>2"
18102 [(use (match_operand:MODEF 0 "register_operand" ""))
18103 (use (match_operand:MODEF 1 "register_operand" ""))]
18104 "(TARGET_USE_FANCY_MATH_387
18105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18106 || TARGET_MIX_SSE_I387)
18107 && flag_unsafe_math_optimizations && !optimize_size)
18108 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18109 && !flag_trapping_math
18110 && (TARGET_ROUND || !optimize_size))"
18112 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18113 && !flag_trapping_math
18114 && (TARGET_ROUND || !optimize_size))
18117 emit_insn (gen_sse4_1_round<mode>2
18118 (operands[0], operands[1], GEN_INT (0x02)));
18119 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18120 ix86_expand_floorceil (operand0, operand1, false);
18122 ix86_expand_floorceildf_32 (operand0, operand1, false);
18126 rtx op0 = gen_reg_rtx (XFmode);
18127 rtx op1 = gen_reg_rtx (XFmode);
18129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18130 emit_insn (gen_frndintxf2_ceil (op0, op1));
18132 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18137 (define_insn_and_split "*fist<mode>2_ceil_1"
18138 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18139 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18141 (clobber (reg:CC FLAGS_REG))]
18142 "TARGET_USE_FANCY_MATH_387
18143 && flag_unsafe_math_optimizations
18144 && !(reload_completed || reload_in_progress)"
18149 ix86_optimize_mode_switching[I387_CEIL] = 1;
18151 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18152 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18153 if (memory_operand (operands[0], VOIDmode))
18154 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18155 operands[2], operands[3]));
18158 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18159 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18160 operands[2], operands[3],
18165 [(set_attr "type" "fistp")
18166 (set_attr "i387_cw" "ceil")
18167 (set_attr "mode" "<MODE>")])
18169 (define_insn "fistdi2_ceil"
18170 [(set (match_operand:DI 0 "memory_operand" "=m")
18171 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18173 (use (match_operand:HI 2 "memory_operand" "m"))
18174 (use (match_operand:HI 3 "memory_operand" "m"))
18175 (clobber (match_scratch:XF 4 "=&1f"))]
18176 "TARGET_USE_FANCY_MATH_387
18177 && flag_unsafe_math_optimizations"
18178 "* return output_fix_trunc (insn, operands, 0);"
18179 [(set_attr "type" "fistp")
18180 (set_attr "i387_cw" "ceil")
18181 (set_attr "mode" "DI")])
18183 (define_insn "fistdi2_ceil_with_temp"
18184 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18185 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18187 (use (match_operand:HI 2 "memory_operand" "m,m"))
18188 (use (match_operand:HI 3 "memory_operand" "m,m"))
18189 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18190 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18191 "TARGET_USE_FANCY_MATH_387
18192 && flag_unsafe_math_optimizations"
18194 [(set_attr "type" "fistp")
18195 (set_attr "i387_cw" "ceil")
18196 (set_attr "mode" "DI")])
18199 [(set (match_operand:DI 0 "register_operand" "")
18200 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18202 (use (match_operand:HI 2 "memory_operand" ""))
18203 (use (match_operand:HI 3 "memory_operand" ""))
18204 (clobber (match_operand:DI 4 "memory_operand" ""))
18205 (clobber (match_scratch 5 ""))]
18207 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18208 (use (match_dup 2))
18209 (use (match_dup 3))
18210 (clobber (match_dup 5))])
18211 (set (match_dup 0) (match_dup 4))]
18215 [(set (match_operand:DI 0 "memory_operand" "")
18216 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18218 (use (match_operand:HI 2 "memory_operand" ""))
18219 (use (match_operand:HI 3 "memory_operand" ""))
18220 (clobber (match_operand:DI 4 "memory_operand" ""))
18221 (clobber (match_scratch 5 ""))]
18223 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18224 (use (match_dup 2))
18225 (use (match_dup 3))
18226 (clobber (match_dup 5))])]
18229 (define_insn "fist<mode>2_ceil"
18230 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18231 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18233 (use (match_operand:HI 2 "memory_operand" "m"))
18234 (use (match_operand:HI 3 "memory_operand" "m"))]
18235 "TARGET_USE_FANCY_MATH_387
18236 && flag_unsafe_math_optimizations"
18237 "* return output_fix_trunc (insn, operands, 0);"
18238 [(set_attr "type" "fistp")
18239 (set_attr "i387_cw" "ceil")
18240 (set_attr "mode" "<MODE>")])
18242 (define_insn "fist<mode>2_ceil_with_temp"
18243 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18244 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18246 (use (match_operand:HI 2 "memory_operand" "m,m"))
18247 (use (match_operand:HI 3 "memory_operand" "m,m"))
18248 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18249 "TARGET_USE_FANCY_MATH_387
18250 && flag_unsafe_math_optimizations"
18252 [(set_attr "type" "fistp")
18253 (set_attr "i387_cw" "ceil")
18254 (set_attr "mode" "<MODE>")])
18257 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18258 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18260 (use (match_operand:HI 2 "memory_operand" ""))
18261 (use (match_operand:HI 3 "memory_operand" ""))
18262 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18264 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18266 (use (match_dup 2))
18267 (use (match_dup 3))])
18268 (set (match_dup 0) (match_dup 4))]
18272 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18273 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18275 (use (match_operand:HI 2 "memory_operand" ""))
18276 (use (match_operand:HI 3 "memory_operand" ""))
18277 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18279 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18281 (use (match_dup 2))
18282 (use (match_dup 3))])]
18285 (define_expand "lceilxf<mode>2"
18286 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18287 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18289 (clobber (reg:CC FLAGS_REG))])]
18290 "TARGET_USE_FANCY_MATH_387
18291 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18292 && flag_unsafe_math_optimizations"
18295 (define_expand "lceil<mode>di2"
18296 [(match_operand:DI 0 "nonimmediate_operand" "")
18297 (match_operand:MODEF 1 "register_operand" "")]
18298 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18299 && !flag_trapping_math"
18301 ix86_expand_lfloorceil (operand0, operand1, false);
18305 (define_expand "lceil<mode>si2"
18306 [(match_operand:SI 0 "nonimmediate_operand" "")
18307 (match_operand:MODEF 1 "register_operand" "")]
18308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18309 && !flag_trapping_math"
18311 ix86_expand_lfloorceil (operand0, operand1, false);
18315 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18316 (define_insn_and_split "frndintxf2_trunc"
18317 [(set (match_operand:XF 0 "register_operand" "")
18318 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18319 UNSPEC_FRNDINT_TRUNC))
18320 (clobber (reg:CC FLAGS_REG))]
18321 "TARGET_USE_FANCY_MATH_387
18322 && flag_unsafe_math_optimizations
18323 && !(reload_completed || reload_in_progress)"
18328 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18330 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18331 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18333 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18334 operands[2], operands[3]));
18337 [(set_attr "type" "frndint")
18338 (set_attr "i387_cw" "trunc")
18339 (set_attr "mode" "XF")])
18341 (define_insn "frndintxf2_trunc_i387"
18342 [(set (match_operand:XF 0 "register_operand" "=f")
18343 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18344 UNSPEC_FRNDINT_TRUNC))
18345 (use (match_operand:HI 2 "memory_operand" "m"))
18346 (use (match_operand:HI 3 "memory_operand" "m"))]
18347 "TARGET_USE_FANCY_MATH_387
18348 && flag_unsafe_math_optimizations"
18349 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18350 [(set_attr "type" "frndint")
18351 (set_attr "i387_cw" "trunc")
18352 (set_attr "mode" "XF")])
18354 (define_expand "btruncxf2"
18355 [(use (match_operand:XF 0 "register_operand" ""))
18356 (use (match_operand:XF 1 "register_operand" ""))]
18357 "TARGET_USE_FANCY_MATH_387
18358 && flag_unsafe_math_optimizations && !optimize_size"
18360 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18364 (define_expand "btrunc<mode>2"
18365 [(use (match_operand:MODEF 0 "register_operand" ""))
18366 (use (match_operand:MODEF 1 "register_operand" ""))]
18367 "(TARGET_USE_FANCY_MATH_387
18368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18369 || TARGET_MIX_SSE_I387)
18370 && flag_unsafe_math_optimizations && !optimize_size)
18371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18372 && !flag_trapping_math
18373 && (TARGET_ROUND || !optimize_size))"
18375 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18376 && !flag_trapping_math
18377 && (TARGET_ROUND || !optimize_size))
18380 emit_insn (gen_sse4_1_round<mode>2
18381 (operands[0], operands[1], GEN_INT (0x03)));
18382 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18383 ix86_expand_trunc (operand0, operand1);
18385 ix86_expand_truncdf_32 (operand0, operand1);
18389 rtx op0 = gen_reg_rtx (XFmode);
18390 rtx op1 = gen_reg_rtx (XFmode);
18392 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18393 emit_insn (gen_frndintxf2_trunc (op0, op1));
18395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18400 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18401 (define_insn_and_split "frndintxf2_mask_pm"
18402 [(set (match_operand:XF 0 "register_operand" "")
18403 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18404 UNSPEC_FRNDINT_MASK_PM))
18405 (clobber (reg:CC FLAGS_REG))]
18406 "TARGET_USE_FANCY_MATH_387
18407 && flag_unsafe_math_optimizations
18408 && !(reload_completed || reload_in_progress)"
18413 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18415 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18416 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18418 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18419 operands[2], operands[3]));
18422 [(set_attr "type" "frndint")
18423 (set_attr "i387_cw" "mask_pm")
18424 (set_attr "mode" "XF")])
18426 (define_insn "frndintxf2_mask_pm_i387"
18427 [(set (match_operand:XF 0 "register_operand" "=f")
18428 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18429 UNSPEC_FRNDINT_MASK_PM))
18430 (use (match_operand:HI 2 "memory_operand" "m"))
18431 (use (match_operand:HI 3 "memory_operand" "m"))]
18432 "TARGET_USE_FANCY_MATH_387
18433 && flag_unsafe_math_optimizations"
18434 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18435 [(set_attr "type" "frndint")
18436 (set_attr "i387_cw" "mask_pm")
18437 (set_attr "mode" "XF")])
18439 (define_expand "nearbyintxf2"
18440 [(use (match_operand:XF 0 "register_operand" ""))
18441 (use (match_operand:XF 1 "register_operand" ""))]
18442 "TARGET_USE_FANCY_MATH_387
18443 && flag_unsafe_math_optimizations"
18445 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18450 (define_expand "nearbyint<mode>2"
18451 [(use (match_operand:MODEF 0 "register_operand" ""))
18452 (use (match_operand:MODEF 1 "register_operand" ""))]
18453 "TARGET_USE_FANCY_MATH_387
18454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18455 || TARGET_MIX_SSE_I387)
18456 && flag_unsafe_math_optimizations"
18458 rtx op0 = gen_reg_rtx (XFmode);
18459 rtx op1 = gen_reg_rtx (XFmode);
18461 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18462 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18468 (define_insn "fxam<mode>2_i387"
18469 [(set (match_operand:HI 0 "register_operand" "=a")
18471 [(match_operand:X87MODEF 1 "register_operand" "f")]
18473 "TARGET_USE_FANCY_MATH_387"
18474 "fxam\n\tfnstsw\t%0"
18475 [(set_attr "type" "multi")
18476 (set_attr "unit" "i387")
18477 (set_attr "mode" "<MODE>")])
18479 (define_expand "isinf<mode>2"
18480 [(use (match_operand:SI 0 "register_operand" ""))
18481 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18482 "TARGET_USE_FANCY_MATH_387
18483 && TARGET_C99_FUNCTIONS
18484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18486 rtx mask = GEN_INT (0x45);
18487 rtx val = GEN_INT (0x05);
18491 rtx scratch = gen_reg_rtx (HImode);
18492 rtx res = gen_reg_rtx (QImode);
18494 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18495 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18496 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18497 cond = gen_rtx_fmt_ee (EQ, QImode,
18498 gen_rtx_REG (CCmode, FLAGS_REG),
18500 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18501 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18505 (define_expand "signbit<mode>2"
18506 [(use (match_operand:SI 0 "register_operand" ""))
18507 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18508 "TARGET_USE_FANCY_MATH_387
18509 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18511 rtx mask = GEN_INT (0x0200);
18513 rtx scratch = gen_reg_rtx (HImode);
18515 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18516 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18520 ;; Block operation instructions
18522 (define_expand "movmemsi"
18523 [(use (match_operand:BLK 0 "memory_operand" ""))
18524 (use (match_operand:BLK 1 "memory_operand" ""))
18525 (use (match_operand:SI 2 "nonmemory_operand" ""))
18526 (use (match_operand:SI 3 "const_int_operand" ""))
18527 (use (match_operand:SI 4 "const_int_operand" ""))
18528 (use (match_operand:SI 5 "const_int_operand" ""))]
18531 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18532 operands[4], operands[5]))
18538 (define_expand "movmemdi"
18539 [(use (match_operand:BLK 0 "memory_operand" ""))
18540 (use (match_operand:BLK 1 "memory_operand" ""))
18541 (use (match_operand:DI 2 "nonmemory_operand" ""))
18542 (use (match_operand:DI 3 "const_int_operand" ""))
18543 (use (match_operand:SI 4 "const_int_operand" ""))
18544 (use (match_operand:SI 5 "const_int_operand" ""))]
18547 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18548 operands[4], operands[5]))
18554 ;; Most CPUs don't like single string operations
18555 ;; Handle this case here to simplify previous expander.
18557 (define_expand "strmov"
18558 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18559 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18560 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18561 (clobber (reg:CC FLAGS_REG))])
18562 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18563 (clobber (reg:CC FLAGS_REG))])]
18566 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18568 /* If .md ever supports :P for Pmode, these can be directly
18569 in the pattern above. */
18570 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18571 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18573 /* Can't use this if the user has appropriated esi or edi. */
18574 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18575 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18577 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18578 operands[2], operands[3],
18579 operands[5], operands[6]));
18583 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18586 (define_expand "strmov_singleop"
18587 [(parallel [(set (match_operand 1 "memory_operand" "")
18588 (match_operand 3 "memory_operand" ""))
18589 (set (match_operand 0 "register_operand" "")
18590 (match_operand 4 "" ""))
18591 (set (match_operand 2 "register_operand" "")
18592 (match_operand 5 "" ""))])]
18593 "TARGET_SINGLE_STRINGOP || optimize_size"
18596 (define_insn "*strmovdi_rex_1"
18597 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18598 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18599 (set (match_operand:DI 0 "register_operand" "=D")
18600 (plus:DI (match_dup 2)
18602 (set (match_operand:DI 1 "register_operand" "=S")
18603 (plus:DI (match_dup 3)
18605 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18607 [(set_attr "type" "str")
18608 (set_attr "mode" "DI")
18609 (set_attr "memory" "both")])
18611 (define_insn "*strmovsi_1"
18612 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18613 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18614 (set (match_operand:SI 0 "register_operand" "=D")
18615 (plus:SI (match_dup 2)
18617 (set (match_operand:SI 1 "register_operand" "=S")
18618 (plus:SI (match_dup 3)
18620 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18622 [(set_attr "type" "str")
18623 (set_attr "mode" "SI")
18624 (set_attr "memory" "both")])
18626 (define_insn "*strmovsi_rex_1"
18627 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18628 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18629 (set (match_operand:DI 0 "register_operand" "=D")
18630 (plus:DI (match_dup 2)
18632 (set (match_operand:DI 1 "register_operand" "=S")
18633 (plus:DI (match_dup 3)
18635 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18637 [(set_attr "type" "str")
18638 (set_attr "mode" "SI")
18639 (set_attr "memory" "both")])
18641 (define_insn "*strmovhi_1"
18642 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18643 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18644 (set (match_operand:SI 0 "register_operand" "=D")
18645 (plus:SI (match_dup 2)
18647 (set (match_operand:SI 1 "register_operand" "=S")
18648 (plus:SI (match_dup 3)
18650 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18652 [(set_attr "type" "str")
18653 (set_attr "memory" "both")
18654 (set_attr "mode" "HI")])
18656 (define_insn "*strmovhi_rex_1"
18657 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18658 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18659 (set (match_operand:DI 0 "register_operand" "=D")
18660 (plus:DI (match_dup 2)
18662 (set (match_operand:DI 1 "register_operand" "=S")
18663 (plus:DI (match_dup 3)
18665 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18667 [(set_attr "type" "str")
18668 (set_attr "memory" "both")
18669 (set_attr "mode" "HI")])
18671 (define_insn "*strmovqi_1"
18672 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18673 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18674 (set (match_operand:SI 0 "register_operand" "=D")
18675 (plus:SI (match_dup 2)
18677 (set (match_operand:SI 1 "register_operand" "=S")
18678 (plus:SI (match_dup 3)
18680 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18682 [(set_attr "type" "str")
18683 (set_attr "memory" "both")
18684 (set_attr "mode" "QI")])
18686 (define_insn "*strmovqi_rex_1"
18687 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18688 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18689 (set (match_operand:DI 0 "register_operand" "=D")
18690 (plus:DI (match_dup 2)
18692 (set (match_operand:DI 1 "register_operand" "=S")
18693 (plus:DI (match_dup 3)
18695 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18697 [(set_attr "type" "str")
18698 (set_attr "memory" "both")
18699 (set_attr "mode" "QI")])
18701 (define_expand "rep_mov"
18702 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18703 (set (match_operand 0 "register_operand" "")
18704 (match_operand 5 "" ""))
18705 (set (match_operand 2 "register_operand" "")
18706 (match_operand 6 "" ""))
18707 (set (match_operand 1 "memory_operand" "")
18708 (match_operand 3 "memory_operand" ""))
18709 (use (match_dup 4))])]
18713 (define_insn "*rep_movdi_rex64"
18714 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18715 (set (match_operand:DI 0 "register_operand" "=D")
18716 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18718 (match_operand:DI 3 "register_operand" "0")))
18719 (set (match_operand:DI 1 "register_operand" "=S")
18720 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18721 (match_operand:DI 4 "register_operand" "1")))
18722 (set (mem:BLK (match_dup 3))
18723 (mem:BLK (match_dup 4)))
18724 (use (match_dup 5))]
18727 [(set_attr "type" "str")
18728 (set_attr "prefix_rep" "1")
18729 (set_attr "memory" "both")
18730 (set_attr "mode" "DI")])
18732 (define_insn "*rep_movsi"
18733 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18734 (set (match_operand:SI 0 "register_operand" "=D")
18735 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18737 (match_operand:SI 3 "register_operand" "0")))
18738 (set (match_operand:SI 1 "register_operand" "=S")
18739 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18740 (match_operand:SI 4 "register_operand" "1")))
18741 (set (mem:BLK (match_dup 3))
18742 (mem:BLK (match_dup 4)))
18743 (use (match_dup 5))]
18746 [(set_attr "type" "str")
18747 (set_attr "prefix_rep" "1")
18748 (set_attr "memory" "both")
18749 (set_attr "mode" "SI")])
18751 (define_insn "*rep_movsi_rex64"
18752 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18753 (set (match_operand:DI 0 "register_operand" "=D")
18754 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18756 (match_operand:DI 3 "register_operand" "0")))
18757 (set (match_operand:DI 1 "register_operand" "=S")
18758 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18759 (match_operand:DI 4 "register_operand" "1")))
18760 (set (mem:BLK (match_dup 3))
18761 (mem:BLK (match_dup 4)))
18762 (use (match_dup 5))]
18765 [(set_attr "type" "str")
18766 (set_attr "prefix_rep" "1")
18767 (set_attr "memory" "both")
18768 (set_attr "mode" "SI")])
18770 (define_insn "*rep_movqi"
18771 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18772 (set (match_operand:SI 0 "register_operand" "=D")
18773 (plus:SI (match_operand:SI 3 "register_operand" "0")
18774 (match_operand:SI 5 "register_operand" "2")))
18775 (set (match_operand:SI 1 "register_operand" "=S")
18776 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18777 (set (mem:BLK (match_dup 3))
18778 (mem:BLK (match_dup 4)))
18779 (use (match_dup 5))]
18782 [(set_attr "type" "str")
18783 (set_attr "prefix_rep" "1")
18784 (set_attr "memory" "both")
18785 (set_attr "mode" "SI")])
18787 (define_insn "*rep_movqi_rex64"
18788 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18789 (set (match_operand:DI 0 "register_operand" "=D")
18790 (plus:DI (match_operand:DI 3 "register_operand" "0")
18791 (match_operand:DI 5 "register_operand" "2")))
18792 (set (match_operand:DI 1 "register_operand" "=S")
18793 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18794 (set (mem:BLK (match_dup 3))
18795 (mem:BLK (match_dup 4)))
18796 (use (match_dup 5))]
18799 [(set_attr "type" "str")
18800 (set_attr "prefix_rep" "1")
18801 (set_attr "memory" "both")
18802 (set_attr "mode" "SI")])
18804 (define_expand "setmemsi"
18805 [(use (match_operand:BLK 0 "memory_operand" ""))
18806 (use (match_operand:SI 1 "nonmemory_operand" ""))
18807 (use (match_operand 2 "const_int_operand" ""))
18808 (use (match_operand 3 "const_int_operand" ""))
18809 (use (match_operand:SI 4 "const_int_operand" ""))
18810 (use (match_operand:SI 5 "const_int_operand" ""))]
18813 if (ix86_expand_setmem (operands[0], operands[1],
18814 operands[2], operands[3],
18815 operands[4], operands[5]))
18821 (define_expand "setmemdi"
18822 [(use (match_operand:BLK 0 "memory_operand" ""))
18823 (use (match_operand:DI 1 "nonmemory_operand" ""))
18824 (use (match_operand 2 "const_int_operand" ""))
18825 (use (match_operand 3 "const_int_operand" ""))
18826 (use (match_operand 4 "const_int_operand" ""))
18827 (use (match_operand 5 "const_int_operand" ""))]
18830 if (ix86_expand_setmem (operands[0], operands[1],
18831 operands[2], operands[3],
18832 operands[4], operands[5]))
18838 ;; Most CPUs don't like single string operations
18839 ;; Handle this case here to simplify previous expander.
18841 (define_expand "strset"
18842 [(set (match_operand 1 "memory_operand" "")
18843 (match_operand 2 "register_operand" ""))
18844 (parallel [(set (match_operand 0 "register_operand" "")
18846 (clobber (reg:CC FLAGS_REG))])]
18849 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18850 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18852 /* If .md ever supports :P for Pmode, this can be directly
18853 in the pattern above. */
18854 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18855 GEN_INT (GET_MODE_SIZE (GET_MODE
18857 if (TARGET_SINGLE_STRINGOP || optimize_size)
18859 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18865 (define_expand "strset_singleop"
18866 [(parallel [(set (match_operand 1 "memory_operand" "")
18867 (match_operand 2 "register_operand" ""))
18868 (set (match_operand 0 "register_operand" "")
18869 (match_operand 3 "" ""))])]
18870 "TARGET_SINGLE_STRINGOP || optimize_size"
18873 (define_insn "*strsetdi_rex_1"
18874 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18875 (match_operand:DI 2 "register_operand" "a"))
18876 (set (match_operand:DI 0 "register_operand" "=D")
18877 (plus:DI (match_dup 1)
18879 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18881 [(set_attr "type" "str")
18882 (set_attr "memory" "store")
18883 (set_attr "mode" "DI")])
18885 (define_insn "*strsetsi_1"
18886 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18887 (match_operand:SI 2 "register_operand" "a"))
18888 (set (match_operand:SI 0 "register_operand" "=D")
18889 (plus:SI (match_dup 1)
18891 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18893 [(set_attr "type" "str")
18894 (set_attr "memory" "store")
18895 (set_attr "mode" "SI")])
18897 (define_insn "*strsetsi_rex_1"
18898 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18899 (match_operand:SI 2 "register_operand" "a"))
18900 (set (match_operand:DI 0 "register_operand" "=D")
18901 (plus:DI (match_dup 1)
18903 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18905 [(set_attr "type" "str")
18906 (set_attr "memory" "store")
18907 (set_attr "mode" "SI")])
18909 (define_insn "*strsethi_1"
18910 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18911 (match_operand:HI 2 "register_operand" "a"))
18912 (set (match_operand:SI 0 "register_operand" "=D")
18913 (plus:SI (match_dup 1)
18915 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18917 [(set_attr "type" "str")
18918 (set_attr "memory" "store")
18919 (set_attr "mode" "HI")])
18921 (define_insn "*strsethi_rex_1"
18922 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18923 (match_operand:HI 2 "register_operand" "a"))
18924 (set (match_operand:DI 0 "register_operand" "=D")
18925 (plus:DI (match_dup 1)
18927 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18929 [(set_attr "type" "str")
18930 (set_attr "memory" "store")
18931 (set_attr "mode" "HI")])
18933 (define_insn "*strsetqi_1"
18934 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18935 (match_operand:QI 2 "register_operand" "a"))
18936 (set (match_operand:SI 0 "register_operand" "=D")
18937 (plus:SI (match_dup 1)
18939 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18941 [(set_attr "type" "str")
18942 (set_attr "memory" "store")
18943 (set_attr "mode" "QI")])
18945 (define_insn "*strsetqi_rex_1"
18946 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18947 (match_operand:QI 2 "register_operand" "a"))
18948 (set (match_operand:DI 0 "register_operand" "=D")
18949 (plus:DI (match_dup 1)
18951 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18953 [(set_attr "type" "str")
18954 (set_attr "memory" "store")
18955 (set_attr "mode" "QI")])
18957 (define_expand "rep_stos"
18958 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18959 (set (match_operand 0 "register_operand" "")
18960 (match_operand 4 "" ""))
18961 (set (match_operand 2 "memory_operand" "") (const_int 0))
18962 (use (match_operand 3 "register_operand" ""))
18963 (use (match_dup 1))])]
18967 (define_insn "*rep_stosdi_rex64"
18968 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18969 (set (match_operand:DI 0 "register_operand" "=D")
18970 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18972 (match_operand:DI 3 "register_operand" "0")))
18973 (set (mem:BLK (match_dup 3))
18975 (use (match_operand:DI 2 "register_operand" "a"))
18976 (use (match_dup 4))]
18979 [(set_attr "type" "str")
18980 (set_attr "prefix_rep" "1")
18981 (set_attr "memory" "store")
18982 (set_attr "mode" "DI")])
18984 (define_insn "*rep_stossi"
18985 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18986 (set (match_operand:SI 0 "register_operand" "=D")
18987 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18989 (match_operand:SI 3 "register_operand" "0")))
18990 (set (mem:BLK (match_dup 3))
18992 (use (match_operand:SI 2 "register_operand" "a"))
18993 (use (match_dup 4))]
18996 [(set_attr "type" "str")
18997 (set_attr "prefix_rep" "1")
18998 (set_attr "memory" "store")
18999 (set_attr "mode" "SI")])
19001 (define_insn "*rep_stossi_rex64"
19002 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19003 (set (match_operand:DI 0 "register_operand" "=D")
19004 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19006 (match_operand:DI 3 "register_operand" "0")))
19007 (set (mem:BLK (match_dup 3))
19009 (use (match_operand:SI 2 "register_operand" "a"))
19010 (use (match_dup 4))]
19013 [(set_attr "type" "str")
19014 (set_attr "prefix_rep" "1")
19015 (set_attr "memory" "store")
19016 (set_attr "mode" "SI")])
19018 (define_insn "*rep_stosqi"
19019 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19020 (set (match_operand:SI 0 "register_operand" "=D")
19021 (plus:SI (match_operand:SI 3 "register_operand" "0")
19022 (match_operand:SI 4 "register_operand" "1")))
19023 (set (mem:BLK (match_dup 3))
19025 (use (match_operand:QI 2 "register_operand" "a"))
19026 (use (match_dup 4))]
19029 [(set_attr "type" "str")
19030 (set_attr "prefix_rep" "1")
19031 (set_attr "memory" "store")
19032 (set_attr "mode" "QI")])
19034 (define_insn "*rep_stosqi_rex64"
19035 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19036 (set (match_operand:DI 0 "register_operand" "=D")
19037 (plus:DI (match_operand:DI 3 "register_operand" "0")
19038 (match_operand:DI 4 "register_operand" "1")))
19039 (set (mem:BLK (match_dup 3))
19041 (use (match_operand:QI 2 "register_operand" "a"))
19042 (use (match_dup 4))]
19045 [(set_attr "type" "str")
19046 (set_attr "prefix_rep" "1")
19047 (set_attr "memory" "store")
19048 (set_attr "mode" "QI")])
19050 (define_expand "cmpstrnsi"
19051 [(set (match_operand:SI 0 "register_operand" "")
19052 (compare:SI (match_operand:BLK 1 "general_operand" "")
19053 (match_operand:BLK 2 "general_operand" "")))
19054 (use (match_operand 3 "general_operand" ""))
19055 (use (match_operand 4 "immediate_operand" ""))]
19056 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19058 rtx addr1, addr2, out, outlow, count, countreg, align;
19060 /* Can't use this if the user has appropriated esi or edi. */
19061 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19066 out = gen_reg_rtx (SImode);
19068 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19069 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19070 if (addr1 != XEXP (operands[1], 0))
19071 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19072 if (addr2 != XEXP (operands[2], 0))
19073 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19075 count = operands[3];
19076 countreg = ix86_zero_extend_to_Pmode (count);
19078 /* %%% Iff we are testing strict equality, we can use known alignment
19079 to good advantage. This may be possible with combine, particularly
19080 once cc0 is dead. */
19081 align = operands[4];
19083 if (CONST_INT_P (count))
19085 if (INTVAL (count) == 0)
19087 emit_move_insn (operands[0], const0_rtx);
19090 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19091 operands[1], operands[2]));
19096 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19098 emit_insn (gen_cmpsi_1 (countreg, countreg));
19099 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19100 operands[1], operands[2]));
19103 outlow = gen_lowpart (QImode, out);
19104 emit_insn (gen_cmpintqi (outlow));
19105 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19107 if (operands[0] != out)
19108 emit_move_insn (operands[0], out);
19113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19115 (define_expand "cmpintqi"
19116 [(set (match_dup 1)
19117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19120 (parallel [(set (match_operand:QI 0 "register_operand" "")
19121 (minus:QI (match_dup 1)
19123 (clobber (reg:CC FLAGS_REG))])]
19125 "operands[1] = gen_reg_rtx (QImode);
19126 operands[2] = gen_reg_rtx (QImode);")
19128 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19129 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19131 (define_expand "cmpstrnqi_nz_1"
19132 [(parallel [(set (reg:CC FLAGS_REG)
19133 (compare:CC (match_operand 4 "memory_operand" "")
19134 (match_operand 5 "memory_operand" "")))
19135 (use (match_operand 2 "register_operand" ""))
19136 (use (match_operand:SI 3 "immediate_operand" ""))
19137 (clobber (match_operand 0 "register_operand" ""))
19138 (clobber (match_operand 1 "register_operand" ""))
19139 (clobber (match_dup 2))])]
19143 (define_insn "*cmpstrnqi_nz_1"
19144 [(set (reg:CC FLAGS_REG)
19145 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19146 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19147 (use (match_operand:SI 6 "register_operand" "2"))
19148 (use (match_operand:SI 3 "immediate_operand" "i"))
19149 (clobber (match_operand:SI 0 "register_operand" "=S"))
19150 (clobber (match_operand:SI 1 "register_operand" "=D"))
19151 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19154 [(set_attr "type" "str")
19155 (set_attr "mode" "QI")
19156 (set_attr "prefix_rep" "1")])
19158 (define_insn "*cmpstrnqi_nz_rex_1"
19159 [(set (reg:CC FLAGS_REG)
19160 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19161 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19162 (use (match_operand:DI 6 "register_operand" "2"))
19163 (use (match_operand:SI 3 "immediate_operand" "i"))
19164 (clobber (match_operand:DI 0 "register_operand" "=S"))
19165 (clobber (match_operand:DI 1 "register_operand" "=D"))
19166 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19169 [(set_attr "type" "str")
19170 (set_attr "mode" "QI")
19171 (set_attr "prefix_rep" "1")])
19173 ;; The same, but the count is not known to not be zero.
19175 (define_expand "cmpstrnqi_1"
19176 [(parallel [(set (reg:CC FLAGS_REG)
19177 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19179 (compare:CC (match_operand 4 "memory_operand" "")
19180 (match_operand 5 "memory_operand" ""))
19182 (use (match_operand:SI 3 "immediate_operand" ""))
19183 (use (reg:CC FLAGS_REG))
19184 (clobber (match_operand 0 "register_operand" ""))
19185 (clobber (match_operand 1 "register_operand" ""))
19186 (clobber (match_dup 2))])]
19190 (define_insn "*cmpstrnqi_1"
19191 [(set (reg:CC FLAGS_REG)
19192 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19194 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19195 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19197 (use (match_operand:SI 3 "immediate_operand" "i"))
19198 (use (reg:CC FLAGS_REG))
19199 (clobber (match_operand:SI 0 "register_operand" "=S"))
19200 (clobber (match_operand:SI 1 "register_operand" "=D"))
19201 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19204 [(set_attr "type" "str")
19205 (set_attr "mode" "QI")
19206 (set_attr "prefix_rep" "1")])
19208 (define_insn "*cmpstrnqi_rex_1"
19209 [(set (reg:CC FLAGS_REG)
19210 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19212 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19213 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19215 (use (match_operand:SI 3 "immediate_operand" "i"))
19216 (use (reg:CC FLAGS_REG))
19217 (clobber (match_operand:DI 0 "register_operand" "=S"))
19218 (clobber (match_operand:DI 1 "register_operand" "=D"))
19219 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19222 [(set_attr "type" "str")
19223 (set_attr "mode" "QI")
19224 (set_attr "prefix_rep" "1")])
19226 (define_expand "strlensi"
19227 [(set (match_operand:SI 0 "register_operand" "")
19228 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19229 (match_operand:QI 2 "immediate_operand" "")
19230 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19233 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19239 (define_expand "strlendi"
19240 [(set (match_operand:DI 0 "register_operand" "")
19241 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19242 (match_operand:QI 2 "immediate_operand" "")
19243 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19246 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19252 (define_expand "strlenqi_1"
19253 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19254 (clobber (match_operand 1 "register_operand" ""))
19255 (clobber (reg:CC FLAGS_REG))])]
19259 (define_insn "*strlenqi_1"
19260 [(set (match_operand:SI 0 "register_operand" "=&c")
19261 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19262 (match_operand:QI 2 "register_operand" "a")
19263 (match_operand:SI 3 "immediate_operand" "i")
19264 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19265 (clobber (match_operand:SI 1 "register_operand" "=D"))
19266 (clobber (reg:CC FLAGS_REG))]
19269 [(set_attr "type" "str")
19270 (set_attr "mode" "QI")
19271 (set_attr "prefix_rep" "1")])
19273 (define_insn "*strlenqi_rex_1"
19274 [(set (match_operand:DI 0 "register_operand" "=&c")
19275 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19276 (match_operand:QI 2 "register_operand" "a")
19277 (match_operand:DI 3 "immediate_operand" "i")
19278 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19279 (clobber (match_operand:DI 1 "register_operand" "=D"))
19280 (clobber (reg:CC FLAGS_REG))]
19283 [(set_attr "type" "str")
19284 (set_attr "mode" "QI")
19285 (set_attr "prefix_rep" "1")])
19287 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19288 ;; handled in combine, but it is not currently up to the task.
19289 ;; When used for their truth value, the cmpstrn* expanders generate
19298 ;; The intermediate three instructions are unnecessary.
19300 ;; This one handles cmpstrn*_nz_1...
19303 (set (reg:CC FLAGS_REG)
19304 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19305 (mem:BLK (match_operand 5 "register_operand" ""))))
19306 (use (match_operand 6 "register_operand" ""))
19307 (use (match_operand:SI 3 "immediate_operand" ""))
19308 (clobber (match_operand 0 "register_operand" ""))
19309 (clobber (match_operand 1 "register_operand" ""))
19310 (clobber (match_operand 2 "register_operand" ""))])
19311 (set (match_operand:QI 7 "register_operand" "")
19312 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19313 (set (match_operand:QI 8 "register_operand" "")
19314 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19315 (set (reg FLAGS_REG)
19316 (compare (match_dup 7) (match_dup 8)))
19318 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19320 (set (reg:CC FLAGS_REG)
19321 (compare:CC (mem:BLK (match_dup 4))
19322 (mem:BLK (match_dup 5))))
19323 (use (match_dup 6))
19324 (use (match_dup 3))
19325 (clobber (match_dup 0))
19326 (clobber (match_dup 1))
19327 (clobber (match_dup 2))])]
19330 ;; ...and this one handles cmpstrn*_1.
19333 (set (reg:CC FLAGS_REG)
19334 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19336 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19337 (mem:BLK (match_operand 5 "register_operand" "")))
19339 (use (match_operand:SI 3 "immediate_operand" ""))
19340 (use (reg:CC FLAGS_REG))
19341 (clobber (match_operand 0 "register_operand" ""))
19342 (clobber (match_operand 1 "register_operand" ""))
19343 (clobber (match_operand 2 "register_operand" ""))])
19344 (set (match_operand:QI 7 "register_operand" "")
19345 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19346 (set (match_operand:QI 8 "register_operand" "")
19347 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19348 (set (reg FLAGS_REG)
19349 (compare (match_dup 7) (match_dup 8)))
19351 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19353 (set (reg:CC FLAGS_REG)
19354 (if_then_else:CC (ne (match_dup 6)
19356 (compare:CC (mem:BLK (match_dup 4))
19357 (mem:BLK (match_dup 5)))
19359 (use (match_dup 3))
19360 (use (reg:CC FLAGS_REG))
19361 (clobber (match_dup 0))
19362 (clobber (match_dup 1))
19363 (clobber (match_dup 2))])]
19368 ;; Conditional move instructions.
19370 (define_expand "movdicc"
19371 [(set (match_operand:DI 0 "register_operand" "")
19372 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19373 (match_operand:DI 2 "general_operand" "")
19374 (match_operand:DI 3 "general_operand" "")))]
19376 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19378 (define_insn "x86_movdicc_0_m1_rex64"
19379 [(set (match_operand:DI 0 "register_operand" "=r")
19380 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19383 (clobber (reg:CC FLAGS_REG))]
19386 ; Since we don't have the proper number of operands for an alu insn,
19387 ; fill in all the blanks.
19388 [(set_attr "type" "alu")
19389 (set_attr "pent_pair" "pu")
19390 (set_attr "memory" "none")
19391 (set_attr "imm_disp" "false")
19392 (set_attr "mode" "DI")
19393 (set_attr "length_immediate" "0")])
19395 (define_insn "*x86_movdicc_0_m1_se"
19396 [(set (match_operand:DI 0 "register_operand" "=r")
19397 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19400 (clobber (reg:CC FLAGS_REG))]
19403 [(set_attr "type" "alu")
19404 (set_attr "pent_pair" "pu")
19405 (set_attr "memory" "none")
19406 (set_attr "imm_disp" "false")
19407 (set_attr "mode" "DI")
19408 (set_attr "length_immediate" "0")])
19410 (define_insn "*movdicc_c_rex64"
19411 [(set (match_operand:DI 0 "register_operand" "=r,r")
19412 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19413 [(reg FLAGS_REG) (const_int 0)])
19414 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19415 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19416 "TARGET_64BIT && TARGET_CMOVE
19417 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19419 cmov%O2%C1\t{%2, %0|%0, %2}
19420 cmov%O2%c1\t{%3, %0|%0, %3}"
19421 [(set_attr "type" "icmov")
19422 (set_attr "mode" "DI")])
19424 (define_expand "movsicc"
19425 [(set (match_operand:SI 0 "register_operand" "")
19426 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19427 (match_operand:SI 2 "general_operand" "")
19428 (match_operand:SI 3 "general_operand" "")))]
19430 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19432 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19433 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19434 ;; So just document what we're doing explicitly.
19436 (define_insn "x86_movsicc_0_m1"
19437 [(set (match_operand:SI 0 "register_operand" "=r")
19438 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19441 (clobber (reg:CC FLAGS_REG))]
19444 ; Since we don't have the proper number of operands for an alu insn,
19445 ; fill in all the blanks.
19446 [(set_attr "type" "alu")
19447 (set_attr "pent_pair" "pu")
19448 (set_attr "memory" "none")
19449 (set_attr "imm_disp" "false")
19450 (set_attr "mode" "SI")
19451 (set_attr "length_immediate" "0")])
19453 (define_insn "*x86_movsicc_0_m1_se"
19454 [(set (match_operand:SI 0 "register_operand" "=r")
19455 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19458 (clobber (reg:CC FLAGS_REG))]
19461 [(set_attr "type" "alu")
19462 (set_attr "pent_pair" "pu")
19463 (set_attr "memory" "none")
19464 (set_attr "imm_disp" "false")
19465 (set_attr "mode" "SI")
19466 (set_attr "length_immediate" "0")])
19468 (define_insn "*movsicc_noc"
19469 [(set (match_operand:SI 0 "register_operand" "=r,r")
19470 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19471 [(reg FLAGS_REG) (const_int 0)])
19472 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19473 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19475 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19477 cmov%O2%C1\t{%2, %0|%0, %2}
19478 cmov%O2%c1\t{%3, %0|%0, %3}"
19479 [(set_attr "type" "icmov")
19480 (set_attr "mode" "SI")])
19482 (define_expand "movhicc"
19483 [(set (match_operand:HI 0 "register_operand" "")
19484 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19485 (match_operand:HI 2 "general_operand" "")
19486 (match_operand:HI 3 "general_operand" "")))]
19487 "TARGET_HIMODE_MATH"
19488 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19490 (define_insn "*movhicc_noc"
19491 [(set (match_operand:HI 0 "register_operand" "=r,r")
19492 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19493 [(reg FLAGS_REG) (const_int 0)])
19494 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19495 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19497 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19499 cmov%O2%C1\t{%2, %0|%0, %2}
19500 cmov%O2%c1\t{%3, %0|%0, %3}"
19501 [(set_attr "type" "icmov")
19502 (set_attr "mode" "HI")])
19504 (define_expand "movqicc"
19505 [(set (match_operand:QI 0 "register_operand" "")
19506 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19507 (match_operand:QI 2 "general_operand" "")
19508 (match_operand:QI 3 "general_operand" "")))]
19509 "TARGET_QIMODE_MATH"
19510 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19512 (define_insn_and_split "*movqicc_noc"
19513 [(set (match_operand:QI 0 "register_operand" "=r,r")
19514 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19515 [(match_operand 4 "flags_reg_operand" "")
19517 (match_operand:QI 2 "register_operand" "r,0")
19518 (match_operand:QI 3 "register_operand" "0,r")))]
19519 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19521 "&& reload_completed"
19522 [(set (match_dup 0)
19523 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19526 "operands[0] = gen_lowpart (SImode, operands[0]);
19527 operands[2] = gen_lowpart (SImode, operands[2]);
19528 operands[3] = gen_lowpart (SImode, operands[3]);"
19529 [(set_attr "type" "icmov")
19530 (set_attr "mode" "SI")])
19532 (define_expand "movsfcc"
19533 [(set (match_operand:SF 0 "register_operand" "")
19534 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19535 (match_operand:SF 2 "register_operand" "")
19536 (match_operand:SF 3 "register_operand" "")))]
19537 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19538 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19540 (define_insn "*movsfcc_1_387"
19541 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19542 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19543 [(reg FLAGS_REG) (const_int 0)])
19544 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19545 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19546 "TARGET_80387 && TARGET_CMOVE
19547 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19549 fcmov%F1\t{%2, %0|%0, %2}
19550 fcmov%f1\t{%3, %0|%0, %3}
19551 cmov%O2%C1\t{%2, %0|%0, %2}
19552 cmov%O2%c1\t{%3, %0|%0, %3}"
19553 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19554 (set_attr "mode" "SF,SF,SI,SI")])
19556 (define_expand "movdfcc"
19557 [(set (match_operand:DF 0 "register_operand" "")
19558 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19559 (match_operand:DF 2 "register_operand" "")
19560 (match_operand:DF 3 "register_operand" "")))]
19561 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19562 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19564 (define_insn "*movdfcc_1"
19565 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19566 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19567 [(reg FLAGS_REG) (const_int 0)])
19568 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19569 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19570 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19571 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19573 fcmov%F1\t{%2, %0|%0, %2}
19574 fcmov%f1\t{%3, %0|%0, %3}
19577 [(set_attr "type" "fcmov,fcmov,multi,multi")
19578 (set_attr "mode" "DF")])
19580 (define_insn "*movdfcc_1_rex64"
19581 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19582 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19583 [(reg FLAGS_REG) (const_int 0)])
19584 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19585 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19586 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19587 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19589 fcmov%F1\t{%2, %0|%0, %2}
19590 fcmov%f1\t{%3, %0|%0, %3}
19591 cmov%O2%C1\t{%2, %0|%0, %2}
19592 cmov%O2%c1\t{%3, %0|%0, %3}"
19593 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19594 (set_attr "mode" "DF")])
19597 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19598 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19599 [(match_operand 4 "flags_reg_operand" "")
19601 (match_operand:DF 2 "nonimmediate_operand" "")
19602 (match_operand:DF 3 "nonimmediate_operand" "")))]
19603 "!TARGET_64BIT && reload_completed"
19604 [(set (match_dup 2)
19605 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19609 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19612 "split_di (operands+2, 1, operands+5, operands+6);
19613 split_di (operands+3, 1, operands+7, operands+8);
19614 split_di (operands, 1, operands+2, operands+3);")
19616 (define_expand "movxfcc"
19617 [(set (match_operand:XF 0 "register_operand" "")
19618 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19619 (match_operand:XF 2 "register_operand" "")
19620 (match_operand:XF 3 "register_operand" "")))]
19621 "TARGET_80387 && TARGET_CMOVE"
19622 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19624 (define_insn "*movxfcc_1"
19625 [(set (match_operand:XF 0 "register_operand" "=f,f")
19626 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19627 [(reg FLAGS_REG) (const_int 0)])
19628 (match_operand:XF 2 "register_operand" "f,0")
19629 (match_operand:XF 3 "register_operand" "0,f")))]
19630 "TARGET_80387 && TARGET_CMOVE"
19632 fcmov%F1\t{%2, %0|%0, %2}
19633 fcmov%f1\t{%3, %0|%0, %3}"
19634 [(set_attr "type" "fcmov")
19635 (set_attr "mode" "XF")])
19637 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19638 ;; the scalar versions to have only XMM registers as operands.
19640 ;; SSE5 conditional move
19641 (define_insn "*sse5_pcmov_<mode>"
19642 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19643 (if_then_else:MODEF
19644 (match_operand:MODEF 1 "register_operand" "x,0")
19645 (match_operand:MODEF 2 "register_operand" "0,x")
19646 (match_operand:MODEF 3 "register_operand" "x,x")))]
19647 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19648 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19649 [(set_attr "type" "sse4arg")])
19651 ;; These versions of the min/max patterns are intentionally ignorant of
19652 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19653 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19654 ;; are undefined in this condition, we're certain this is correct.
19656 (define_insn "smin<mode>3"
19657 [(set (match_operand:MODEF 0 "register_operand" "=x")
19659 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19660 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19661 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19662 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19663 [(set_attr "type" "sseadd")
19664 (set_attr "mode" "<MODE>")])
19666 (define_insn "smax<mode>3"
19667 [(set (match_operand:MODEF 0 "register_operand" "=x")
19669 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19670 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19671 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19672 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19673 [(set_attr "type" "sseadd")
19674 (set_attr "mode" "<MODE>")])
19676 ;; These versions of the min/max patterns implement exactly the operations
19677 ;; min = (op1 < op2 ? op1 : op2)
19678 ;; max = (!(op1 < op2) ? op1 : op2)
19679 ;; Their operands are not commutative, and thus they may be used in the
19680 ;; presence of -0.0 and NaN.
19682 (define_insn "*ieee_smin<mode>3"
19683 [(set (match_operand:MODEF 0 "register_operand" "=x")
19685 [(match_operand:MODEF 1 "register_operand" "0")
19686 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19688 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19689 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19690 [(set_attr "type" "sseadd")
19691 (set_attr "mode" "<MODE>")])
19693 (define_insn "*ieee_smax<mode>3"
19694 [(set (match_operand:MODEF 0 "register_operand" "=x")
19696 [(match_operand:MODEF 1 "register_operand" "0")
19697 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19699 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19700 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19701 [(set_attr "type" "sseadd")
19702 (set_attr "mode" "<MODE>")])
19704 ;; Make two stack loads independent:
19706 ;; fld %st(0) -> fld bb
19707 ;; fmul bb fmul %st(1), %st
19709 ;; Actually we only match the last two instructions for simplicity.
19711 [(set (match_operand 0 "fp_register_operand" "")
19712 (match_operand 1 "fp_register_operand" ""))
19714 (match_operator 2 "binary_fp_operator"
19716 (match_operand 3 "memory_operand" "")]))]
19717 "REGNO (operands[0]) != REGNO (operands[1])"
19718 [(set (match_dup 0) (match_dup 3))
19719 (set (match_dup 0) (match_dup 4))]
19721 ;; The % modifier is not operational anymore in peephole2's, so we have to
19722 ;; swap the operands manually in the case of addition and multiplication.
19723 "if (COMMUTATIVE_ARITH_P (operands[2]))
19724 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19725 operands[0], operands[1]);
19727 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19728 operands[1], operands[0]);")
19730 ;; Conditional addition patterns
19731 (define_expand "addqicc"
19732 [(match_operand:QI 0 "register_operand" "")
19733 (match_operand 1 "comparison_operator" "")
19734 (match_operand:QI 2 "register_operand" "")
19735 (match_operand:QI 3 "const_int_operand" "")]
19737 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19739 (define_expand "addhicc"
19740 [(match_operand:HI 0 "register_operand" "")
19741 (match_operand 1 "comparison_operator" "")
19742 (match_operand:HI 2 "register_operand" "")
19743 (match_operand:HI 3 "const_int_operand" "")]
19745 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19747 (define_expand "addsicc"
19748 [(match_operand:SI 0 "register_operand" "")
19749 (match_operand 1 "comparison_operator" "")
19750 (match_operand:SI 2 "register_operand" "")
19751 (match_operand:SI 3 "const_int_operand" "")]
19753 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19755 (define_expand "adddicc"
19756 [(match_operand:DI 0 "register_operand" "")
19757 (match_operand 1 "comparison_operator" "")
19758 (match_operand:DI 2 "register_operand" "")
19759 (match_operand:DI 3 "const_int_operand" "")]
19761 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19764 ;; Misc patterns (?)
19766 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19767 ;; Otherwise there will be nothing to keep
19769 ;; [(set (reg ebp) (reg esp))]
19770 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19771 ;; (clobber (eflags)]
19772 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19774 ;; in proper program order.
19775 (define_insn "pro_epilogue_adjust_stack_1"
19776 [(set (match_operand:SI 0 "register_operand" "=r,r")
19777 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19778 (match_operand:SI 2 "immediate_operand" "i,i")))
19779 (clobber (reg:CC FLAGS_REG))
19780 (clobber (mem:BLK (scratch)))]
19783 switch (get_attr_type (insn))
19786 return "mov{l}\t{%1, %0|%0, %1}";
19789 if (CONST_INT_P (operands[2])
19790 && (INTVAL (operands[2]) == 128
19791 || (INTVAL (operands[2]) < 0
19792 && INTVAL (operands[2]) != -128)))
19794 operands[2] = GEN_INT (-INTVAL (operands[2]));
19795 return "sub{l}\t{%2, %0|%0, %2}";
19797 return "add{l}\t{%2, %0|%0, %2}";
19800 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19801 return "lea{l}\t{%a2, %0|%0, %a2}";
19804 gcc_unreachable ();
19807 [(set (attr "type")
19808 (cond [(eq_attr "alternative" "0")
19809 (const_string "alu")
19810 (match_operand:SI 2 "const0_operand" "")
19811 (const_string "imov")
19813 (const_string "lea")))
19814 (set_attr "mode" "SI")])
19816 (define_insn "pro_epilogue_adjust_stack_rex64"
19817 [(set (match_operand:DI 0 "register_operand" "=r,r")
19818 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19819 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19820 (clobber (reg:CC FLAGS_REG))
19821 (clobber (mem:BLK (scratch)))]
19824 switch (get_attr_type (insn))
19827 return "mov{q}\t{%1, %0|%0, %1}";
19830 if (CONST_INT_P (operands[2])
19831 /* Avoid overflows. */
19832 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19833 && (INTVAL (operands[2]) == 128
19834 || (INTVAL (operands[2]) < 0
19835 && INTVAL (operands[2]) != -128)))
19837 operands[2] = GEN_INT (-INTVAL (operands[2]));
19838 return "sub{q}\t{%2, %0|%0, %2}";
19840 return "add{q}\t{%2, %0|%0, %2}";
19843 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19844 return "lea{q}\t{%a2, %0|%0, %a2}";
19847 gcc_unreachable ();
19850 [(set (attr "type")
19851 (cond [(eq_attr "alternative" "0")
19852 (const_string "alu")
19853 (match_operand:DI 2 "const0_operand" "")
19854 (const_string "imov")
19856 (const_string "lea")))
19857 (set_attr "mode" "DI")])
19859 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19860 [(set (match_operand:DI 0 "register_operand" "=r,r")
19861 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19862 (match_operand:DI 3 "immediate_operand" "i,i")))
19863 (use (match_operand:DI 2 "register_operand" "r,r"))
19864 (clobber (reg:CC FLAGS_REG))
19865 (clobber (mem:BLK (scratch)))]
19868 switch (get_attr_type (insn))
19871 return "add{q}\t{%2, %0|%0, %2}";
19874 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19875 return "lea{q}\t{%a2, %0|%0, %a2}";
19878 gcc_unreachable ();
19881 [(set_attr "type" "alu,lea")
19882 (set_attr "mode" "DI")])
19884 (define_insn "allocate_stack_worker_32"
19885 [(set (match_operand:SI 0 "register_operand" "+a")
19886 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19887 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19888 (clobber (reg:CC FLAGS_REG))]
19889 "!TARGET_64BIT && TARGET_STACK_PROBE"
19891 [(set_attr "type" "multi")
19892 (set_attr "length" "5")])
19894 (define_insn "allocate_stack_worker_64"
19895 [(set (match_operand:DI 0 "register_operand" "=a")
19896 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19897 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19898 (clobber (reg:DI R10_REG))
19899 (clobber (reg:DI R11_REG))
19900 (clobber (reg:CC FLAGS_REG))]
19901 "TARGET_64BIT && TARGET_STACK_PROBE"
19903 [(set_attr "type" "multi")
19904 (set_attr "length" "5")])
19906 (define_expand "allocate_stack"
19907 [(match_operand 0 "register_operand" "")
19908 (match_operand 1 "general_operand" "")]
19909 "TARGET_STACK_PROBE"
19913 #ifndef CHECK_STACK_LIMIT
19914 #define CHECK_STACK_LIMIT 0
19917 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19918 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19920 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19921 stack_pointer_rtx, 0, OPTAB_DIRECT);
19922 if (x != stack_pointer_rtx)
19923 emit_move_insn (stack_pointer_rtx, x);
19927 x = copy_to_mode_reg (Pmode, operands[1]);
19929 x = gen_allocate_stack_worker_64 (x);
19931 x = gen_allocate_stack_worker_32 (x);
19935 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19939 (define_expand "builtin_setjmp_receiver"
19940 [(label_ref (match_operand 0 "" ""))]
19941 "!TARGET_64BIT && flag_pic"
19946 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19947 rtx label_rtx = gen_label_rtx ();
19948 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19949 xops[0] = xops[1] = picreg;
19950 xops[2] = gen_rtx_CONST (SImode,
19951 gen_rtx_MINUS (SImode,
19952 gen_rtx_LABEL_REF (SImode, label_rtx),
19953 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19954 ix86_expand_binary_operator (MINUS, SImode, xops);
19957 emit_insn (gen_set_got (pic_offset_table_rtx));
19961 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19964 [(set (match_operand 0 "register_operand" "")
19965 (match_operator 3 "promotable_binary_operator"
19966 [(match_operand 1 "register_operand" "")
19967 (match_operand 2 "aligned_operand" "")]))
19968 (clobber (reg:CC FLAGS_REG))]
19969 "! TARGET_PARTIAL_REG_STALL && reload_completed
19970 && ((GET_MODE (operands[0]) == HImode
19971 && ((!optimize_size && !TARGET_FAST_PREFIX)
19972 /* ??? next two lines just !satisfies_constraint_K (...) */
19973 || !CONST_INT_P (operands[2])
19974 || satisfies_constraint_K (operands[2])))
19975 || (GET_MODE (operands[0]) == QImode
19976 && (TARGET_PROMOTE_QImode || optimize_size)))"
19977 [(parallel [(set (match_dup 0)
19978 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19979 (clobber (reg:CC FLAGS_REG))])]
19980 "operands[0] = gen_lowpart (SImode, operands[0]);
19981 operands[1] = gen_lowpart (SImode, operands[1]);
19982 if (GET_CODE (operands[3]) != ASHIFT)
19983 operands[2] = gen_lowpart (SImode, operands[2]);
19984 PUT_MODE (operands[3], SImode);")
19986 ; Promote the QImode tests, as i386 has encoding of the AND
19987 ; instruction with 32-bit sign-extended immediate and thus the
19988 ; instruction size is unchanged, except in the %eax case for
19989 ; which it is increased by one byte, hence the ! optimize_size.
19991 [(set (match_operand 0 "flags_reg_operand" "")
19992 (match_operator 2 "compare_operator"
19993 [(and (match_operand 3 "aligned_operand" "")
19994 (match_operand 4 "const_int_operand" ""))
19996 (set (match_operand 1 "register_operand" "")
19997 (and (match_dup 3) (match_dup 4)))]
19998 "! TARGET_PARTIAL_REG_STALL && reload_completed
20000 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20001 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20002 /* Ensure that the operand will remain sign-extended immediate. */
20003 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20004 [(parallel [(set (match_dup 0)
20005 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20008 (and:SI (match_dup 3) (match_dup 4)))])]
20011 = gen_int_mode (INTVAL (operands[4])
20012 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20013 operands[1] = gen_lowpart (SImode, operands[1]);
20014 operands[3] = gen_lowpart (SImode, operands[3]);
20017 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20018 ; the TEST instruction with 32-bit sign-extended immediate and thus
20019 ; the instruction size would at least double, which is not what we
20020 ; want even with ! optimize_size.
20022 [(set (match_operand 0 "flags_reg_operand" "")
20023 (match_operator 1 "compare_operator"
20024 [(and (match_operand:HI 2 "aligned_operand" "")
20025 (match_operand:HI 3 "const_int_operand" ""))
20027 "! TARGET_PARTIAL_REG_STALL && reload_completed
20028 && ! TARGET_FAST_PREFIX
20030 /* Ensure that the operand will remain sign-extended immediate. */
20031 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20032 [(set (match_dup 0)
20033 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20037 = gen_int_mode (INTVAL (operands[3])
20038 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20039 operands[2] = gen_lowpart (SImode, operands[2]);
20043 [(set (match_operand 0 "register_operand" "")
20044 (neg (match_operand 1 "register_operand" "")))
20045 (clobber (reg:CC FLAGS_REG))]
20046 "! TARGET_PARTIAL_REG_STALL && reload_completed
20047 && (GET_MODE (operands[0]) == HImode
20048 || (GET_MODE (operands[0]) == QImode
20049 && (TARGET_PROMOTE_QImode || optimize_size)))"
20050 [(parallel [(set (match_dup 0)
20051 (neg:SI (match_dup 1)))
20052 (clobber (reg:CC FLAGS_REG))])]
20053 "operands[0] = gen_lowpart (SImode, operands[0]);
20054 operands[1] = gen_lowpart (SImode, operands[1]);")
20057 [(set (match_operand 0 "register_operand" "")
20058 (not (match_operand 1 "register_operand" "")))]
20059 "! TARGET_PARTIAL_REG_STALL && reload_completed
20060 && (GET_MODE (operands[0]) == HImode
20061 || (GET_MODE (operands[0]) == QImode
20062 && (TARGET_PROMOTE_QImode || optimize_size)))"
20063 [(set (match_dup 0)
20064 (not:SI (match_dup 1)))]
20065 "operands[0] = gen_lowpart (SImode, operands[0]);
20066 operands[1] = gen_lowpart (SImode, operands[1]);")
20069 [(set (match_operand 0 "register_operand" "")
20070 (if_then_else (match_operator 1 "comparison_operator"
20071 [(reg FLAGS_REG) (const_int 0)])
20072 (match_operand 2 "register_operand" "")
20073 (match_operand 3 "register_operand" "")))]
20074 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20075 && (GET_MODE (operands[0]) == HImode
20076 || (GET_MODE (operands[0]) == QImode
20077 && (TARGET_PROMOTE_QImode || optimize_size)))"
20078 [(set (match_dup 0)
20079 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20080 "operands[0] = gen_lowpart (SImode, operands[0]);
20081 operands[2] = gen_lowpart (SImode, operands[2]);
20082 operands[3] = gen_lowpart (SImode, operands[3]);")
20085 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20086 ;; transform a complex memory operation into two memory to register operations.
20088 ;; Don't push memory operands
20090 [(set (match_operand:SI 0 "push_operand" "")
20091 (match_operand:SI 1 "memory_operand" ""))
20092 (match_scratch:SI 2 "r")]
20093 "!optimize_size && !TARGET_PUSH_MEMORY
20094 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20095 [(set (match_dup 2) (match_dup 1))
20096 (set (match_dup 0) (match_dup 2))]
20100 [(set (match_operand:DI 0 "push_operand" "")
20101 (match_operand:DI 1 "memory_operand" ""))
20102 (match_scratch:DI 2 "r")]
20103 "!optimize_size && !TARGET_PUSH_MEMORY
20104 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20105 [(set (match_dup 2) (match_dup 1))
20106 (set (match_dup 0) (match_dup 2))]
20109 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20112 [(set (match_operand:SF 0 "push_operand" "")
20113 (match_operand:SF 1 "memory_operand" ""))
20114 (match_scratch:SF 2 "r")]
20115 "!optimize_size && !TARGET_PUSH_MEMORY
20116 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20117 [(set (match_dup 2) (match_dup 1))
20118 (set (match_dup 0) (match_dup 2))]
20122 [(set (match_operand:HI 0 "push_operand" "")
20123 (match_operand:HI 1 "memory_operand" ""))
20124 (match_scratch:HI 2 "r")]
20125 "!optimize_size && !TARGET_PUSH_MEMORY
20126 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20127 [(set (match_dup 2) (match_dup 1))
20128 (set (match_dup 0) (match_dup 2))]
20132 [(set (match_operand:QI 0 "push_operand" "")
20133 (match_operand:QI 1 "memory_operand" ""))
20134 (match_scratch:QI 2 "q")]
20135 "!optimize_size && !TARGET_PUSH_MEMORY
20136 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20137 [(set (match_dup 2) (match_dup 1))
20138 (set (match_dup 0) (match_dup 2))]
20141 ;; Don't move an immediate directly to memory when the instruction
20144 [(match_scratch:SI 1 "r")
20145 (set (match_operand:SI 0 "memory_operand" "")
20148 && ! TARGET_USE_MOV0
20149 && TARGET_SPLIT_LONG_MOVES
20150 && get_attr_length (insn) >= ix86_cost->large_insn
20151 && peep2_regno_dead_p (0, FLAGS_REG)"
20152 [(parallel [(set (match_dup 1) (const_int 0))
20153 (clobber (reg:CC FLAGS_REG))])
20154 (set (match_dup 0) (match_dup 1))]
20158 [(match_scratch:HI 1 "r")
20159 (set (match_operand:HI 0 "memory_operand" "")
20162 && ! TARGET_USE_MOV0
20163 && TARGET_SPLIT_LONG_MOVES
20164 && get_attr_length (insn) >= ix86_cost->large_insn
20165 && peep2_regno_dead_p (0, FLAGS_REG)"
20166 [(parallel [(set (match_dup 2) (const_int 0))
20167 (clobber (reg:CC FLAGS_REG))])
20168 (set (match_dup 0) (match_dup 1))]
20169 "operands[2] = gen_lowpart (SImode, operands[1]);")
20172 [(match_scratch:QI 1 "q")
20173 (set (match_operand:QI 0 "memory_operand" "")
20176 && ! TARGET_USE_MOV0
20177 && TARGET_SPLIT_LONG_MOVES
20178 && get_attr_length (insn) >= ix86_cost->large_insn
20179 && peep2_regno_dead_p (0, FLAGS_REG)"
20180 [(parallel [(set (match_dup 2) (const_int 0))
20181 (clobber (reg:CC FLAGS_REG))])
20182 (set (match_dup 0) (match_dup 1))]
20183 "operands[2] = gen_lowpart (SImode, operands[1]);")
20186 [(match_scratch:SI 2 "r")
20187 (set (match_operand:SI 0 "memory_operand" "")
20188 (match_operand:SI 1 "immediate_operand" ""))]
20190 && TARGET_SPLIT_LONG_MOVES
20191 && get_attr_length (insn) >= ix86_cost->large_insn"
20192 [(set (match_dup 2) (match_dup 1))
20193 (set (match_dup 0) (match_dup 2))]
20197 [(match_scratch:HI 2 "r")
20198 (set (match_operand:HI 0 "memory_operand" "")
20199 (match_operand:HI 1 "immediate_operand" ""))]
20201 && TARGET_SPLIT_LONG_MOVES
20202 && get_attr_length (insn) >= ix86_cost->large_insn"
20203 [(set (match_dup 2) (match_dup 1))
20204 (set (match_dup 0) (match_dup 2))]
20208 [(match_scratch:QI 2 "q")
20209 (set (match_operand:QI 0 "memory_operand" "")
20210 (match_operand:QI 1 "immediate_operand" ""))]
20212 && TARGET_SPLIT_LONG_MOVES
20213 && get_attr_length (insn) >= ix86_cost->large_insn"
20214 [(set (match_dup 2) (match_dup 1))
20215 (set (match_dup 0) (match_dup 2))]
20218 ;; Don't compare memory with zero, load and use a test instead.
20220 [(set (match_operand 0 "flags_reg_operand" "")
20221 (match_operator 1 "compare_operator"
20222 [(match_operand:SI 2 "memory_operand" "")
20224 (match_scratch:SI 3 "r")]
20225 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20226 [(set (match_dup 3) (match_dup 2))
20227 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20230 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20231 ;; Don't split NOTs with a displacement operand, because resulting XOR
20232 ;; will not be pairable anyway.
20234 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20235 ;; represented using a modRM byte. The XOR replacement is long decoded,
20236 ;; so this split helps here as well.
20238 ;; Note: Can't do this as a regular split because we can't get proper
20239 ;; lifetime information then.
20242 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20243 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20245 && ((TARGET_NOT_UNPAIRABLE
20246 && (!MEM_P (operands[0])
20247 || !memory_displacement_operand (operands[0], SImode)))
20248 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20249 && peep2_regno_dead_p (0, FLAGS_REG)"
20250 [(parallel [(set (match_dup 0)
20251 (xor:SI (match_dup 1) (const_int -1)))
20252 (clobber (reg:CC FLAGS_REG))])]
20256 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20257 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20259 && ((TARGET_NOT_UNPAIRABLE
20260 && (!MEM_P (operands[0])
20261 || !memory_displacement_operand (operands[0], HImode)))
20262 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0)
20265 (xor:HI (match_dup 1) (const_int -1)))
20266 (clobber (reg:CC FLAGS_REG))])]
20270 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20271 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20273 && ((TARGET_NOT_UNPAIRABLE
20274 && (!MEM_P (operands[0])
20275 || !memory_displacement_operand (operands[0], QImode)))
20276 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20277 && peep2_regno_dead_p (0, FLAGS_REG)"
20278 [(parallel [(set (match_dup 0)
20279 (xor:QI (match_dup 1) (const_int -1)))
20280 (clobber (reg:CC FLAGS_REG))])]
20283 ;; Non pairable "test imm, reg" instructions can be translated to
20284 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20285 ;; byte opcode instead of two, have a short form for byte operands),
20286 ;; so do it for other CPUs as well. Given that the value was dead,
20287 ;; this should not create any new dependencies. Pass on the sub-word
20288 ;; versions if we're concerned about partial register stalls.
20291 [(set (match_operand 0 "flags_reg_operand" "")
20292 (match_operator 1 "compare_operator"
20293 [(and:SI (match_operand:SI 2 "register_operand" "")
20294 (match_operand:SI 3 "immediate_operand" ""))
20296 "ix86_match_ccmode (insn, CCNOmode)
20297 && (true_regnum (operands[2]) != AX_REG
20298 || satisfies_constraint_K (operands[3]))
20299 && peep2_reg_dead_p (1, operands[2])"
20301 [(set (match_dup 0)
20302 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20305 (and:SI (match_dup 2) (match_dup 3)))])]
20308 ;; We don't need to handle HImode case, because it will be promoted to SImode
20309 ;; on ! TARGET_PARTIAL_REG_STALL
20312 [(set (match_operand 0 "flags_reg_operand" "")
20313 (match_operator 1 "compare_operator"
20314 [(and:QI (match_operand:QI 2 "register_operand" "")
20315 (match_operand:QI 3 "immediate_operand" ""))
20317 "! TARGET_PARTIAL_REG_STALL
20318 && ix86_match_ccmode (insn, CCNOmode)
20319 && true_regnum (operands[2]) != AX_REG
20320 && peep2_reg_dead_p (1, operands[2])"
20322 [(set (match_dup 0)
20323 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20326 (and:QI (match_dup 2) (match_dup 3)))])]
20330 [(set (match_operand 0 "flags_reg_operand" "")
20331 (match_operator 1 "compare_operator"
20334 (match_operand 2 "ext_register_operand" "")
20337 (match_operand 3 "const_int_operand" ""))
20339 "! TARGET_PARTIAL_REG_STALL
20340 && ix86_match_ccmode (insn, CCNOmode)
20341 && true_regnum (operands[2]) != AX_REG
20342 && peep2_reg_dead_p (1, operands[2])"
20343 [(parallel [(set (match_dup 0)
20352 (set (zero_extract:SI (match_dup 2)
20363 ;; Don't do logical operations with memory inputs.
20365 [(match_scratch:SI 2 "r")
20366 (parallel [(set (match_operand:SI 0 "register_operand" "")
20367 (match_operator:SI 3 "arith_or_logical_operator"
20369 (match_operand:SI 1 "memory_operand" "")]))
20370 (clobber (reg:CC FLAGS_REG))])]
20371 "! optimize_size && ! TARGET_READ_MODIFY"
20372 [(set (match_dup 2) (match_dup 1))
20373 (parallel [(set (match_dup 0)
20374 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20375 (clobber (reg:CC FLAGS_REG))])]
20379 [(match_scratch:SI 2 "r")
20380 (parallel [(set (match_operand:SI 0 "register_operand" "")
20381 (match_operator:SI 3 "arith_or_logical_operator"
20382 [(match_operand:SI 1 "memory_operand" "")
20384 (clobber (reg:CC FLAGS_REG))])]
20385 "! optimize_size && ! TARGET_READ_MODIFY"
20386 [(set (match_dup 2) (match_dup 1))
20387 (parallel [(set (match_dup 0)
20388 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20389 (clobber (reg:CC FLAGS_REG))])]
20392 ; Don't do logical operations with memory outputs
20394 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20395 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20396 ; the same decoder scheduling characteristics as the original.
20399 [(match_scratch:SI 2 "r")
20400 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20401 (match_operator:SI 3 "arith_or_logical_operator"
20403 (match_operand:SI 1 "nonmemory_operand" "")]))
20404 (clobber (reg:CC FLAGS_REG))])]
20405 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20406 [(set (match_dup 2) (match_dup 0))
20407 (parallel [(set (match_dup 2)
20408 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20409 (clobber (reg:CC FLAGS_REG))])
20410 (set (match_dup 0) (match_dup 2))]
20414 [(match_scratch:SI 2 "r")
20415 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20416 (match_operator:SI 3 "arith_or_logical_operator"
20417 [(match_operand:SI 1 "nonmemory_operand" "")
20419 (clobber (reg:CC FLAGS_REG))])]
20420 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20421 [(set (match_dup 2) (match_dup 0))
20422 (parallel [(set (match_dup 2)
20423 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20424 (clobber (reg:CC FLAGS_REG))])
20425 (set (match_dup 0) (match_dup 2))]
20428 ;; Attempt to always use XOR for zeroing registers.
20430 [(set (match_operand 0 "register_operand" "")
20431 (match_operand 1 "const0_operand" ""))]
20432 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20433 && (! TARGET_USE_MOV0 || optimize_size)
20434 && GENERAL_REG_P (operands[0])
20435 && peep2_regno_dead_p (0, FLAGS_REG)"
20436 [(parallel [(set (match_dup 0) (const_int 0))
20437 (clobber (reg:CC FLAGS_REG))])]
20439 operands[0] = gen_lowpart (word_mode, operands[0]);
20443 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20445 "(GET_MODE (operands[0]) == QImode
20446 || GET_MODE (operands[0]) == HImode)
20447 && (! TARGET_USE_MOV0 || optimize_size)
20448 && peep2_regno_dead_p (0, FLAGS_REG)"
20449 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20450 (clobber (reg:CC FLAGS_REG))])])
20452 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20454 [(set (match_operand 0 "register_operand" "")
20456 "(GET_MODE (operands[0]) == HImode
20457 || GET_MODE (operands[0]) == SImode
20458 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20459 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20460 && peep2_regno_dead_p (0, FLAGS_REG)"
20461 [(parallel [(set (match_dup 0) (const_int -1))
20462 (clobber (reg:CC FLAGS_REG))])]
20463 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20466 ;; Attempt to convert simple leas to adds. These can be created by
20469 [(set (match_operand:SI 0 "register_operand" "")
20470 (plus:SI (match_dup 0)
20471 (match_operand:SI 1 "nonmemory_operand" "")))]
20472 "peep2_regno_dead_p (0, FLAGS_REG)"
20473 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20474 (clobber (reg:CC FLAGS_REG))])]
20478 [(set (match_operand:SI 0 "register_operand" "")
20479 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20480 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20481 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20482 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20483 (clobber (reg:CC FLAGS_REG))])]
20484 "operands[2] = gen_lowpart (SImode, operands[2]);")
20487 [(set (match_operand:DI 0 "register_operand" "")
20488 (plus:DI (match_dup 0)
20489 (match_operand:DI 1 "x86_64_general_operand" "")))]
20490 "peep2_regno_dead_p (0, FLAGS_REG)"
20491 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20492 (clobber (reg:CC FLAGS_REG))])]
20496 [(set (match_operand:SI 0 "register_operand" "")
20497 (mult:SI (match_dup 0)
20498 (match_operand:SI 1 "const_int_operand" "")))]
20499 "exact_log2 (INTVAL (operands[1])) >= 0
20500 && peep2_regno_dead_p (0, FLAGS_REG)"
20501 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20502 (clobber (reg:CC FLAGS_REG))])]
20503 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20506 [(set (match_operand:DI 0 "register_operand" "")
20507 (mult:DI (match_dup 0)
20508 (match_operand:DI 1 "const_int_operand" "")))]
20509 "exact_log2 (INTVAL (operands[1])) >= 0
20510 && peep2_regno_dead_p (0, FLAGS_REG)"
20511 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20512 (clobber (reg:CC FLAGS_REG))])]
20513 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20516 [(set (match_operand:SI 0 "register_operand" "")
20517 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20518 (match_operand:DI 2 "const_int_operand" "")) 0))]
20519 "exact_log2 (INTVAL (operands[2])) >= 0
20520 && REGNO (operands[0]) == REGNO (operands[1])
20521 && peep2_regno_dead_p (0, FLAGS_REG)"
20522 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20523 (clobber (reg:CC FLAGS_REG))])]
20524 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20526 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20527 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20528 ;; many CPUs it is also faster, since special hardware to avoid esp
20529 ;; dependencies is present.
20531 ;; While some of these conversions may be done using splitters, we use peepholes
20532 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20534 ;; Convert prologue esp subtractions to push.
20535 ;; We need register to push. In order to keep verify_flow_info happy we have
20537 ;; - use scratch and clobber it in order to avoid dependencies
20538 ;; - use already live register
20539 ;; We can't use the second way right now, since there is no reliable way how to
20540 ;; verify that given register is live. First choice will also most likely in
20541 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20542 ;; call clobbered registers are dead. We may want to use base pointer as an
20543 ;; alternative when no register is available later.
20546 [(match_scratch:SI 0 "r")
20547 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20548 (clobber (reg:CC FLAGS_REG))
20549 (clobber (mem:BLK (scratch)))])]
20550 "optimize_size || !TARGET_SUB_ESP_4"
20551 [(clobber (match_dup 0))
20552 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20553 (clobber (mem:BLK (scratch)))])])
20556 [(match_scratch:SI 0 "r")
20557 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20558 (clobber (reg:CC FLAGS_REG))
20559 (clobber (mem:BLK (scratch)))])]
20560 "optimize_size || !TARGET_SUB_ESP_8"
20561 [(clobber (match_dup 0))
20562 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20563 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20564 (clobber (mem:BLK (scratch)))])])
20566 ;; Convert esp subtractions to push.
20568 [(match_scratch:SI 0 "r")
20569 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20570 (clobber (reg:CC FLAGS_REG))])]
20571 "optimize_size || !TARGET_SUB_ESP_4"
20572 [(clobber (match_dup 0))
20573 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20576 [(match_scratch:SI 0 "r")
20577 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20578 (clobber (reg:CC FLAGS_REG))])]
20579 "optimize_size || !TARGET_SUB_ESP_8"
20580 [(clobber (match_dup 0))
20581 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20582 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20584 ;; Convert epilogue deallocator to pop.
20586 [(match_scratch:SI 0 "r")
20587 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20588 (clobber (reg:CC FLAGS_REG))
20589 (clobber (mem:BLK (scratch)))])]
20590 "optimize_size || !TARGET_ADD_ESP_4"
20591 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20592 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20593 (clobber (mem:BLK (scratch)))])]
20596 ;; Two pops case is tricky, since pop causes dependency on destination register.
20597 ;; We use two registers if available.
20599 [(match_scratch:SI 0 "r")
20600 (match_scratch:SI 1 "r")
20601 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20602 (clobber (reg:CC FLAGS_REG))
20603 (clobber (mem:BLK (scratch)))])]
20604 "optimize_size || !TARGET_ADD_ESP_8"
20605 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20606 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607 (clobber (mem:BLK (scratch)))])
20608 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20609 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20613 [(match_scratch:SI 0 "r")
20614 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20615 (clobber (reg:CC FLAGS_REG))
20616 (clobber (mem:BLK (scratch)))])]
20618 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20619 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20620 (clobber (mem:BLK (scratch)))])
20621 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20622 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20625 ;; Convert esp additions to pop.
20627 [(match_scratch:SI 0 "r")
20628 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20629 (clobber (reg:CC FLAGS_REG))])]
20631 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20632 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20635 ;; Two pops case is tricky, since pop causes dependency on destination register.
20636 ;; We use two registers if available.
20638 [(match_scratch:SI 0 "r")
20639 (match_scratch:SI 1 "r")
20640 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20641 (clobber (reg:CC FLAGS_REG))])]
20643 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20644 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20645 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20646 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20650 [(match_scratch:SI 0 "r")
20651 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20652 (clobber (reg:CC FLAGS_REG))])]
20654 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20655 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20656 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20657 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20660 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20661 ;; required and register dies. Similarly for 128 to plus -128.
20663 [(set (match_operand 0 "flags_reg_operand" "")
20664 (match_operator 1 "compare_operator"
20665 [(match_operand 2 "register_operand" "")
20666 (match_operand 3 "const_int_operand" "")]))]
20667 "(INTVAL (operands[3]) == -1
20668 || INTVAL (operands[3]) == 1
20669 || INTVAL (operands[3]) == 128)
20670 && ix86_match_ccmode (insn, CCGCmode)
20671 && peep2_reg_dead_p (1, operands[2])"
20672 [(parallel [(set (match_dup 0)
20673 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20674 (clobber (match_dup 2))])]
20678 [(match_scratch:DI 0 "r")
20679 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20680 (clobber (reg:CC FLAGS_REG))
20681 (clobber (mem:BLK (scratch)))])]
20682 "optimize_size || !TARGET_SUB_ESP_4"
20683 [(clobber (match_dup 0))
20684 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20685 (clobber (mem:BLK (scratch)))])])
20688 [(match_scratch:DI 0 "r")
20689 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20690 (clobber (reg:CC FLAGS_REG))
20691 (clobber (mem:BLK (scratch)))])]
20692 "optimize_size || !TARGET_SUB_ESP_8"
20693 [(clobber (match_dup 0))
20694 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20695 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20696 (clobber (mem:BLK (scratch)))])])
20698 ;; Convert esp subtractions to push.
20700 [(match_scratch:DI 0 "r")
20701 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20702 (clobber (reg:CC FLAGS_REG))])]
20703 "optimize_size || !TARGET_SUB_ESP_4"
20704 [(clobber (match_dup 0))
20705 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20708 [(match_scratch:DI 0 "r")
20709 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20710 (clobber (reg:CC FLAGS_REG))])]
20711 "optimize_size || !TARGET_SUB_ESP_8"
20712 [(clobber (match_dup 0))
20713 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20714 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20716 ;; Convert epilogue deallocator to pop.
20718 [(match_scratch:DI 0 "r")
20719 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20720 (clobber (reg:CC FLAGS_REG))
20721 (clobber (mem:BLK (scratch)))])]
20722 "optimize_size || !TARGET_ADD_ESP_4"
20723 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20724 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20725 (clobber (mem:BLK (scratch)))])]
20728 ;; Two pops case is tricky, since pop causes dependency on destination register.
20729 ;; We use two registers if available.
20731 [(match_scratch:DI 0 "r")
20732 (match_scratch:DI 1 "r")
20733 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20734 (clobber (reg:CC FLAGS_REG))
20735 (clobber (mem:BLK (scratch)))])]
20736 "optimize_size || !TARGET_ADD_ESP_8"
20737 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20738 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739 (clobber (mem:BLK (scratch)))])
20740 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20741 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20745 [(match_scratch:DI 0 "r")
20746 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20747 (clobber (reg:CC FLAGS_REG))
20748 (clobber (mem:BLK (scratch)))])]
20750 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20751 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20752 (clobber (mem:BLK (scratch)))])
20753 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20754 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20757 ;; Convert esp additions to pop.
20759 [(match_scratch:DI 0 "r")
20760 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20761 (clobber (reg:CC FLAGS_REG))])]
20763 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20764 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20767 ;; Two pops case is tricky, since pop causes dependency on destination register.
20768 ;; We use two registers if available.
20770 [(match_scratch:DI 0 "r")
20771 (match_scratch:DI 1 "r")
20772 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20773 (clobber (reg:CC FLAGS_REG))])]
20775 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20776 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20777 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20778 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20782 [(match_scratch:DI 0 "r")
20783 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20784 (clobber (reg:CC FLAGS_REG))])]
20786 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20787 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20788 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20789 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20792 ;; Convert imul by three, five and nine into lea
20795 [(set (match_operand:SI 0 "register_operand" "")
20796 (mult:SI (match_operand:SI 1 "register_operand" "")
20797 (match_operand:SI 2 "const_int_operand" "")))
20798 (clobber (reg:CC FLAGS_REG))])]
20799 "INTVAL (operands[2]) == 3
20800 || INTVAL (operands[2]) == 5
20801 || INTVAL (operands[2]) == 9"
20802 [(set (match_dup 0)
20803 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20805 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20809 [(set (match_operand:SI 0 "register_operand" "")
20810 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20811 (match_operand:SI 2 "const_int_operand" "")))
20812 (clobber (reg:CC FLAGS_REG))])]
20814 && (INTVAL (operands[2]) == 3
20815 || INTVAL (operands[2]) == 5
20816 || INTVAL (operands[2]) == 9)"
20817 [(set (match_dup 0) (match_dup 1))
20819 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20821 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20825 [(set (match_operand:DI 0 "register_operand" "")
20826 (mult:DI (match_operand:DI 1 "register_operand" "")
20827 (match_operand:DI 2 "const_int_operand" "")))
20828 (clobber (reg:CC FLAGS_REG))])]
20830 && (INTVAL (operands[2]) == 3
20831 || INTVAL (operands[2]) == 5
20832 || INTVAL (operands[2]) == 9)"
20833 [(set (match_dup 0)
20834 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20836 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20840 [(set (match_operand:DI 0 "register_operand" "")
20841 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20842 (match_operand:DI 2 "const_int_operand" "")))
20843 (clobber (reg:CC FLAGS_REG))])]
20846 && (INTVAL (operands[2]) == 3
20847 || INTVAL (operands[2]) == 5
20848 || INTVAL (operands[2]) == 9)"
20849 [(set (match_dup 0) (match_dup 1))
20851 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20853 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20855 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20856 ;; imul $32bit_imm, reg, reg is direct decoded.
20858 [(match_scratch:DI 3 "r")
20859 (parallel [(set (match_operand:DI 0 "register_operand" "")
20860 (mult:DI (match_operand:DI 1 "memory_operand" "")
20861 (match_operand:DI 2 "immediate_operand" "")))
20862 (clobber (reg:CC FLAGS_REG))])]
20863 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20864 && !satisfies_constraint_K (operands[2])"
20865 [(set (match_dup 3) (match_dup 1))
20866 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20867 (clobber (reg:CC FLAGS_REG))])]
20871 [(match_scratch:SI 3 "r")
20872 (parallel [(set (match_operand:SI 0 "register_operand" "")
20873 (mult:SI (match_operand:SI 1 "memory_operand" "")
20874 (match_operand:SI 2 "immediate_operand" "")))
20875 (clobber (reg:CC FLAGS_REG))])]
20876 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20877 && !satisfies_constraint_K (operands[2])"
20878 [(set (match_dup 3) (match_dup 1))
20879 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20880 (clobber (reg:CC FLAGS_REG))])]
20884 [(match_scratch:SI 3 "r")
20885 (parallel [(set (match_operand:DI 0 "register_operand" "")
20887 (mult:SI (match_operand:SI 1 "memory_operand" "")
20888 (match_operand:SI 2 "immediate_operand" ""))))
20889 (clobber (reg:CC FLAGS_REG))])]
20890 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20891 && !satisfies_constraint_K (operands[2])"
20892 [(set (match_dup 3) (match_dup 1))
20893 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20894 (clobber (reg:CC FLAGS_REG))])]
20897 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20898 ;; Convert it into imul reg, reg
20899 ;; It would be better to force assembler to encode instruction using long
20900 ;; immediate, but there is apparently no way to do so.
20902 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20903 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20904 (match_operand:DI 2 "const_int_operand" "")))
20905 (clobber (reg:CC FLAGS_REG))])
20906 (match_scratch:DI 3 "r")]
20907 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20908 && satisfies_constraint_K (operands[2])"
20909 [(set (match_dup 3) (match_dup 2))
20910 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20911 (clobber (reg:CC FLAGS_REG))])]
20913 if (!rtx_equal_p (operands[0], operands[1]))
20914 emit_move_insn (operands[0], operands[1]);
20918 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20919 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20920 (match_operand:SI 2 "const_int_operand" "")))
20921 (clobber (reg:CC FLAGS_REG))])
20922 (match_scratch:SI 3 "r")]
20923 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20924 && satisfies_constraint_K (operands[2])"
20925 [(set (match_dup 3) (match_dup 2))
20926 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20927 (clobber (reg:CC FLAGS_REG))])]
20929 if (!rtx_equal_p (operands[0], operands[1]))
20930 emit_move_insn (operands[0], operands[1]);
20934 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20935 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20936 (match_operand:HI 2 "immediate_operand" "")))
20937 (clobber (reg:CC FLAGS_REG))])
20938 (match_scratch:HI 3 "r")]
20939 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20940 [(set (match_dup 3) (match_dup 2))
20941 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20942 (clobber (reg:CC FLAGS_REG))])]
20944 if (!rtx_equal_p (operands[0], operands[1]))
20945 emit_move_insn (operands[0], operands[1]);
20948 ;; After splitting up read-modify operations, array accesses with memory
20949 ;; operands might end up in form:
20951 ;; movl 4(%esp), %edx
20953 ;; instead of pre-splitting:
20955 ;; addl 4(%esp), %eax
20957 ;; movl 4(%esp), %edx
20958 ;; leal (%edx,%eax,4), %eax
20961 [(parallel [(set (match_operand 0 "register_operand" "")
20962 (ashift (match_operand 1 "register_operand" "")
20963 (match_operand 2 "const_int_operand" "")))
20964 (clobber (reg:CC FLAGS_REG))])
20965 (set (match_operand 3 "register_operand")
20966 (match_operand 4 "x86_64_general_operand" ""))
20967 (parallel [(set (match_operand 5 "register_operand" "")
20968 (plus (match_operand 6 "register_operand" "")
20969 (match_operand 7 "register_operand" "")))
20970 (clobber (reg:CC FLAGS_REG))])]
20971 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20972 /* Validate MODE for lea. */
20973 && ((!TARGET_PARTIAL_REG_STALL
20974 && (GET_MODE (operands[0]) == QImode
20975 || GET_MODE (operands[0]) == HImode))
20976 || GET_MODE (operands[0]) == SImode
20977 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20978 /* We reorder load and the shift. */
20979 && !rtx_equal_p (operands[1], operands[3])
20980 && !reg_overlap_mentioned_p (operands[0], operands[4])
20981 /* Last PLUS must consist of operand 0 and 3. */
20982 && !rtx_equal_p (operands[0], operands[3])
20983 && (rtx_equal_p (operands[3], operands[6])
20984 || rtx_equal_p (operands[3], operands[7]))
20985 && (rtx_equal_p (operands[0], operands[6])
20986 || rtx_equal_p (operands[0], operands[7]))
20987 /* The intermediate operand 0 must die or be same as output. */
20988 && (rtx_equal_p (operands[0], operands[5])
20989 || peep2_reg_dead_p (3, operands[0]))"
20990 [(set (match_dup 3) (match_dup 4))
20991 (set (match_dup 0) (match_dup 1))]
20993 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20994 int scale = 1 << INTVAL (operands[2]);
20995 rtx index = gen_lowpart (Pmode, operands[1]);
20996 rtx base = gen_lowpart (Pmode, operands[3]);
20997 rtx dest = gen_lowpart (mode, operands[5]);
20999 operands[1] = gen_rtx_PLUS (Pmode, base,
21000 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21002 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21003 operands[0] = dest;
21006 ;; Call-value patterns last so that the wildcard operand does not
21007 ;; disrupt insn-recog's switch tables.
21009 (define_insn "*call_value_pop_0"
21010 [(set (match_operand 0 "" "")
21011 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21012 (match_operand:SI 2 "" "")))
21013 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21014 (match_operand:SI 3 "immediate_operand" "")))]
21017 if (SIBLING_CALL_P (insn))
21020 return "call\t%P1";
21022 [(set_attr "type" "callv")])
21024 (define_insn "*call_value_pop_1"
21025 [(set (match_operand 0 "" "")
21026 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21027 (match_operand:SI 2 "" "")))
21028 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21029 (match_operand:SI 3 "immediate_operand" "i")))]
21032 if (constant_call_address_operand (operands[1], Pmode))
21034 if (SIBLING_CALL_P (insn))
21037 return "call\t%P1";
21039 if (SIBLING_CALL_P (insn))
21042 return "call\t%A1";
21044 [(set_attr "type" "callv")])
21046 (define_insn "*call_value_0"
21047 [(set (match_operand 0 "" "")
21048 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21049 (match_operand:SI 2 "" "")))]
21052 if (SIBLING_CALL_P (insn))
21055 return "call\t%P1";
21057 [(set_attr "type" "callv")])
21059 (define_insn "*call_value_0_rex64"
21060 [(set (match_operand 0 "" "")
21061 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21062 (match_operand:DI 2 "const_int_operand" "")))]
21065 if (SIBLING_CALL_P (insn))
21068 return "call\t%P1";
21070 [(set_attr "type" "callv")])
21072 (define_insn "*call_value_1"
21073 [(set (match_operand 0 "" "")
21074 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21075 (match_operand:SI 2 "" "")))]
21076 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21078 if (constant_call_address_operand (operands[1], Pmode))
21079 return "call\t%P1";
21080 return "call\t%A1";
21082 [(set_attr "type" "callv")])
21084 (define_insn "*sibcall_value_1"
21085 [(set (match_operand 0 "" "")
21086 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21087 (match_operand:SI 2 "" "")))]
21088 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21090 if (constant_call_address_operand (operands[1], Pmode))
21094 [(set_attr "type" "callv")])
21096 (define_insn "*call_value_1_rex64"
21097 [(set (match_operand 0 "" "")
21098 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21099 (match_operand:DI 2 "" "")))]
21100 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21101 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21103 if (constant_call_address_operand (operands[1], Pmode))
21104 return "call\t%P1";
21105 return "call\t%A1";
21107 [(set_attr "type" "callv")])
21109 (define_insn "*call_value_1_rex64_large"
21110 [(set (match_operand 0 "" "")
21111 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21112 (match_operand:DI 2 "" "")))]
21113 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21115 [(set_attr "type" "callv")])
21117 (define_insn "*sibcall_value_1_rex64"
21118 [(set (match_operand 0 "" "")
21119 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21120 (match_operand:DI 2 "" "")))]
21121 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21123 [(set_attr "type" "callv")])
21125 (define_insn "*sibcall_value_1_rex64_v"
21126 [(set (match_operand 0 "" "")
21127 (call (mem:QI (reg:DI R11_REG))
21128 (match_operand:DI 1 "" "")))]
21129 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21131 [(set_attr "type" "callv")])
21133 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21134 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21135 ;; caught for use by garbage collectors and the like. Using an insn that
21136 ;; maps to SIGILL makes it more likely the program will rightfully die.
21137 ;; Keeping with tradition, "6" is in honor of #UD.
21138 (define_insn "trap"
21139 [(trap_if (const_int 1) (const_int 6))]
21141 { return ASM_SHORT "0x0b0f"; }
21142 [(set_attr "length" "2")])
21144 (define_expand "sse_prologue_save"
21145 [(parallel [(set (match_operand:BLK 0 "" "")
21146 (unspec:BLK [(reg:DI 21)
21153 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21154 (use (match_operand:DI 1 "register_operand" ""))
21155 (use (match_operand:DI 2 "immediate_operand" ""))
21156 (use (label_ref:DI (match_operand 3 "" "")))])]
21160 (define_insn "*sse_prologue_save_insn"
21161 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21162 (match_operand:DI 4 "const_int_operand" "n")))
21163 (unspec:BLK [(reg:DI 21)
21170 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21171 (use (match_operand:DI 1 "register_operand" "r"))
21172 (use (match_operand:DI 2 "const_int_operand" "i"))
21173 (use (label_ref:DI (match_operand 3 "" "X")))]
21175 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21176 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21180 operands[0] = gen_rtx_MEM (Pmode,
21181 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21182 output_asm_insn (\"jmp\\t%A1\", operands);
21183 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21185 operands[4] = adjust_address (operands[0], DImode, i*16);
21186 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21187 PUT_MODE (operands[4], TImode);
21188 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21189 output_asm_insn (\"rex\", operands);
21190 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21192 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21193 CODE_LABEL_NUMBER (operands[3]));
21197 [(set_attr "type" "other")
21198 (set_attr "length_immediate" "0")
21199 (set_attr "length_address" "0")
21200 (set_attr "length" "135")
21201 (set_attr "memory" "store")
21202 (set_attr "modrm" "0")
21203 (set_attr "mode" "DI")])
21205 (define_expand "prefetch"
21206 [(prefetch (match_operand 0 "address_operand" "")
21207 (match_operand:SI 1 "const_int_operand" "")
21208 (match_operand:SI 2 "const_int_operand" ""))]
21209 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21211 int rw = INTVAL (operands[1]);
21212 int locality = INTVAL (operands[2]);
21214 gcc_assert (rw == 0 || rw == 1);
21215 gcc_assert (locality >= 0 && locality <= 3);
21216 gcc_assert (GET_MODE (operands[0]) == Pmode
21217 || GET_MODE (operands[0]) == VOIDmode);
21219 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21220 supported by SSE counterpart or the SSE prefetch is not available
21221 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21223 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21224 operands[2] = GEN_INT (3);
21226 operands[1] = const0_rtx;
21229 (define_insn "*prefetch_sse"
21230 [(prefetch (match_operand:SI 0 "address_operand" "p")
21232 (match_operand:SI 1 "const_int_operand" ""))]
21233 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21235 static const char * const patterns[4] = {
21236 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21239 int locality = INTVAL (operands[1]);
21240 gcc_assert (locality >= 0 && locality <= 3);
21242 return patterns[locality];
21244 [(set_attr "type" "sse")
21245 (set_attr "memory" "none")])
21247 (define_insn "*prefetch_sse_rex"
21248 [(prefetch (match_operand:DI 0 "address_operand" "p")
21250 (match_operand:SI 1 "const_int_operand" ""))]
21251 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21253 static const char * const patterns[4] = {
21254 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21257 int locality = INTVAL (operands[1]);
21258 gcc_assert (locality >= 0 && locality <= 3);
21260 return patterns[locality];
21262 [(set_attr "type" "sse")
21263 (set_attr "memory" "none")])
21265 (define_insn "*prefetch_3dnow"
21266 [(prefetch (match_operand:SI 0 "address_operand" "p")
21267 (match_operand:SI 1 "const_int_operand" "n")
21269 "TARGET_3DNOW && !TARGET_64BIT"
21271 if (INTVAL (operands[1]) == 0)
21272 return "prefetch\t%a0";
21274 return "prefetchw\t%a0";
21276 [(set_attr "type" "mmx")
21277 (set_attr "memory" "none")])
21279 (define_insn "*prefetch_3dnow_rex"
21280 [(prefetch (match_operand:DI 0 "address_operand" "p")
21281 (match_operand:SI 1 "const_int_operand" "n")
21283 "TARGET_3DNOW && TARGET_64BIT"
21285 if (INTVAL (operands[1]) == 0)
21286 return "prefetch\t%a0";
21288 return "prefetchw\t%a0";
21290 [(set_attr "type" "mmx")
21291 (set_attr "memory" "none")])
21293 (define_expand "stack_protect_set"
21294 [(match_operand 0 "memory_operand" "")
21295 (match_operand 1 "memory_operand" "")]
21298 #ifdef TARGET_THREAD_SSP_OFFSET
21300 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21301 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21303 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21304 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21307 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21309 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21314 (define_insn "stack_protect_set_si"
21315 [(set (match_operand:SI 0 "memory_operand" "=m")
21316 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21317 (set (match_scratch:SI 2 "=&r") (const_int 0))
21318 (clobber (reg:CC FLAGS_REG))]
21320 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21321 [(set_attr "type" "multi")])
21323 (define_insn "stack_protect_set_di"
21324 [(set (match_operand:DI 0 "memory_operand" "=m")
21325 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21326 (set (match_scratch:DI 2 "=&r") (const_int 0))
21327 (clobber (reg:CC FLAGS_REG))]
21329 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21330 [(set_attr "type" "multi")])
21332 (define_insn "stack_tls_protect_set_si"
21333 [(set (match_operand:SI 0 "memory_operand" "=m")
21334 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21335 (set (match_scratch:SI 2 "=&r") (const_int 0))
21336 (clobber (reg:CC FLAGS_REG))]
21338 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21339 [(set_attr "type" "multi")])
21341 (define_insn "stack_tls_protect_set_di"
21342 [(set (match_operand:DI 0 "memory_operand" "=m")
21343 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21344 (set (match_scratch:DI 2 "=&r") (const_int 0))
21345 (clobber (reg:CC FLAGS_REG))]
21348 /* The kernel uses a different segment register for performance reasons; a
21349 system call would not have to trash the userspace segment register,
21350 which would be expensive */
21351 if (ix86_cmodel != CM_KERNEL)
21352 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21354 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21356 [(set_attr "type" "multi")])
21358 (define_expand "stack_protect_test"
21359 [(match_operand 0 "memory_operand" "")
21360 (match_operand 1 "memory_operand" "")
21361 (match_operand 2 "" "")]
21364 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21365 ix86_compare_op0 = operands[0];
21366 ix86_compare_op1 = operands[1];
21367 ix86_compare_emitted = flags;
21369 #ifdef TARGET_THREAD_SSP_OFFSET
21371 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21372 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21374 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21375 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21378 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21380 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21382 emit_jump_insn (gen_beq (operands[2]));
21386 (define_insn "stack_protect_test_si"
21387 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21388 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21389 (match_operand:SI 2 "memory_operand" "m")]
21391 (clobber (match_scratch:SI 3 "=&r"))]
21393 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21394 [(set_attr "type" "multi")])
21396 (define_insn "stack_protect_test_di"
21397 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21398 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21399 (match_operand:DI 2 "memory_operand" "m")]
21401 (clobber (match_scratch:DI 3 "=&r"))]
21403 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21404 [(set_attr "type" "multi")])
21406 (define_insn "stack_tls_protect_test_si"
21407 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21408 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21409 (match_operand:SI 2 "const_int_operand" "i")]
21410 UNSPEC_SP_TLS_TEST))
21411 (clobber (match_scratch:SI 3 "=r"))]
21413 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21414 [(set_attr "type" "multi")])
21416 (define_insn "stack_tls_protect_test_di"
21417 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21418 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21419 (match_operand:DI 2 "const_int_operand" "i")]
21420 UNSPEC_SP_TLS_TEST))
21421 (clobber (match_scratch:DI 3 "=r"))]
21424 /* The kernel uses a different segment register for performance reasons; a
21425 system call would not have to trash the userspace segment register,
21426 which would be expensive */
21427 if (ix86_cmodel != CM_KERNEL)
21428 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21430 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21432 [(set_attr "type" "multi")])
21434 (define_mode_iterator CRC32MODE [QI HI SI])
21435 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21436 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21438 (define_insn "sse4_2_crc32<mode>"
21439 [(set (match_operand:SI 0 "register_operand" "=r")
21441 [(match_operand:SI 1 "register_operand" "0")
21442 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21445 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21446 [(set_attr "type" "sselog1")
21447 (set_attr "prefix_rep" "1")
21448 (set_attr "prefix_extra" "1")
21449 (set_attr "mode" "SI")])
21451 (define_insn "sse4_2_crc32di"
21452 [(set (match_operand:DI 0 "register_operand" "=r")
21454 [(match_operand:DI 1 "register_operand" "0")
21455 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21457 "TARGET_SSE4_2 && TARGET_64BIT"
21458 "crc32q\t{%2, %0|%0, %2}"
21459 [(set_attr "type" "sselog1")
21460 (set_attr "prefix_rep" "1")
21461 (set_attr "prefix_extra" "1")
21462 (set_attr "mode" "DI")])
21466 (include "sync.md")