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, 2009, 2010
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
61 (UNSPEC_MACHOPIC_OFFSET 10)
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
71 (UNSPEC_MEMORY_BLOCKAGE 18)
76 (UNSPEC_TLS_LD_BASE 22)
78 (UNSPEC_TLS_IE_SUN 24)
80 ; Other random patterns
90 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
91 (UNSPEC_TRUNC_NOOP 39)
93 ; For SSE/MMX support:
94 (UNSPEC_FIX_NOTRUNC 40)
111 (UNSPEC_MS_TO_SYSV_CALL 48)
113 ; Generic math support
115 (UNSPEC_IEEE_MIN 51) ; not commutative
116 (UNSPEC_IEEE_MAX 52) ; not commutative
131 (UNSPEC_FRNDINT_FLOOR 70)
132 (UNSPEC_FRNDINT_CEIL 71)
133 (UNSPEC_FRNDINT_TRUNC 72)
134 (UNSPEC_FRNDINT_MASK_PM 73)
135 (UNSPEC_FIST_FLOOR 74)
136 (UNSPEC_FIST_CEIL 75)
138 ; x87 Double output FP
139 (UNSPEC_SINCOS_COS 80)
140 (UNSPEC_SINCOS_SIN 81)
141 (UNSPEC_XTRACT_FRACT 84)
142 (UNSPEC_XTRACT_EXP 85)
143 (UNSPEC_FSCALE_FRACT 86)
144 (UNSPEC_FSCALE_EXP 87)
156 (UNSPEC_SP_TLS_SET 102)
157 (UNSPEC_SP_TLS_TEST 103)
167 (UNSPEC_INSERTQI 132)
172 (UNSPEC_INSERTPS 135)
174 (UNSPEC_MOVNTDQA 137)
176 (UNSPEC_PHMINPOSUW 139)
182 (UNSPEC_PCMPESTR 144)
183 (UNSPEC_PCMPISTR 145)
186 (UNSPEC_SSE5_INTRINSIC 150)
187 (UNSPEC_SSE5_UNSIGNED_CMP 151)
188 (UNSPEC_SSE5_TRUEFALSE 152)
189 (UNSPEC_SSE5_PERMUTE 153)
191 (UNSPEC_CVTPH2PS 155)
192 (UNSPEC_CVTPS2PH 156)
196 (UNSPEC_AESENCLAST 160)
198 (UNSPEC_AESDECLAST 162)
200 (UNSPEC_AESKEYGENASSIST 164)
208 (UNSPEC_VPERMIL2F128 168)
209 (UNSPEC_MASKLOAD 169)
210 (UNSPEC_MASKSTORE 170)
216 [(UNSPECV_BLOCKAGE 0)
217 (UNSPECV_STACK_PROBE 1)
229 (UNSPECV_PROLOGUE_USE 14)
231 (UNSPECV_VZEROALL 16)
232 (UNSPECV_VZEROUPPER 17)
235 ;; Constants to represent pcomtrue/pcomfalse variants
245 ;; Constants used in the SSE5 pperm instruction
247 [(PPERM_SRC 0x00) /* copy source */
248 (PPERM_INVERT 0x20) /* invert source */
249 (PPERM_REVERSE 0x40) /* bit reverse source */
250 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
251 (PPERM_ZERO 0x80) /* all 0's */
252 (PPERM_ONES 0xa0) /* all 1's */
253 (PPERM_SIGN 0xc0) /* propagate sign bit */
254 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
255 (PPERM_SRC1 0x00) /* use first source byte */
256 (PPERM_SRC2 0x10) /* use second source byte */
259 ;; Registers by name.
311 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
314 ;; In C guard expressions, put expressions which may be compile-time
315 ;; constants first. This allows for better optimization. For
316 ;; example, write "TARGET_64BIT && reload_completed", not
317 ;; "reload_completed && TARGET_64BIT".
321 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
323 (const (symbol_ref "ix86_schedule")))
325 ;; A basic instruction type. Refinements due to arguments to be
326 ;; provided in other attributes.
329 alu,alu1,negnot,imov,imovx,lea,
330 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
331 icmp,test,ibr,setcc,icmov,
332 push,pop,call,callv,leave,
334 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
335 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
336 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
338 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
339 (const_string "other"))
341 ;; Main data type used by the insn
343 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
344 (const_string "unknown"))
346 ;; The CPU unit operations uses.
347 (define_attr "unit" "integer,i387,sse,mmx,unknown"
348 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
349 (const_string "i387")
350 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
351 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
352 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
354 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
356 (eq_attr "type" "other")
357 (const_string "unknown")]
358 (const_string "integer")))
360 ;; The (bounding maximum) length of an instruction immediate.
361 (define_attr "length_immediate" ""
362 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
365 (eq_attr "unit" "i387,sse,mmx")
367 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
369 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
370 (eq_attr "type" "imov,test")
371 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
372 (eq_attr "type" "call")
373 (if_then_else (match_operand 0 "constant_call_address_operand" "")
376 (eq_attr "type" "callv")
377 (if_then_else (match_operand 1 "constant_call_address_operand" "")
380 ;; We don't know the size before shorten_branches. Expect
381 ;; the instruction to fit for better scheduling.
382 (eq_attr "type" "ibr")
385 (symbol_ref "/* Update immediate_length and other attributes! */
386 gcc_unreachable (),1")))
388 ;; The (bounding maximum) length of an instruction address.
389 (define_attr "length_address" ""
390 (cond [(eq_attr "type" "str,other,multi,fxch")
392 (and (eq_attr "type" "call")
393 (match_operand 0 "constant_call_address_operand" ""))
395 (and (eq_attr "type" "callv")
396 (match_operand 1 "constant_call_address_operand" ""))
399 (symbol_ref "ix86_attr_length_address_default (insn)")))
401 ;; Set when length prefix is used.
402 (define_attr "prefix_data16" ""
403 (if_then_else (ior (eq_attr "mode" "HI")
404 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
408 ;; Set when string REP prefix is used.
409 (define_attr "prefix_rep" ""
410 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
414 ;; Set when 0f opcode prefix is used.
415 (define_attr "prefix_0f" ""
417 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
418 (eq_attr "unit" "sse,mmx"))
422 ;; Set when REX opcode prefix is used.
423 (define_attr "prefix_rex" ""
424 (cond [(and (eq_attr "mode" "DI")
425 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
427 (and (eq_attr "mode" "QI")
428 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
431 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
437 ;; There are also additional prefixes in SSSE3.
438 (define_attr "prefix_extra" "" (const_int 0))
440 ;; Prefix used: original, VEX or maybe VEX.
441 (define_attr "prefix" "orig,vex,maybe_vex"
442 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444 (const_string "orig")))
446 ;; There is a 8bit immediate for VEX.
447 (define_attr "prefix_vex_imm8" "" (const_int 0))
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
452 ;; The length of VEX prefix
453 (define_attr "length_vex" ""
454 (if_then_else (eq_attr "prefix_0f" "1")
455 (if_then_else (eq_attr "prefix_vex_w" "1")
456 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
457 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
458 (if_then_else (eq_attr "prefix_vex_w" "1")
459 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
460 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
462 ;; Set when modrm byte is used.
463 (define_attr "modrm" ""
464 (cond [(eq_attr "type" "str,leave")
466 (eq_attr "unit" "i387")
468 (and (eq_attr "type" "incdec")
469 (ior (match_operand:SI 1 "register_operand" "")
470 (match_operand:HI 1 "register_operand" "")))
472 (and (eq_attr "type" "push")
473 (not (match_operand 1 "memory_operand" "")))
475 (and (eq_attr "type" "pop")
476 (not (match_operand 0 "memory_operand" "")))
478 (and (eq_attr "type" "imov")
479 (ior (and (match_operand 0 "register_operand" "")
480 (match_operand 1 "immediate_operand" ""))
481 (ior (and (match_operand 0 "ax_reg_operand" "")
482 (match_operand 1 "memory_displacement_only_operand" ""))
483 (and (match_operand 0 "memory_displacement_only_operand" "")
484 (match_operand 1 "ax_reg_operand" "")))))
486 (and (eq_attr "type" "call")
487 (match_operand 0 "constant_call_address_operand" ""))
489 (and (eq_attr "type" "callv")
490 (match_operand 1 "constant_call_address_operand" ""))
495 ;; The (bounding maximum) length of an instruction in bytes.
496 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
497 ;; Later we may want to split them and compute proper length as for
499 (define_attr "length" ""
500 (cond [(eq_attr "type" "other,multi,fistp,frndint")
502 (eq_attr "type" "fcmp")
504 (eq_attr "unit" "i387")
506 (plus (attr "prefix_data16")
507 (attr "length_address")))
508 (ior (eq_attr "prefix" "vex")
509 (and (eq_attr "prefix" "maybe_vex")
510 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
511 (plus (attr "length_vex")
512 (plus (attr "prefix_vex_imm8")
514 (attr "length_address"))))]
515 (plus (plus (attr "modrm")
516 (plus (attr "prefix_0f")
517 (plus (attr "prefix_rex")
518 (plus (attr "prefix_extra")
520 (plus (attr "prefix_rep")
521 (plus (attr "prefix_data16")
522 (plus (attr "length_immediate")
523 (attr "length_address")))))))
525 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
526 ;; `store' if there is a simple memory reference therein, or `unknown'
527 ;; if the instruction is complex.
529 (define_attr "memory" "none,load,store,both,unknown"
530 (cond [(eq_attr "type" "other,multi,str")
531 (const_string "unknown")
532 (eq_attr "type" "lea,fcmov,fpspc")
533 (const_string "none")
534 (eq_attr "type" "fistp,leave")
535 (const_string "both")
536 (eq_attr "type" "frndint")
537 (const_string "load")
538 (eq_attr "type" "push")
539 (if_then_else (match_operand 1 "memory_operand" "")
540 (const_string "both")
541 (const_string "store"))
542 (eq_attr "type" "pop")
543 (if_then_else (match_operand 0 "memory_operand" "")
544 (const_string "both")
545 (const_string "load"))
546 (eq_attr "type" "setcc")
547 (if_then_else (match_operand 0 "memory_operand" "")
548 (const_string "store")
549 (const_string "none"))
550 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
551 (if_then_else (ior (match_operand 0 "memory_operand" "")
552 (match_operand 1 "memory_operand" ""))
553 (const_string "load")
554 (const_string "none"))
555 (eq_attr "type" "ibr")
556 (if_then_else (match_operand 0 "memory_operand" "")
557 (const_string "load")
558 (const_string "none"))
559 (eq_attr "type" "call")
560 (if_then_else (match_operand 0 "constant_call_address_operand" "")
561 (const_string "none")
562 (const_string "load"))
563 (eq_attr "type" "callv")
564 (if_then_else (match_operand 1 "constant_call_address_operand" "")
565 (const_string "none")
566 (const_string "load"))
567 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
568 (match_operand 1 "memory_operand" ""))
569 (const_string "both")
570 (and (match_operand 0 "memory_operand" "")
571 (match_operand 1 "memory_operand" ""))
572 (const_string "both")
573 (match_operand 0 "memory_operand" "")
574 (const_string "store")
575 (match_operand 1 "memory_operand" "")
576 (const_string "load")
578 "!alu1,negnot,ishift1,
579 imov,imovx,icmp,test,bitmanip,
581 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
582 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
583 (match_operand 2 "memory_operand" ""))
584 (const_string "load")
585 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
586 (match_operand 3 "memory_operand" ""))
587 (const_string "load")
589 (const_string "none")))
591 ;; Indicates if an instruction has both an immediate and a displacement.
593 (define_attr "imm_disp" "false,true,unknown"
594 (cond [(eq_attr "type" "other,multi")
595 (const_string "unknown")
596 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
597 (and (match_operand 0 "memory_displacement_operand" "")
598 (match_operand 1 "immediate_operand" "")))
599 (const_string "true")
600 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
601 (and (match_operand 0 "memory_displacement_operand" "")
602 (match_operand 2 "immediate_operand" "")))
603 (const_string "true")
605 (const_string "false")))
607 ;; Indicates if an FP operation has an integer source.
609 (define_attr "fp_int_src" "false,true"
610 (const_string "false"))
612 ;; Defines rounding mode of an FP operation.
614 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
615 (const_string "any"))
617 ;; Describe a user's asm statement.
618 (define_asm_attributes
619 [(set_attr "length" "128")
620 (set_attr "type" "multi")])
622 ;; All integer comparison codes.
623 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
625 ;; All floating-point comparison codes.
626 (define_code_iterator fp_cond [unordered ordered
627 uneq unge ungt unle unlt ltgt ])
629 (define_code_iterator plusminus [plus minus])
631 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
633 ;; Base name for define_insn
634 (define_code_attr plusminus_insn
635 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
636 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
638 ;; Base name for insn mnemonic.
639 (define_code_attr plusminus_mnemonic
640 [(plus "add") (ss_plus "adds") (us_plus "addus")
641 (minus "sub") (ss_minus "subs") (us_minus "subus")])
643 ;; Mark commutative operators as such in constraints.
644 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
645 (minus "") (ss_minus "") (us_minus "")])
647 ;; Mapping of signed max and min
648 (define_code_iterator smaxmin [smax smin])
650 ;; Mapping of unsigned max and min
651 (define_code_iterator umaxmin [umax umin])
653 ;; Mapping of signed/unsigned max and min
654 (define_code_iterator maxmin [smax smin umax umin])
656 ;; Base name for integer and FP insn mnemonic
657 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
658 (umax "maxu") (umin "minu")])
659 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
661 ;; Mapping of parallel logic operators
662 (define_code_iterator plogic [and ior xor])
664 ;; Base name for insn mnemonic.
665 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
667 ;; Mapping of abs neg operators
668 (define_code_iterator absneg [abs neg])
670 ;; Base name for x87 insn mnemonic.
671 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
673 ;; All single word integer modes.
674 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
676 ;; Single word integer modes without QImode.
677 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
679 ;; Instruction suffix for integer modes.
680 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
682 ;; Register class for integer modes.
683 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
685 ;; Immediate operand constraint for integer modes.
686 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
688 ;; General operand predicate for integer modes.
689 (define_mode_attr general_operand
690 [(QI "general_operand")
691 (HI "general_operand")
692 (SI "general_operand")
693 (DI "x86_64_general_operand")])
695 ;; SSE and x87 SFmode and DFmode floating point modes
696 (define_mode_iterator MODEF [SF DF])
698 ;; All x87 floating point modes
699 (define_mode_iterator X87MODEF [SF DF XF])
701 ;; All integer modes handled by x87 fisttp operator.
702 (define_mode_iterator X87MODEI [HI SI DI])
704 ;; All integer modes handled by integer x87 operators.
705 (define_mode_iterator X87MODEI12 [HI SI])
707 ;; All integer modes handled by SSE cvtts?2si* operators.
708 (define_mode_iterator SSEMODEI24 [SI DI])
710 ;; SSE asm suffix for floating point modes
711 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
713 ;; SSE vector mode corresponding to a scalar mode
714 (define_mode_attr ssevecmode
715 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
717 ;; Instruction suffix for REX 64bit operators.
718 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
720 ;; This mode iterator allows :P to be used for patterns that operate on
721 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
722 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
725 ;; Scheduling descriptions
727 (include "pentium.md")
730 (include "athlon.md")
734 ;; Operand and operator predicates and constraints
736 (include "predicates.md")
737 (include "constraints.md")
740 ;; Compare instructions.
742 ;; All compare insns have expanders that save the operands away without
743 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
744 ;; after the cmp) will actually emit the cmpM.
746 (define_expand "cmpti"
747 [(set (reg:CC FLAGS_REG)
748 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
749 (match_operand:TI 1 "x86_64_general_operand" "")))]
752 if (MEM_P (operands[0]) && MEM_P (operands[1]))
753 operands[0] = force_reg (TImode, operands[0]);
754 ix86_compare_op0 = operands[0];
755 ix86_compare_op1 = operands[1];
759 (define_expand "cmpdi"
760 [(set (reg:CC FLAGS_REG)
761 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
762 (match_operand:DI 1 "x86_64_general_operand" "")))]
765 if (MEM_P (operands[0]) && MEM_P (operands[1]))
766 operands[0] = force_reg (DImode, operands[0]);
767 ix86_compare_op0 = operands[0];
768 ix86_compare_op1 = operands[1];
772 (define_expand "cmpsi"
773 [(set (reg:CC FLAGS_REG)
774 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
775 (match_operand:SI 1 "general_operand" "")))]
778 if (MEM_P (operands[0]) && MEM_P (operands[1]))
779 operands[0] = force_reg (SImode, operands[0]);
780 ix86_compare_op0 = operands[0];
781 ix86_compare_op1 = operands[1];
785 (define_expand "cmphi"
786 [(set (reg:CC FLAGS_REG)
787 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
788 (match_operand:HI 1 "general_operand" "")))]
791 if (MEM_P (operands[0]) && MEM_P (operands[1]))
792 operands[0] = force_reg (HImode, operands[0]);
793 ix86_compare_op0 = operands[0];
794 ix86_compare_op1 = operands[1];
798 (define_expand "cmpqi"
799 [(set (reg:CC FLAGS_REG)
800 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
801 (match_operand:QI 1 "general_operand" "")))]
804 if (MEM_P (operands[0]) && MEM_P (operands[1]))
805 operands[0] = force_reg (QImode, operands[0]);
806 ix86_compare_op0 = operands[0];
807 ix86_compare_op1 = operands[1];
811 (define_insn "cmpdi_ccno_1_rex64"
812 [(set (reg FLAGS_REG)
813 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
814 (match_operand:DI 1 "const0_operand" "")))]
815 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
818 cmp{q}\t{%1, %0|%0, %1}"
819 [(set_attr "type" "test,icmp")
820 (set_attr "length_immediate" "0,1")
821 (set_attr "mode" "DI")])
823 (define_insn "*cmpdi_minus_1_rex64"
824 [(set (reg FLAGS_REG)
825 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
826 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
828 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
829 "cmp{q}\t{%1, %0|%0, %1}"
830 [(set_attr "type" "icmp")
831 (set_attr "mode" "DI")])
833 (define_expand "cmpdi_1_rex64"
834 [(set (reg:CC FLAGS_REG)
835 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
836 (match_operand:DI 1 "general_operand" "")))]
840 (define_insn "cmpdi_1_insn_rex64"
841 [(set (reg FLAGS_REG)
842 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
843 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
844 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
845 "cmp{q}\t{%1, %0|%0, %1}"
846 [(set_attr "type" "icmp")
847 (set_attr "mode" "DI")])
850 (define_insn "*cmpsi_ccno_1"
851 [(set (reg FLAGS_REG)
852 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
853 (match_operand:SI 1 "const0_operand" "")))]
854 "ix86_match_ccmode (insn, CCNOmode)"
857 cmp{l}\t{%1, %0|%0, %1}"
858 [(set_attr "type" "test,icmp")
859 (set_attr "length_immediate" "0,1")
860 (set_attr "mode" "SI")])
862 (define_insn "*cmpsi_minus_1"
863 [(set (reg FLAGS_REG)
864 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
865 (match_operand:SI 1 "general_operand" "ri,mr"))
867 "ix86_match_ccmode (insn, CCGOCmode)"
868 "cmp{l}\t{%1, %0|%0, %1}"
869 [(set_attr "type" "icmp")
870 (set_attr "mode" "SI")])
872 (define_expand "cmpsi_1"
873 [(set (reg:CC FLAGS_REG)
874 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
875 (match_operand:SI 1 "general_operand" "")))]
879 (define_insn "*cmpsi_1_insn"
880 [(set (reg FLAGS_REG)
881 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
882 (match_operand:SI 1 "general_operand" "ri,mr")))]
883 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
884 && ix86_match_ccmode (insn, CCmode)"
885 "cmp{l}\t{%1, %0|%0, %1}"
886 [(set_attr "type" "icmp")
887 (set_attr "mode" "SI")])
889 (define_insn "*cmphi_ccno_1"
890 [(set (reg FLAGS_REG)
891 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
892 (match_operand:HI 1 "const0_operand" "")))]
893 "ix86_match_ccmode (insn, CCNOmode)"
896 cmp{w}\t{%1, %0|%0, %1}"
897 [(set_attr "type" "test,icmp")
898 (set_attr "length_immediate" "0,1")
899 (set_attr "mode" "HI")])
901 (define_insn "*cmphi_minus_1"
902 [(set (reg FLAGS_REG)
903 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
904 (match_operand:HI 1 "general_operand" "rn,mr"))
906 "ix86_match_ccmode (insn, CCGOCmode)"
907 "cmp{w}\t{%1, %0|%0, %1}"
908 [(set_attr "type" "icmp")
909 (set_attr "mode" "HI")])
911 (define_insn "*cmphi_1"
912 [(set (reg FLAGS_REG)
913 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
914 (match_operand:HI 1 "general_operand" "rn,mr")))]
915 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916 && ix86_match_ccmode (insn, CCmode)"
917 "cmp{w}\t{%1, %0|%0, %1}"
918 [(set_attr "type" "icmp")
919 (set_attr "mode" "HI")])
921 (define_insn "*cmpqi_ccno_1"
922 [(set (reg FLAGS_REG)
923 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
924 (match_operand:QI 1 "const0_operand" "")))]
925 "ix86_match_ccmode (insn, CCNOmode)"
928 cmp{b}\t{$0, %0|%0, 0}"
929 [(set_attr "type" "test,icmp")
930 (set_attr "length_immediate" "0,1")
931 (set_attr "mode" "QI")])
933 (define_insn "*cmpqi_1"
934 [(set (reg FLAGS_REG)
935 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
936 (match_operand:QI 1 "general_operand" "qn,mq")))]
937 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
938 && ix86_match_ccmode (insn, CCmode)"
939 "cmp{b}\t{%1, %0|%0, %1}"
940 [(set_attr "type" "icmp")
941 (set_attr "mode" "QI")])
943 (define_insn "*cmpqi_minus_1"
944 [(set (reg FLAGS_REG)
945 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
946 (match_operand:QI 1 "general_operand" "qn,mq"))
948 "ix86_match_ccmode (insn, CCGOCmode)"
949 "cmp{b}\t{%1, %0|%0, %1}"
950 [(set_attr "type" "icmp")
951 (set_attr "mode" "QI")])
953 (define_insn "*cmpqi_ext_1"
954 [(set (reg FLAGS_REG)
956 (match_operand:QI 0 "general_operand" "Qm")
959 (match_operand 1 "ext_register_operand" "Q")
962 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
963 "cmp{b}\t{%h1, %0|%0, %h1}"
964 [(set_attr "type" "icmp")
965 (set_attr "mode" "QI")])
967 (define_insn "*cmpqi_ext_1_rex64"
968 [(set (reg FLAGS_REG)
970 (match_operand:QI 0 "register_operand" "Q")
973 (match_operand 1 "ext_register_operand" "Q")
976 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
977 "cmp{b}\t{%h1, %0|%0, %h1}"
978 [(set_attr "type" "icmp")
979 (set_attr "mode" "QI")])
981 (define_insn "*cmpqi_ext_2"
982 [(set (reg FLAGS_REG)
986 (match_operand 0 "ext_register_operand" "Q")
989 (match_operand:QI 1 "const0_operand" "")))]
990 "ix86_match_ccmode (insn, CCNOmode)"
992 [(set_attr "type" "test")
993 (set_attr "length_immediate" "0")
994 (set_attr "mode" "QI")])
996 (define_expand "cmpqi_ext_3"
997 [(set (reg:CC FLAGS_REG)
1001 (match_operand 0 "ext_register_operand" "")
1004 (match_operand:QI 1 "general_operand" "")))]
1008 (define_insn "cmpqi_ext_3_insn"
1009 [(set (reg FLAGS_REG)
1013 (match_operand 0 "ext_register_operand" "Q")
1016 (match_operand:QI 1 "general_operand" "Qmn")))]
1017 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018 "cmp{b}\t{%1, %h0|%h0, %1}"
1019 [(set_attr "type" "icmp")
1020 (set_attr "mode" "QI")])
1022 (define_insn "cmpqi_ext_3_insn_rex64"
1023 [(set (reg FLAGS_REG)
1027 (match_operand 0 "ext_register_operand" "Q")
1030 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1031 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1032 "cmp{b}\t{%1, %h0|%h0, %1}"
1033 [(set_attr "type" "icmp")
1034 (set_attr "mode" "QI")])
1036 (define_insn "*cmpqi_ext_4"
1037 [(set (reg FLAGS_REG)
1041 (match_operand 0 "ext_register_operand" "Q")
1046 (match_operand 1 "ext_register_operand" "Q")
1048 (const_int 8)) 0)))]
1049 "ix86_match_ccmode (insn, CCmode)"
1050 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1051 [(set_attr "type" "icmp")
1052 (set_attr "mode" "QI")])
1054 ;; These implement float point compares.
1055 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1056 ;; which would allow mix and match FP modes on the compares. Which is what
1057 ;; the old patterns did, but with many more of them.
1059 (define_expand "cmpxf"
1060 [(set (reg:CC FLAGS_REG)
1061 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1062 (match_operand:XF 1 "nonmemory_operand" "")))]
1065 ix86_compare_op0 = operands[0];
1066 ix86_compare_op1 = operands[1];
1070 (define_expand "cmp<mode>"
1071 [(set (reg:CC FLAGS_REG)
1072 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1073 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1074 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1076 ix86_compare_op0 = operands[0];
1077 ix86_compare_op1 = operands[1];
1081 ;; FP compares, step 1:
1082 ;; Set the FP condition codes.
1084 ;; CCFPmode compare with exceptions
1085 ;; CCFPUmode compare with no exceptions
1087 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1088 ;; used to manage the reg stack popping would not be preserved.
1090 (define_insn "*cmpfp_0"
1091 [(set (match_operand:HI 0 "register_operand" "=a")
1094 (match_operand 1 "register_operand" "f")
1095 (match_operand 2 "const0_operand" ""))]
1097 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1098 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1099 "* return output_fp_compare (insn, operands, 0, 0);"
1100 [(set_attr "type" "multi")
1101 (set_attr "unit" "i387")
1103 (cond [(match_operand:SF 1 "" "")
1105 (match_operand:DF 1 "" "")
1108 (const_string "XF")))])
1110 (define_insn_and_split "*cmpfp_0_cc"
1111 [(set (reg:CCFP FLAGS_REG)
1113 (match_operand 1 "register_operand" "f")
1114 (match_operand 2 "const0_operand" "")))
1115 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1117 && TARGET_SAHF && !TARGET_CMOVE
1118 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1120 "&& reload_completed"
1123 [(compare:CCFP (match_dup 1)(match_dup 2))]
1125 (set (reg:CC FLAGS_REG)
1126 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1128 [(set_attr "type" "multi")
1129 (set_attr "unit" "i387")
1131 (cond [(match_operand:SF 1 "" "")
1133 (match_operand:DF 1 "" "")
1136 (const_string "XF")))])
1138 (define_insn "*cmpfp_xf"
1139 [(set (match_operand:HI 0 "register_operand" "=a")
1142 (match_operand:XF 1 "register_operand" "f")
1143 (match_operand:XF 2 "register_operand" "f"))]
1146 "* return output_fp_compare (insn, operands, 0, 0);"
1147 [(set_attr "type" "multi")
1148 (set_attr "unit" "i387")
1149 (set_attr "mode" "XF")])
1151 (define_insn_and_split "*cmpfp_xf_cc"
1152 [(set (reg:CCFP FLAGS_REG)
1154 (match_operand:XF 1 "register_operand" "f")
1155 (match_operand:XF 2 "register_operand" "f")))
1156 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1158 && TARGET_SAHF && !TARGET_CMOVE"
1160 "&& reload_completed"
1163 [(compare:CCFP (match_dup 1)(match_dup 2))]
1165 (set (reg:CC FLAGS_REG)
1166 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1168 [(set_attr "type" "multi")
1169 (set_attr "unit" "i387")
1170 (set_attr "mode" "XF")])
1172 (define_insn "*cmpfp_<mode>"
1173 [(set (match_operand:HI 0 "register_operand" "=a")
1176 (match_operand:MODEF 1 "register_operand" "f")
1177 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1180 "* return output_fp_compare (insn, operands, 0, 0);"
1181 [(set_attr "type" "multi")
1182 (set_attr "unit" "i387")
1183 (set_attr "mode" "<MODE>")])
1185 (define_insn_and_split "*cmpfp_<mode>_cc"
1186 [(set (reg:CCFP FLAGS_REG)
1188 (match_operand:MODEF 1 "register_operand" "f")
1189 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1190 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1192 && TARGET_SAHF && !TARGET_CMOVE"
1194 "&& reload_completed"
1197 [(compare:CCFP (match_dup 1)(match_dup 2))]
1199 (set (reg:CC FLAGS_REG)
1200 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1202 [(set_attr "type" "multi")
1203 (set_attr "unit" "i387")
1204 (set_attr "mode" "<MODE>")])
1206 (define_insn "*cmpfp_u"
1207 [(set (match_operand:HI 0 "register_operand" "=a")
1210 (match_operand 1 "register_operand" "f")
1211 (match_operand 2 "register_operand" "f"))]
1213 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1215 "* return output_fp_compare (insn, operands, 0, 1);"
1216 [(set_attr "type" "multi")
1217 (set_attr "unit" "i387")
1219 (cond [(match_operand:SF 1 "" "")
1221 (match_operand:DF 1 "" "")
1224 (const_string "XF")))])
1226 (define_insn_and_split "*cmpfp_u_cc"
1227 [(set (reg:CCFPU FLAGS_REG)
1229 (match_operand 1 "register_operand" "f")
1230 (match_operand 2 "register_operand" "f")))
1231 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233 && TARGET_SAHF && !TARGET_CMOVE
1234 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1236 "&& reload_completed"
1239 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1241 (set (reg:CC FLAGS_REG)
1242 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1244 [(set_attr "type" "multi")
1245 (set_attr "unit" "i387")
1247 (cond [(match_operand:SF 1 "" "")
1249 (match_operand:DF 1 "" "")
1252 (const_string "XF")))])
1254 (define_insn "*cmpfp_<mode>"
1255 [(set (match_operand:HI 0 "register_operand" "=a")
1258 (match_operand 1 "register_operand" "f")
1259 (match_operator 3 "float_operator"
1260 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1262 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1263 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1264 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1265 "* return output_fp_compare (insn, operands, 0, 0);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1268 (set_attr "fp_int_src" "true")
1269 (set_attr "mode" "<MODE>")])
1271 (define_insn_and_split "*cmpfp_<mode>_cc"
1272 [(set (reg:CCFP FLAGS_REG)
1274 (match_operand 1 "register_operand" "f")
1275 (match_operator 3 "float_operator"
1276 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1281 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1283 "&& reload_completed"
1288 (match_op_dup 3 [(match_dup 2)]))]
1290 (set (reg:CC FLAGS_REG)
1291 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "fp_int_src" "true")
1296 (set_attr "mode" "<MODE>")])
1298 ;; FP compares, step 2
1299 ;; Move the fpsw to ax.
1301 (define_insn "x86_fnstsw_1"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1303 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1306 [(set_attr "length" "2")
1307 (set_attr "mode" "SI")
1308 (set_attr "unit" "i387")])
1310 ;; FP compares, step 3
1311 ;; Get ax into flags, general case.
1313 (define_insn "x86_sahf_1"
1314 [(set (reg:CC FLAGS_REG)
1315 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1319 #ifndef HAVE_AS_IX86_SAHF
1321 return ".byte\t0x9e";
1326 [(set_attr "length" "1")
1327 (set_attr "athlon_decode" "vector")
1328 (set_attr "amdfam10_decode" "direct")
1329 (set_attr "mode" "SI")])
1331 ;; Pentium Pro can do steps 1 through 3 in one go.
1332 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1333 (define_insn "*cmpfp_i_mixed"
1334 [(set (reg:CCFP FLAGS_REG)
1335 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1336 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1337 "TARGET_MIX_SSE_I387
1338 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1339 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1340 "* return output_fp_compare (insn, operands, 1, 0);"
1341 [(set_attr "type" "fcmp,ssecomi")
1342 (set_attr "prefix" "orig,maybe_vex")
1344 (if_then_else (match_operand:SF 1 "" "")
1346 (const_string "DF")))
1347 (set_attr "athlon_decode" "vector")
1348 (set_attr "amdfam10_decode" "direct")])
1350 (define_insn "*cmpfp_i_sse"
1351 [(set (reg:CCFP FLAGS_REG)
1352 (compare:CCFP (match_operand 0 "register_operand" "x")
1353 (match_operand 1 "nonimmediate_operand" "xm")))]
1355 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1356 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1357 "* return output_fp_compare (insn, operands, 1, 0);"
1358 [(set_attr "type" "ssecomi")
1359 (set_attr "prefix" "maybe_vex")
1361 (if_then_else (match_operand:SF 1 "" "")
1363 (const_string "DF")))
1364 (set_attr "athlon_decode" "vector")
1365 (set_attr "amdfam10_decode" "direct")])
1367 (define_insn "*cmpfp_i_i387"
1368 [(set (reg:CCFP FLAGS_REG)
1369 (compare:CCFP (match_operand 0 "register_operand" "f")
1370 (match_operand 1 "register_operand" "f")))]
1371 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1373 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1374 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1375 "* return output_fp_compare (insn, operands, 1, 0);"
1376 [(set_attr "type" "fcmp")
1378 (cond [(match_operand:SF 1 "" "")
1380 (match_operand:DF 1 "" "")
1383 (const_string "XF")))
1384 (set_attr "athlon_decode" "vector")
1385 (set_attr "amdfam10_decode" "direct")])
1387 (define_insn "*cmpfp_iu_mixed"
1388 [(set (reg:CCFPU FLAGS_REG)
1389 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1390 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1391 "TARGET_MIX_SSE_I387
1392 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1393 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1394 "* return output_fp_compare (insn, operands, 1, 1);"
1395 [(set_attr "type" "fcmp,ssecomi")
1396 (set_attr "prefix" "orig,maybe_vex")
1398 (if_then_else (match_operand:SF 1 "" "")
1400 (const_string "DF")))
1401 (set_attr "athlon_decode" "vector")
1402 (set_attr "amdfam10_decode" "direct")])
1404 (define_insn "*cmpfp_iu_sse"
1405 [(set (reg:CCFPU FLAGS_REG)
1406 (compare:CCFPU (match_operand 0 "register_operand" "x")
1407 (match_operand 1 "nonimmediate_operand" "xm")))]
1409 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1410 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1411 "* return output_fp_compare (insn, operands, 1, 1);"
1412 [(set_attr "type" "ssecomi")
1413 (set_attr "prefix" "maybe_vex")
1415 (if_then_else (match_operand:SF 1 "" "")
1417 (const_string "DF")))
1418 (set_attr "athlon_decode" "vector")
1419 (set_attr "amdfam10_decode" "direct")])
1421 (define_insn "*cmpfp_iu_387"
1422 [(set (reg:CCFPU FLAGS_REG)
1423 (compare:CCFPU (match_operand 0 "register_operand" "f")
1424 (match_operand 1 "register_operand" "f")))]
1425 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1427 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1428 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1429 "* return output_fp_compare (insn, operands, 1, 1);"
1430 [(set_attr "type" "fcmp")
1432 (cond [(match_operand:SF 1 "" "")
1434 (match_operand:DF 1 "" "")
1437 (const_string "XF")))
1438 (set_attr "athlon_decode" "vector")
1439 (set_attr "amdfam10_decode" "direct")])
1441 ;; Move instructions.
1443 ;; General case of fullword move.
1445 (define_expand "movsi"
1446 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1447 (match_operand:SI 1 "general_operand" ""))]
1449 "ix86_expand_move (SImode, operands); DONE;")
1451 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1454 ;; %%% We don't use a post-inc memory reference because x86 is not a
1455 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1456 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1457 ;; targets without our curiosities, and it is just as easy to represent
1458 ;; this differently.
1460 (define_insn "*pushsi2"
1461 [(set (match_operand:SI 0 "push_operand" "=<")
1462 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1465 [(set_attr "type" "push")
1466 (set_attr "mode" "SI")])
1468 ;; For 64BIT abi we always round up to 8 bytes.
1469 (define_insn "*pushsi2_rex64"
1470 [(set (match_operand:SI 0 "push_operand" "=X")
1471 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1474 [(set_attr "type" "push")
1475 (set_attr "mode" "SI")])
1477 (define_insn "*pushsi2_prologue"
1478 [(set (match_operand:SI 0 "push_operand" "=<")
1479 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1480 (clobber (mem:BLK (scratch)))]
1483 [(set_attr "type" "push")
1484 (set_attr "mode" "SI")])
1486 (define_insn "*popsi1_epilogue"
1487 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1488 (mem:SI (reg:SI SP_REG)))
1489 (set (reg:SI SP_REG)
1490 (plus:SI (reg:SI SP_REG) (const_int 4)))
1491 (clobber (mem:BLK (scratch)))]
1494 [(set_attr "type" "pop")
1495 (set_attr "mode" "SI")])
1497 (define_insn "popsi1"
1498 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1499 (mem:SI (reg:SI SP_REG)))
1500 (set (reg:SI SP_REG)
1501 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1504 [(set_attr "type" "pop")
1505 (set_attr "mode" "SI")])
1507 (define_insn "*movsi_xor"
1508 [(set (match_operand:SI 0 "register_operand" "=r")
1509 (match_operand:SI 1 "const0_operand" ""))
1510 (clobber (reg:CC FLAGS_REG))]
1513 [(set_attr "type" "alu1")
1514 (set_attr "mode" "SI")
1515 (set_attr "length_immediate" "0")])
1517 (define_insn "*movsi_or"
1518 [(set (match_operand:SI 0 "register_operand" "=r")
1519 (match_operand:SI 1 "immediate_operand" "i"))
1520 (clobber (reg:CC FLAGS_REG))]
1522 && operands[1] == constm1_rtx"
1524 operands[1] = constm1_rtx;
1525 return "or{l}\t{%1, %0|%0, %1}";
1527 [(set_attr "type" "alu1")
1528 (set_attr "mode" "SI")
1529 (set_attr "length_immediate" "1")])
1531 (define_insn "*movsi_1"
1532 [(set (match_operand:SI 0 "nonimmediate_operand"
1533 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1534 (match_operand:SI 1 "general_operand"
1535 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1536 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1538 switch (get_attr_type (insn))
1541 if (get_attr_mode (insn) == MODE_TI)
1542 return "%vpxor\t%0, %d0";
1543 return "%vxorps\t%0, %d0";
1546 switch (get_attr_mode (insn))
1549 return "%vmovdqa\t{%1, %0|%0, %1}";
1551 return "%vmovaps\t{%1, %0|%0, %1}";
1553 return "%vmovd\t{%1, %0|%0, %1}";
1555 return "%vmovss\t{%1, %0|%0, %1}";
1561 return "pxor\t%0, %0";
1564 if (get_attr_mode (insn) == MODE_DI)
1565 return "movq\t{%1, %0|%0, %1}";
1566 return "movd\t{%1, %0|%0, %1}";
1569 return "lea{l}\t{%a1, %0|%0, %a1}";
1572 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1573 return "mov{l}\t{%1, %0|%0, %1}";
1577 (cond [(eq_attr "alternative" "2")
1578 (const_string "mmx")
1579 (eq_attr "alternative" "3,4,5")
1580 (const_string "mmxmov")
1581 (eq_attr "alternative" "6")
1582 (const_string "sselog1")
1583 (eq_attr "alternative" "7,8,9,10,11")
1584 (const_string "ssemov")
1585 (match_operand:DI 1 "pic_32bit_operand" "")
1586 (const_string "lea")
1588 (const_string "imov")))
1589 (set (attr "prefix")
1590 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1591 (const_string "orig")
1592 (const_string "maybe_vex")))
1594 (cond [(eq_attr "alternative" "2,3")
1596 (eq_attr "alternative" "6,7")
1598 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1599 (const_string "V4SF")
1600 (const_string "TI"))
1601 (and (eq_attr "alternative" "8,9,10,11")
1602 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1605 (const_string "SI")))])
1607 ;; Stores and loads of ax to arbitrary constant address.
1608 ;; We fake an second form of instruction to force reload to load address
1609 ;; into register when rax is not available
1610 (define_insn "*movabssi_1_rex64"
1611 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1612 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1613 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1615 movabs{l}\t{%1, %P0|%P0, %1}
1616 mov{l}\t{%1, %a0|%a0, %1}"
1617 [(set_attr "type" "imov")
1618 (set_attr "modrm" "0,*")
1619 (set_attr "length_address" "8,0")
1620 (set_attr "length_immediate" "0,*")
1621 (set_attr "memory" "store")
1622 (set_attr "mode" "SI")])
1624 (define_insn "*movabssi_2_rex64"
1625 [(set (match_operand:SI 0 "register_operand" "=a,r")
1626 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1627 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1629 movabs{l}\t{%P1, %0|%0, %P1}
1630 mov{l}\t{%a1, %0|%0, %a1}"
1631 [(set_attr "type" "imov")
1632 (set_attr "modrm" "0,*")
1633 (set_attr "length_address" "8,0")
1634 (set_attr "length_immediate" "0")
1635 (set_attr "memory" "load")
1636 (set_attr "mode" "SI")])
1638 (define_insn "*swapsi"
1639 [(set (match_operand:SI 0 "register_operand" "+r")
1640 (match_operand:SI 1 "register_operand" "+r"))
1645 [(set_attr "type" "imov")
1646 (set_attr "mode" "SI")
1647 (set_attr "pent_pair" "np")
1648 (set_attr "athlon_decode" "vector")
1649 (set_attr "amdfam10_decode" "double")])
1651 (define_expand "movhi"
1652 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1653 (match_operand:HI 1 "general_operand" ""))]
1655 "ix86_expand_move (HImode, operands); DONE;")
1657 (define_insn "*pushhi2"
1658 [(set (match_operand:HI 0 "push_operand" "=X")
1659 (match_operand:HI 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 "*pushhi2_rex64"
1667 [(set (match_operand:HI 0 "push_operand" "=X")
1668 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "DI")])
1674 (define_insn "*movhi_1"
1675 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1676 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1677 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1679 switch (get_attr_type (insn))
1682 /* movzwl is faster than movw on p2 due to partial word stalls,
1683 though not as fast as an aligned movl. */
1684 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1686 if (get_attr_mode (insn) == MODE_SI)
1687 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1689 return "mov{w}\t{%1, %0|%0, %1}";
1693 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1694 (const_string "imov")
1695 (and (eq_attr "alternative" "0")
1696 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1698 (eq (symbol_ref "TARGET_HIMODE_MATH")
1700 (const_string "imov")
1701 (and (eq_attr "alternative" "1,2")
1702 (match_operand:HI 1 "aligned_operand" ""))
1703 (const_string "imov")
1704 (and (ne (symbol_ref "TARGET_MOVX")
1706 (eq_attr "alternative" "0,2"))
1707 (const_string "imovx")
1709 (const_string "imov")))
1711 (cond [(eq_attr "type" "imovx")
1713 (and (eq_attr "alternative" "1,2")
1714 (match_operand:HI 1 "aligned_operand" ""))
1716 (and (eq_attr "alternative" "0")
1717 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1719 (eq (symbol_ref "TARGET_HIMODE_MATH")
1723 (const_string "HI")))])
1725 ;; Stores and loads of ax to arbitrary constant address.
1726 ;; We fake an second form of instruction to force reload to load address
1727 ;; into register when rax is not available
1728 (define_insn "*movabshi_1_rex64"
1729 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1730 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1731 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1733 movabs{w}\t{%1, %P0|%P0, %1}
1734 mov{w}\t{%1, %a0|%a0, %1}"
1735 [(set_attr "type" "imov")
1736 (set_attr "modrm" "0,*")
1737 (set_attr "length_address" "8,0")
1738 (set_attr "length_immediate" "0,*")
1739 (set_attr "memory" "store")
1740 (set_attr "mode" "HI")])
1742 (define_insn "*movabshi_2_rex64"
1743 [(set (match_operand:HI 0 "register_operand" "=a,r")
1744 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1745 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1747 movabs{w}\t{%P1, %0|%0, %P1}
1748 mov{w}\t{%a1, %0|%0, %a1}"
1749 [(set_attr "type" "imov")
1750 (set_attr "modrm" "0,*")
1751 (set_attr "length_address" "8,0")
1752 (set_attr "length_immediate" "0")
1753 (set_attr "memory" "load")
1754 (set_attr "mode" "HI")])
1756 (define_insn "*swaphi_1"
1757 [(set (match_operand:HI 0 "register_operand" "+r")
1758 (match_operand:HI 1 "register_operand" "+r"))
1761 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1763 [(set_attr "type" "imov")
1764 (set_attr "mode" "SI")
1765 (set_attr "pent_pair" "np")
1766 (set_attr "athlon_decode" "vector")
1767 (set_attr "amdfam10_decode" "double")])
1769 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1770 (define_insn "*swaphi_2"
1771 [(set (match_operand:HI 0 "register_operand" "+r")
1772 (match_operand:HI 1 "register_operand" "+r"))
1775 "TARGET_PARTIAL_REG_STALL"
1777 [(set_attr "type" "imov")
1778 (set_attr "mode" "HI")
1779 (set_attr "pent_pair" "np")
1780 (set_attr "athlon_decode" "vector")])
1782 (define_expand "movstricthi"
1783 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1784 (match_operand:HI 1 "general_operand" ""))]
1787 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1789 /* Don't generate memory->memory moves, go through a register */
1790 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1791 operands[1] = force_reg (HImode, operands[1]);
1794 (define_insn "*movstricthi_1"
1795 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1796 (match_operand:HI 1 "general_operand" "rn,m"))]
1797 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1799 "mov{w}\t{%1, %0|%0, %1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "HI")])
1803 (define_insn "*movstricthi_xor"
1804 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1805 (match_operand:HI 1 "const0_operand" ""))
1806 (clobber (reg:CC FLAGS_REG))]
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "HI")
1811 (set_attr "length_immediate" "0")])
1813 (define_expand "movqi"
1814 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1815 (match_operand:QI 1 "general_operand" ""))]
1817 "ix86_expand_move (QImode, operands); DONE;")
1819 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1820 ;; "push a byte". But actually we use pushl, which has the effect
1821 ;; of rounding the amount pushed up to a word.
1823 (define_insn "*pushqi2"
1824 [(set (match_operand:QI 0 "push_operand" "=X")
1825 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1828 [(set_attr "type" "push")
1829 (set_attr "mode" "SI")])
1831 ;; For 64BIT abi we always round up to 8 bytes.
1832 (define_insn "*pushqi2_rex64"
1833 [(set (match_operand:QI 0 "push_operand" "=X")
1834 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1837 [(set_attr "type" "push")
1838 (set_attr "mode" "DI")])
1840 ;; Situation is quite tricky about when to choose full sized (SImode) move
1841 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1842 ;; partial register dependency machines (such as AMD Athlon), where QImode
1843 ;; moves issue extra dependency and for partial register stalls machines
1844 ;; that don't use QImode patterns (and QImode move cause stall on the next
1847 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1848 ;; register stall machines with, where we use QImode instructions, since
1849 ;; partial register stall can be caused there. Then we use movzx.
1850 (define_insn "*movqi_1"
1851 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1852 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1853 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855 switch (get_attr_type (insn))
1858 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1859 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1861 if (get_attr_mode (insn) == MODE_SI)
1862 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1864 return "mov{b}\t{%1, %0|%0, %1}";
1868 (cond [(and (eq_attr "alternative" "5")
1869 (not (match_operand:QI 1 "aligned_operand" "")))
1870 (const_string "imovx")
1871 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1872 (const_string "imov")
1873 (and (eq_attr "alternative" "3")
1874 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1876 (eq (symbol_ref "TARGET_QIMODE_MATH")
1878 (const_string "imov")
1879 (eq_attr "alternative" "3,5")
1880 (const_string "imovx")
1881 (and (ne (symbol_ref "TARGET_MOVX")
1883 (eq_attr "alternative" "2"))
1884 (const_string "imovx")
1886 (const_string "imov")))
1888 (cond [(eq_attr "alternative" "3,4,5")
1890 (eq_attr "alternative" "6")
1892 (eq_attr "type" "imovx")
1894 (and (eq_attr "type" "imov")
1895 (and (eq_attr "alternative" "0,1")
1896 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1898 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1900 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1903 ;; Avoid partial register stalls when not using QImode arithmetic
1904 (and (eq_attr "type" "imov")
1905 (and (eq_attr "alternative" "0,1")
1906 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1908 (eq (symbol_ref "TARGET_QIMODE_MATH")
1912 (const_string "QI")))])
1914 (define_insn "*swapqi_1"
1915 [(set (match_operand:QI 0 "register_operand" "+r")
1916 (match_operand:QI 1 "register_operand" "+r"))
1919 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1921 [(set_attr "type" "imov")
1922 (set_attr "mode" "SI")
1923 (set_attr "pent_pair" "np")
1924 (set_attr "athlon_decode" "vector")
1925 (set_attr "amdfam10_decode" "vector")])
1927 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1928 (define_insn "*swapqi_2"
1929 [(set (match_operand:QI 0 "register_operand" "+q")
1930 (match_operand:QI 1 "register_operand" "+q"))
1933 "TARGET_PARTIAL_REG_STALL"
1935 [(set_attr "type" "imov")
1936 (set_attr "mode" "QI")
1937 (set_attr "pent_pair" "np")
1938 (set_attr "athlon_decode" "vector")])
1940 (define_expand "movstrictqi"
1941 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1942 (match_operand:QI 1 "general_operand" ""))]
1945 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1947 /* Don't generate memory->memory moves, go through a register. */
1948 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1949 operands[1] = force_reg (QImode, operands[1]);
1952 (define_insn "*movstrictqi_1"
1953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1954 (match_operand:QI 1 "general_operand" "*qn,m"))]
1955 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1956 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1957 "mov{b}\t{%1, %0|%0, %1}"
1958 [(set_attr "type" "imov")
1959 (set_attr "mode" "QI")])
1961 (define_insn "*movstrictqi_xor"
1962 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1963 (match_operand:QI 1 "const0_operand" ""))
1964 (clobber (reg:CC FLAGS_REG))]
1967 [(set_attr "type" "alu1")
1968 (set_attr "mode" "QI")
1969 (set_attr "length_immediate" "0")])
1971 (define_insn "*movsi_extv_1"
1972 [(set (match_operand:SI 0 "register_operand" "=R")
1973 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1977 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1978 [(set_attr "type" "imovx")
1979 (set_attr "mode" "SI")])
1981 (define_insn "*movhi_extv_1"
1982 [(set (match_operand:HI 0 "register_operand" "=R")
1983 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1987 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1988 [(set_attr "type" "imovx")
1989 (set_attr "mode" "SI")])
1991 (define_insn "*movqi_extv_1"
1992 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1993 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1998 switch (get_attr_type (insn))
2001 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2003 return "mov{b}\t{%h1, %0|%0, %h1}";
2007 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2008 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2009 (ne (symbol_ref "TARGET_MOVX")
2011 (const_string "imovx")
2012 (const_string "imov")))
2014 (if_then_else (eq_attr "type" "imovx")
2016 (const_string "QI")))])
2018 (define_insn "*movqi_extv_1_rex64"
2019 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2020 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2025 switch (get_attr_type (insn))
2028 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2030 return "mov{b}\t{%h1, %0|%0, %h1}";
2034 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2035 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2036 (ne (symbol_ref "TARGET_MOVX")
2038 (const_string "imovx")
2039 (const_string "imov")))
2041 (if_then_else (eq_attr "type" "imovx")
2043 (const_string "QI")))])
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsqi_1_rex64"
2049 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2053 movabs{b}\t{%1, %P0|%P0, %1}
2054 mov{b}\t{%1, %a0|%a0, %1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0,*")
2059 (set_attr "memory" "store")
2060 (set_attr "mode" "QI")])
2062 (define_insn "*movabsqi_2_rex64"
2063 [(set (match_operand:QI 0 "register_operand" "=a,r")
2064 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2067 movabs{b}\t{%P1, %0|%0, %P1}
2068 mov{b}\t{%a1, %0|%0, %a1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "modrm" "0,*")
2071 (set_attr "length_address" "8,0")
2072 (set_attr "length_immediate" "0")
2073 (set_attr "memory" "load")
2074 (set_attr "mode" "QI")])
2076 (define_insn "*movdi_extzv_1"
2077 [(set (match_operand:DI 0 "register_operand" "=R")
2078 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2082 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2083 [(set_attr "type" "imovx")
2084 (set_attr "mode" "DI")])
2086 (define_insn "*movsi_extzv_1"
2087 [(set (match_operand:SI 0 "register_operand" "=R")
2088 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2092 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2093 [(set_attr "type" "imovx")
2094 (set_attr "mode" "SI")])
2096 (define_insn "*movqi_extzv_2"
2097 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2098 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2103 switch (get_attr_type (insn))
2106 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2108 return "mov{b}\t{%h1, %0|%0, %h1}";
2112 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2113 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2114 (ne (symbol_ref "TARGET_MOVX")
2116 (const_string "imovx")
2117 (const_string "imov")))
2119 (if_then_else (eq_attr "type" "imovx")
2121 (const_string "QI")))])
2123 (define_insn "*movqi_extzv_2_rex64"
2124 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2125 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2130 switch (get_attr_type (insn))
2133 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2135 return "mov{b}\t{%h1, %0|%0, %h1}";
2139 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2140 (ne (symbol_ref "TARGET_MOVX")
2142 (const_string "imovx")
2143 (const_string "imov")))
2145 (if_then_else (eq_attr "type" "imovx")
2147 (const_string "QI")))])
2149 (define_insn "movsi_insv_1"
2150 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2153 (match_operand:SI 1 "general_operand" "Qmn"))]
2155 "mov{b}\t{%b1, %h0|%h0, %b1}"
2156 [(set_attr "type" "imov")
2157 (set_attr "mode" "QI")])
2159 (define_insn "*movsi_insv_1_rex64"
2160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2163 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2165 "mov{b}\t{%b1, %h0|%h0, %b1}"
2166 [(set_attr "type" "imov")
2167 (set_attr "mode" "QI")])
2169 (define_insn "movdi_insv_1_rex64"
2170 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2173 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2175 "mov{b}\t{%b1, %h0|%h0, %b1}"
2176 [(set_attr "type" "imov")
2177 (set_attr "mode" "QI")])
2179 (define_insn "*movqi_insv_2"
2180 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2183 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2186 "mov{b}\t{%h1, %h0|%h0, %h1}"
2187 [(set_attr "type" "imov")
2188 (set_attr "mode" "QI")])
2190 (define_expand "movdi"
2191 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2192 (match_operand:DI 1 "general_operand" ""))]
2194 "ix86_expand_move (DImode, operands); DONE;")
2196 (define_insn "*pushdi"
2197 [(set (match_operand:DI 0 "push_operand" "=<")
2198 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2202 (define_insn "*pushdi2_rex64"
2203 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2204 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2209 [(set_attr "type" "push,multi")
2210 (set_attr "mode" "DI")])
2212 ;; Convert impossible pushes of immediate to existing instructions.
2213 ;; First try to get scratch register and go through it. In case this
2214 ;; fails, push sign extended lower part first and then overwrite
2215 ;; upper part by 32bit move.
2217 [(match_scratch:DI 2 "r")
2218 (set (match_operand:DI 0 "push_operand" "")
2219 (match_operand:DI 1 "immediate_operand" ""))]
2220 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2221 && !x86_64_immediate_operand (operands[1], DImode)"
2222 [(set (match_dup 2) (match_dup 1))
2223 (set (match_dup 0) (match_dup 2))]
2226 ;; We need to define this as both peepholer and splitter for case
2227 ;; peephole2 pass is not run.
2228 ;; "&& 1" is needed to keep it from matching the previous pattern.
2230 [(set (match_operand:DI 0 "push_operand" "")
2231 (match_operand:DI 1 "immediate_operand" ""))]
2232 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2233 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2234 [(set (match_dup 0) (match_dup 1))
2235 (set (match_dup 2) (match_dup 3))]
2236 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2237 operands[1] = gen_lowpart (DImode, operands[2]);
2238 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2243 [(set (match_operand:DI 0 "push_operand" "")
2244 (match_operand:DI 1 "immediate_operand" ""))]
2245 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2246 ? epilogue_completed : reload_completed)
2247 && !symbolic_operand (operands[1], DImode)
2248 && !x86_64_immediate_operand (operands[1], DImode)"
2249 [(set (match_dup 0) (match_dup 1))
2250 (set (match_dup 2) (match_dup 3))]
2251 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2252 operands[1] = gen_lowpart (DImode, operands[2]);
2253 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2257 (define_insn "*pushdi2_prologue_rex64"
2258 [(set (match_operand:DI 0 "push_operand" "=<")
2259 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2260 (clobber (mem:BLK (scratch)))]
2263 [(set_attr "type" "push")
2264 (set_attr "mode" "DI")])
2266 (define_insn "*popdi1_epilogue_rex64"
2267 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2268 (mem:DI (reg:DI SP_REG)))
2269 (set (reg:DI SP_REG)
2270 (plus:DI (reg:DI SP_REG) (const_int 8)))
2271 (clobber (mem:BLK (scratch)))]
2274 [(set_attr "type" "pop")
2275 (set_attr "mode" "DI")])
2277 (define_insn "popdi1"
2278 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2279 (mem:DI (reg:DI SP_REG)))
2280 (set (reg:DI SP_REG)
2281 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2284 [(set_attr "type" "pop")
2285 (set_attr "mode" "DI")])
2287 (define_insn "*movdi_xor_rex64"
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (match_operand:DI 1 "const0_operand" ""))
2290 (clobber (reg:CC FLAGS_REG))]
2292 && reload_completed"
2294 [(set_attr "type" "alu1")
2295 (set_attr "mode" "SI")
2296 (set_attr "length_immediate" "0")])
2298 (define_insn "*movdi_or_rex64"
2299 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (match_operand:DI 1 "const_int_operand" "i"))
2301 (clobber (reg:CC FLAGS_REG))]
2304 && operands[1] == constm1_rtx"
2306 operands[1] = constm1_rtx;
2307 return "or{q}\t{%1, %0|%0, %1}";
2309 [(set_attr "type" "alu1")
2310 (set_attr "mode" "DI")
2311 (set_attr "length_immediate" "1")])
2313 (define_insn "*movdi_2"
2314 [(set (match_operand:DI 0 "nonimmediate_operand"
2315 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2316 (match_operand:DI 1 "general_operand"
2317 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2318 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2323 movq\t{%1, %0|%0, %1}
2324 movq\t{%1, %0|%0, %1}
2326 %vmovq\t{%1, %0|%0, %1}
2327 %vmovdqa\t{%1, %0|%0, %1}
2328 %vmovq\t{%1, %0|%0, %1}
2330 movlps\t{%1, %0|%0, %1}
2331 movaps\t{%1, %0|%0, %1}
2332 movlps\t{%1, %0|%0, %1}"
2333 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2334 (set (attr "prefix")
2335 (if_then_else (eq_attr "alternative" "5,6,7,8")
2336 (const_string "vex")
2337 (const_string "orig")))
2338 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2341 [(set (match_operand:DI 0 "push_operand" "")
2342 (match_operand:DI 1 "general_operand" ""))]
2343 "!TARGET_64BIT && reload_completed
2344 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2346 "ix86_split_long_move (operands); DONE;")
2348 ;; %%% This multiword shite has got to go.
2350 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2351 (match_operand:DI 1 "general_operand" ""))]
2352 "!TARGET_64BIT && reload_completed
2353 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2354 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2356 "ix86_split_long_move (operands); DONE;")
2358 (define_insn "*movdi_1_rex64"
2359 [(set (match_operand:DI 0 "nonimmediate_operand"
2360 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2361 (match_operand:DI 1 "general_operand"
2362 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2363 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2365 switch (get_attr_type (insn))
2368 if (SSE_REG_P (operands[0]))
2369 return "movq2dq\t{%1, %0|%0, %1}";
2371 return "movdq2q\t{%1, %0|%0, %1}";
2376 if (get_attr_mode (insn) == MODE_TI)
2377 return "vmovdqa\t{%1, %0|%0, %1}";
2379 return "vmovq\t{%1, %0|%0, %1}";
2382 if (get_attr_mode (insn) == MODE_TI)
2383 return "movdqa\t{%1, %0|%0, %1}";
2387 /* Moves from and into integer register is done using movd
2388 opcode with REX prefix. */
2389 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2390 return "movd\t{%1, %0|%0, %1}";
2391 return "movq\t{%1, %0|%0, %1}";
2394 return "%vpxor\t%0, %d0";
2397 return "pxor\t%0, %0";
2403 return "lea{q}\t{%a1, %0|%0, %a1}";
2406 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2407 if (get_attr_mode (insn) == MODE_SI)
2408 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2409 else if (which_alternative == 2)
2410 return "movabs{q}\t{%1, %0|%0, %1}";
2412 return "mov{q}\t{%1, %0|%0, %1}";
2416 (cond [(eq_attr "alternative" "5")
2417 (const_string "mmx")
2418 (eq_attr "alternative" "6,7,8,9,10")
2419 (const_string "mmxmov")
2420 (eq_attr "alternative" "11")
2421 (const_string "sselog1")
2422 (eq_attr "alternative" "12,13,14,15,16")
2423 (const_string "ssemov")
2424 (eq_attr "alternative" "17,18")
2425 (const_string "ssecvt")
2426 (eq_attr "alternative" "4")
2427 (const_string "multi")
2428 (match_operand:DI 1 "pic_32bit_operand" "")
2429 (const_string "lea")
2431 (const_string "imov")))
2432 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2433 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2434 (set (attr "prefix")
2435 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2436 (const_string "maybe_vex")
2437 (const_string "orig")))
2438 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2440 ;; Stores and loads of ax to arbitrary constant address.
2441 ;; We fake an second form of instruction to force reload to load address
2442 ;; into register when rax is not available
2443 (define_insn "*movabsdi_1_rex64"
2444 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2445 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2446 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2448 movabs{q}\t{%1, %P0|%P0, %1}
2449 mov{q}\t{%1, %a0|%a0, %1}"
2450 [(set_attr "type" "imov")
2451 (set_attr "modrm" "0,*")
2452 (set_attr "length_address" "8,0")
2453 (set_attr "length_immediate" "0,*")
2454 (set_attr "memory" "store")
2455 (set_attr "mode" "DI")])
2457 (define_insn "*movabsdi_2_rex64"
2458 [(set (match_operand:DI 0 "register_operand" "=a,r")
2459 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2460 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2462 movabs{q}\t{%P1, %0|%0, %P1}
2463 mov{q}\t{%a1, %0|%0, %a1}"
2464 [(set_attr "type" "imov")
2465 (set_attr "modrm" "0,*")
2466 (set_attr "length_address" "8,0")
2467 (set_attr "length_immediate" "0")
2468 (set_attr "memory" "load")
2469 (set_attr "mode" "DI")])
2471 ;; Convert impossible stores of immediate to existing instructions.
2472 ;; First try to get scratch register and go through it. In case this
2473 ;; fails, move by 32bit parts.
2475 [(match_scratch:DI 2 "r")
2476 (set (match_operand:DI 0 "memory_operand" "")
2477 (match_operand:DI 1 "immediate_operand" ""))]
2478 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2479 && !x86_64_immediate_operand (operands[1], DImode)"
2480 [(set (match_dup 2) (match_dup 1))
2481 (set (match_dup 0) (match_dup 2))]
2484 ;; We need to define this as both peepholer and splitter for case
2485 ;; peephole2 pass is not run.
2486 ;; "&& 1" is needed to keep it from matching the previous pattern.
2488 [(set (match_operand:DI 0 "memory_operand" "")
2489 (match_operand:DI 1 "immediate_operand" ""))]
2490 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2491 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2492 [(set (match_dup 2) (match_dup 3))
2493 (set (match_dup 4) (match_dup 5))]
2494 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2497 [(set (match_operand:DI 0 "memory_operand" "")
2498 (match_operand:DI 1 "immediate_operand" ""))]
2499 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2500 ? epilogue_completed : reload_completed)
2501 && !symbolic_operand (operands[1], DImode)
2502 && !x86_64_immediate_operand (operands[1], DImode)"
2503 [(set (match_dup 2) (match_dup 3))
2504 (set (match_dup 4) (match_dup 5))]
2505 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2507 (define_insn "*swapdi_rex64"
2508 [(set (match_operand:DI 0 "register_operand" "+r")
2509 (match_operand:DI 1 "register_operand" "+r"))
2514 [(set_attr "type" "imov")
2515 (set_attr "mode" "DI")
2516 (set_attr "pent_pair" "np")
2517 (set_attr "athlon_decode" "vector")
2518 (set_attr "amdfam10_decode" "double")])
2520 (define_expand "movoi"
2521 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2522 (match_operand:OI 1 "general_operand" ""))]
2524 "ix86_expand_move (OImode, operands); DONE;")
2526 (define_insn "*movoi_internal"
2527 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2528 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2530 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2532 switch (which_alternative)
2535 return "vxorps\t%0, %0, %0";
2538 if (misaligned_operand (operands[0], OImode)
2539 || misaligned_operand (operands[1], OImode))
2540 return "vmovdqu\t{%1, %0|%0, %1}";
2542 return "vmovdqa\t{%1, %0|%0, %1}";
2547 [(set_attr "type" "sselog1,ssemov,ssemov")
2548 (set_attr "prefix" "vex")
2549 (set_attr "mode" "OI")])
2551 (define_expand "movti"
2552 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2553 (match_operand:TI 1 "nonimmediate_operand" ""))]
2554 "TARGET_SSE || TARGET_64BIT"
2557 ix86_expand_move (TImode, operands);
2558 else if (push_operand (operands[0], TImode))
2559 ix86_expand_push (TImode, operands[1]);
2561 ix86_expand_vector_move (TImode, operands);
2565 (define_insn "*pushti"
2566 [(set (match_operand:TI 0 "push_operand" "=<")
2567 (match_operand:TI 1 "general_no_elim_operand" "riF*m"))]
2571 (define_insn "*movti_internal"
2572 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2573 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2574 "TARGET_SSE && !TARGET_64BIT
2575 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2577 switch (which_alternative)
2580 if (get_attr_mode (insn) == MODE_V4SF)
2581 return "%vxorps\t%0, %d0";
2583 return "%vpxor\t%0, %d0";
2586 /* TDmode values are passed as TImode on the stack. Moving them
2587 to stack may result in unaligned memory access. */
2588 if (misaligned_operand (operands[0], TImode)
2589 || misaligned_operand (operands[1], TImode))
2591 if (get_attr_mode (insn) == MODE_V4SF)
2592 return "%vmovups\t{%1, %0|%0, %1}";
2594 return "%vmovdqu\t{%1, %0|%0, %1}";
2598 if (get_attr_mode (insn) == MODE_V4SF)
2599 return "%vmovaps\t{%1, %0|%0, %1}";
2601 return "%vmovdqa\t{%1, %0|%0, %1}";
2607 [(set_attr "type" "sselog1,ssemov,ssemov")
2608 (set_attr "prefix" "maybe_vex")
2610 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2611 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2612 (const_string "V4SF")
2613 (and (eq_attr "alternative" "2")
2614 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2616 (const_string "V4SF")]
2617 (const_string "TI")))])
2619 (define_insn "*movti_rex64"
2620 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2621 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2625 switch (which_alternative)
2631 if (get_attr_mode (insn) == MODE_V4SF)
2632 return "%vxorps\t%0, %d0";
2634 return "%vpxor\t%0, %d0";
2637 /* TDmode values are passed as TImode on the stack. Moving them
2638 to stack may result in unaligned memory access. */
2639 if (misaligned_operand (operands[0], TImode)
2640 || misaligned_operand (operands[1], TImode))
2642 if (get_attr_mode (insn) == MODE_V4SF)
2643 return "%vmovups\t{%1, %0|%0, %1}";
2645 return "%vmovdqu\t{%1, %0|%0, %1}";
2649 if (get_attr_mode (insn) == MODE_V4SF)
2650 return "%vmovaps\t{%1, %0|%0, %1}";
2652 return "%vmovdqa\t{%1, %0|%0, %1}";
2658 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2659 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2661 (cond [(eq_attr "alternative" "2,3")
2663 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2665 (const_string "V4SF")
2666 (const_string "TI"))
2667 (eq_attr "alternative" "4")
2669 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2671 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2673 (const_string "V4SF")
2674 (const_string "TI"))]
2675 (const_string "DI")))])
2678 [(set (match_operand:TI 0 "push_operand" "")
2679 (match_operand:TI 1 "general_operand" ""))]
2680 "TARGET_64BIT && reload_completed
2681 && !SSE_REG_P (operands[1])"
2683 "ix86_split_long_move (operands); DONE;")
2686 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2687 (match_operand:TI 1 "general_operand" ""))]
2688 "reload_completed && !SSE_REG_P (operands[0])
2689 && !SSE_REG_P (operands[1])"
2691 "ix86_split_long_move (operands); DONE;")
2693 ;; This expands to what emit_move_complex would generate if we didn't
2694 ;; have a movti pattern. Having this avoids problems with reload on
2695 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2696 ;; to have around all the time.
2697 (define_expand "movcdi"
2698 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2699 (match_operand:CDI 1 "general_operand" ""))]
2702 if (push_operand (operands[0], CDImode))
2703 emit_move_complex_push (CDImode, operands[0], operands[1]);
2705 emit_move_complex_parts (operands[0], operands[1]);
2709 (define_expand "movsf"
2710 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2711 (match_operand:SF 1 "general_operand" ""))]
2713 "ix86_expand_move (SFmode, operands); DONE;")
2715 (define_insn "*pushsf"
2716 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2717 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2720 /* Anything else should be already split before reg-stack. */
2721 gcc_assert (which_alternative == 1);
2722 return "push{l}\t%1";
2724 [(set_attr "type" "multi,push,multi")
2725 (set_attr "unit" "i387,*,*")
2726 (set_attr "mode" "SF,SI,SF")])
2728 (define_insn "*pushsf_rex64"
2729 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2730 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2733 /* Anything else should be already split before reg-stack. */
2734 gcc_assert (which_alternative == 1);
2735 return "push{q}\t%q1";
2737 [(set_attr "type" "multi,push,multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "SF,DI,SF")])
2742 [(set (match_operand:SF 0 "push_operand" "")
2743 (match_operand:SF 1 "memory_operand" ""))]
2745 && MEM_P (operands[1])
2746 && (operands[2] = find_constant_src (insn))"
2751 ;; %%% Kill this when call knows how to work this out.
2753 [(set (match_operand:SF 0 "push_operand" "")
2754 (match_operand:SF 1 "any_fp_register_operand" ""))]
2756 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2757 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2760 [(set (match_operand:SF 0 "push_operand" "")
2761 (match_operand:SF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2764 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2766 (define_insn "*movsf_1"
2767 [(set (match_operand:SF 0 "nonimmediate_operand"
2768 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2769 (match_operand:SF 1 "general_operand"
2770 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2771 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2772 && (reload_in_progress || reload_completed
2773 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2774 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2775 && standard_80387_constant_p (operands[1]))
2776 || GET_CODE (operands[1]) != CONST_DOUBLE
2777 || memory_operand (operands[0], SFmode))"
2779 switch (which_alternative)
2783 return output_387_reg_move (insn, operands);
2786 return standard_80387_constant_opcode (operands[1]);
2790 return "mov{l}\t{%1, %0|%0, %1}";
2792 if (get_attr_mode (insn) == MODE_TI)
2793 return "%vpxor\t%0, %d0";
2795 return "%vxorps\t%0, %d0";
2797 if (get_attr_mode (insn) == MODE_V4SF)
2798 return "%vmovaps\t{%1, %0|%0, %1}";
2800 return "%vmovss\t{%1, %d0|%d0, %1}";
2803 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2804 : "vmovss\t{%1, %0|%0, %1}";
2806 return "movss\t{%1, %0|%0, %1}";
2808 return "%vmovss\t{%1, %0|%0, %1}";
2810 case 9: case 10: case 14: case 15:
2811 return "movd\t{%1, %0|%0, %1}";
2813 return "%vmovd\t{%1, %0|%0, %1}";
2816 return "movq\t{%1, %0|%0, %1}";
2822 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2823 (set (attr "prefix")
2824 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2825 (const_string "maybe_vex")
2826 (const_string "orig")))
2828 (cond [(eq_attr "alternative" "3,4,9,10")
2830 (eq_attr "alternative" "5")
2832 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834 (ne (symbol_ref "TARGET_SSE2")
2836 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2839 (const_string "V4SF"))
2840 /* For architectures resolving dependencies on
2841 whole SSE registers use APS move to break dependency
2842 chains, otherwise use short move to avoid extra work.
2844 Do the same for architectures resolving dependencies on
2845 the parts. While in DF mode it is better to always handle
2846 just register parts, the SF mode is different due to lack
2847 of instructions to load just part of the register. It is
2848 better to maintain the whole registers in single format
2849 to avoid problems on using packed logical operations. */
2850 (eq_attr "alternative" "6")
2852 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2854 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2856 (const_string "V4SF")
2857 (const_string "SF"))
2858 (eq_attr "alternative" "11")
2859 (const_string "DI")]
2860 (const_string "SF")))])
2862 (define_insn "*swapsf"
2863 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2864 (match_operand:SF 1 "fp_register_operand" "+f"))
2867 "reload_completed || TARGET_80387"
2869 if (STACK_TOP_P (operands[0]))
2874 [(set_attr "type" "fxch")
2875 (set_attr "mode" "SF")])
2877 (define_expand "movdf"
2878 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2879 (match_operand:DF 1 "general_operand" ""))]
2881 "ix86_expand_move (DFmode, operands); DONE;")
2883 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2884 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2885 ;; On the average, pushdf using integers can be still shorter. Allow this
2886 ;; pattern for optimize_size too.
2888 (define_insn "*pushdf_nointeger"
2889 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2890 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2891 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2893 /* This insn should be already split before reg-stack. */
2896 [(set_attr "type" "multi")
2897 (set_attr "unit" "i387,*,*,*")
2898 (set_attr "mode" "DF,SI,SI,DF")])
2900 (define_insn "*pushdf_integer"
2901 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2902 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2903 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2905 /* This insn should be already split before reg-stack. */
2908 [(set_attr "type" "multi")
2909 (set_attr "unit" "i387,*,*")
2910 (set_attr "mode" "DF,SI,DF")])
2912 ;; %%% Kill this when call knows how to work this out.
2914 [(set (match_operand:DF 0 "push_operand" "")
2915 (match_operand:DF 1 "any_fp_register_operand" ""))]
2917 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2918 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2922 [(set (match_operand:DF 0 "push_operand" "")
2923 (match_operand:DF 1 "general_operand" ""))]
2926 "ix86_split_long_move (operands); DONE;")
2928 ;; Moving is usually shorter when only FP registers are used. This separate
2929 ;; movdf pattern avoids the use of integer registers for FP operations
2930 ;; when optimizing for size.
2932 (define_insn "*movdf_nointeger"
2933 [(set (match_operand:DF 0 "nonimmediate_operand"
2934 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2935 (match_operand:DF 1 "general_operand"
2936 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2937 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2938 && ((optimize_function_for_size_p (cfun)
2939 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2940 && (reload_in_progress || reload_completed
2941 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2942 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2943 && optimize_function_for_size_p (cfun)
2944 && !memory_operand (operands[0], DFmode)
2945 && standard_80387_constant_p (operands[1]))
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || ((optimize_function_for_size_p (cfun)
2948 || !TARGET_MEMORY_MISMATCH_STALL
2949 || reload_in_progress || reload_completed)
2950 && memory_operand (operands[0], DFmode)))"
2952 switch (which_alternative)
2956 return output_387_reg_move (insn, operands);
2959 return standard_80387_constant_opcode (operands[1]);
2965 switch (get_attr_mode (insn))
2968 return "%vxorps\t%0, %d0";
2970 return "%vxorpd\t%0, %d0";
2972 return "%vpxor\t%0, %d0";
2979 switch (get_attr_mode (insn))
2982 return "%vmovaps\t{%1, %0|%0, %1}";
2984 return "%vmovapd\t{%1, %0|%0, %1}";
2986 return "%vmovdqa\t{%1, %0|%0, %1}";
2988 return "%vmovq\t{%1, %0|%0, %1}";
2992 if (REG_P (operands[0]) && REG_P (operands[1]))
2993 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2995 return "vmovsd\t{%1, %0|%0, %1}";
2998 return "movsd\t{%1, %0|%0, %1}";
3002 if (REG_P (operands[0]))
3003 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3005 return "vmovlpd\t{%1, %0|%0, %1}";
3008 return "movlpd\t{%1, %0|%0, %1}";
3012 if (REG_P (operands[0]))
3013 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3015 return "vmovlps\t{%1, %0|%0, %1}";
3018 return "movlps\t{%1, %0|%0, %1}";
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3028 (set (attr "prefix")
3029 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3030 (const_string "orig")
3031 (const_string "maybe_vex")))
3033 (cond [(eq_attr "alternative" "0,1,2")
3035 (eq_attr "alternative" "3,4")
3038 /* For SSE1, we have many fewer alternatives. */
3039 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3040 (cond [(eq_attr "alternative" "5,6")
3041 (const_string "V4SF")
3043 (const_string "V2SF"))
3045 /* xorps is one byte shorter. */
3046 (eq_attr "alternative" "5")
3047 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3049 (const_string "V4SF")
3050 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3054 (const_string "V2DF"))
3056 /* For architectures resolving dependencies on
3057 whole SSE registers use APD move to break dependency
3058 chains, otherwise use short move to avoid extra work.
3060 movaps encodes one byte shorter. */
3061 (eq_attr "alternative" "6")
3063 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3065 (const_string "V4SF")
3066 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3068 (const_string "V2DF")
3070 (const_string "DF"))
3071 /* For architectures resolving dependencies on register
3072 parts we may avoid extra work to zero out upper part
3074 (eq_attr "alternative" "7")
3076 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3078 (const_string "V1DF")
3079 (const_string "DF"))
3081 (const_string "DF")))])
3083 (define_insn "*movdf_integer_rex64"
3084 [(set (match_operand:DF 0 "nonimmediate_operand"
3085 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3086 (match_operand:DF 1 "general_operand"
3087 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3088 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3089 && (reload_in_progress || reload_completed
3090 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3091 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3092 && optimize_function_for_size_p (cfun)
3093 && standard_80387_constant_p (operands[1]))
3094 || GET_CODE (operands[1]) != CONST_DOUBLE
3095 || memory_operand (operands[0], DFmode))"
3097 switch (which_alternative)
3101 return output_387_reg_move (insn, operands);
3104 return standard_80387_constant_opcode (operands[1]);
3111 switch (get_attr_mode (insn))
3114 return "%vxorps\t%0, %d0";
3116 return "%vxorpd\t%0, %d0";
3118 return "%vpxor\t%0, %d0";
3125 switch (get_attr_mode (insn))
3128 return "%vmovaps\t{%1, %0|%0, %1}";
3130 return "%vmovapd\t{%1, %0|%0, %1}";
3132 return "%vmovdqa\t{%1, %0|%0, %1}";
3134 return "%vmovq\t{%1, %0|%0, %1}";
3138 if (REG_P (operands[0]) && REG_P (operands[1]))
3139 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3141 return "vmovsd\t{%1, %0|%0, %1}";
3144 return "movsd\t{%1, %0|%0, %1}";
3146 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3148 return "%vmovlps\t{%1, %d0|%d0, %1}";
3155 return "%vmovd\t{%1, %0|%0, %1}";
3161 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3162 (set (attr "prefix")
3163 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3164 (const_string "orig")
3165 (const_string "maybe_vex")))
3167 (cond [(eq_attr "alternative" "0,1,2")
3169 (eq_attr "alternative" "3,4,9,10")
3172 /* For SSE1, we have many fewer alternatives. */
3173 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3174 (cond [(eq_attr "alternative" "5,6")
3175 (const_string "V4SF")
3177 (const_string "V2SF"))
3179 /* xorps is one byte shorter. */
3180 (eq_attr "alternative" "5")
3181 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3183 (const_string "V4SF")
3184 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3188 (const_string "V2DF"))
3190 /* For architectures resolving dependencies on
3191 whole SSE registers use APD move to break dependency
3192 chains, otherwise use short move to avoid extra work.
3194 movaps encodes one byte shorter. */
3195 (eq_attr "alternative" "6")
3197 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3199 (const_string "V4SF")
3200 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3202 (const_string "V2DF")
3204 (const_string "DF"))
3205 /* For architectures resolving dependencies on register
3206 parts we may avoid extra work to zero out upper part
3208 (eq_attr "alternative" "7")
3210 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3212 (const_string "V1DF")
3213 (const_string "DF"))
3215 (const_string "DF")))])
3217 (define_insn "*movdf_integer"
3218 [(set (match_operand:DF 0 "nonimmediate_operand"
3219 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3220 (match_operand:DF 1 "general_operand"
3221 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3222 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3223 && optimize_function_for_speed_p (cfun)
3224 && TARGET_INTEGER_DFMODE_MOVES
3225 && (reload_in_progress || reload_completed
3226 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3227 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3228 && optimize_function_for_size_p (cfun)
3229 && standard_80387_constant_p (operands[1]))
3230 || GET_CODE (operands[1]) != CONST_DOUBLE
3231 || memory_operand (operands[0], DFmode))"
3233 switch (which_alternative)
3237 return output_387_reg_move (insn, operands);
3240 return standard_80387_constant_opcode (operands[1]);
3247 switch (get_attr_mode (insn))
3250 return "xorps\t%0, %0";
3252 return "xorpd\t%0, %0";
3254 return "pxor\t%0, %0";
3261 switch (get_attr_mode (insn))
3264 return "movaps\t{%1, %0|%0, %1}";
3266 return "movapd\t{%1, %0|%0, %1}";
3268 return "movdqa\t{%1, %0|%0, %1}";
3270 return "movq\t{%1, %0|%0, %1}";
3272 return "movsd\t{%1, %0|%0, %1}";
3274 return "movlpd\t{%1, %0|%0, %1}";
3276 return "movlps\t{%1, %0|%0, %1}";
3285 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3287 (cond [(eq_attr "alternative" "0,1,2")
3289 (eq_attr "alternative" "3,4")
3292 /* For SSE1, we have many fewer alternatives. */
3293 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3294 (cond [(eq_attr "alternative" "5,6")
3295 (const_string "V4SF")
3297 (const_string "V2SF"))
3299 /* xorps is one byte shorter. */
3300 (eq_attr "alternative" "5")
3301 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3303 (const_string "V4SF")
3304 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3308 (const_string "V2DF"))
3310 /* For architectures resolving dependencies on
3311 whole SSE registers use APD move to break dependency
3312 chains, otherwise use short move to avoid extra work.
3314 movaps encodes one byte shorter. */
3315 (eq_attr "alternative" "6")
3317 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3319 (const_string "V4SF")
3320 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3322 (const_string "V2DF")
3324 (const_string "DF"))
3325 /* For architectures resolving dependencies on register
3326 parts we may avoid extra work to zero out upper part
3328 (eq_attr "alternative" "7")
3330 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3332 (const_string "V1DF")
3333 (const_string "DF"))
3335 (const_string "DF")))])
3338 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3339 (match_operand:DF 1 "general_operand" ""))]
3341 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3342 && ! (ANY_FP_REG_P (operands[0]) ||
3343 (GET_CODE (operands[0]) == SUBREG
3344 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3345 && ! (ANY_FP_REG_P (operands[1]) ||
3346 (GET_CODE (operands[1]) == SUBREG
3347 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3349 "ix86_split_long_move (operands); DONE;")
3351 (define_insn "*swapdf"
3352 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3353 (match_operand:DF 1 "fp_register_operand" "+f"))
3356 "reload_completed || TARGET_80387"
3358 if (STACK_TOP_P (operands[0]))
3363 [(set_attr "type" "fxch")
3364 (set_attr "mode" "DF")])
3366 (define_expand "movxf"
3367 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3368 (match_operand:XF 1 "general_operand" ""))]
3370 "ix86_expand_move (XFmode, operands); DONE;")
3372 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3373 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3374 ;; Pushing using integer instructions is longer except for constants
3375 ;; and direct memory references.
3376 ;; (assuming that any given constant is pushed only once, but this ought to be
3377 ;; handled elsewhere).
3379 (define_insn "*pushxf_nointeger"
3380 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3381 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3382 "optimize_function_for_size_p (cfun)"
3384 /* This insn should be already split before reg-stack. */
3387 [(set_attr "type" "multi")
3388 (set_attr "unit" "i387,*,*")
3389 (set_attr "mode" "XF,SI,SI")])
3391 (define_insn "*pushxf_integer"
3392 [(set (match_operand:XF 0 "push_operand" "=<,<")
3393 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3394 "optimize_function_for_speed_p (cfun)"
3396 /* This insn should be already split before reg-stack. */
3399 [(set_attr "type" "multi")
3400 (set_attr "unit" "i387,*")
3401 (set_attr "mode" "XF,SI")])
3404 [(set (match_operand 0 "push_operand" "")
3405 (match_operand 1 "general_operand" ""))]
3407 && (GET_MODE (operands[0]) == XFmode
3408 || GET_MODE (operands[0]) == DFmode)
3409 && !ANY_FP_REG_P (operands[1])"
3411 "ix86_split_long_move (operands); DONE;")
3414 [(set (match_operand:XF 0 "push_operand" "")
3415 (match_operand:XF 1 "any_fp_register_operand" ""))]
3417 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3418 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3419 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3421 ;; Do not use integer registers when optimizing for size
3422 (define_insn "*movxf_nointeger"
3423 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3424 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3425 "optimize_function_for_size_p (cfun)
3426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3427 && (reload_in_progress || reload_completed
3428 || standard_80387_constant_p (operands[1])
3429 || GET_CODE (operands[1]) != CONST_DOUBLE
3430 || memory_operand (operands[0], XFmode))"
3432 switch (which_alternative)
3436 return output_387_reg_move (insn, operands);
3439 return standard_80387_constant_opcode (operands[1]);
3447 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3448 (set_attr "mode" "XF,XF,XF,SI,SI")])
3450 (define_insn "*movxf_integer"
3451 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3452 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3453 "optimize_function_for_speed_p (cfun)
3454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3455 && (reload_in_progress || reload_completed
3456 || GET_CODE (operands[1]) != CONST_DOUBLE
3457 || memory_operand (operands[0], XFmode))"
3459 switch (which_alternative)
3463 return output_387_reg_move (insn, operands);
3466 return standard_80387_constant_opcode (operands[1]);
3475 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3476 (set_attr "mode" "XF,XF,XF,SI,SI")])
3478 (define_expand "movtf"
3479 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3480 (match_operand:TF 1 "nonimmediate_operand" ""))]
3483 ix86_expand_move (TFmode, operands);
3487 (define_insn "*movtf_internal"
3488 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3489 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3493 switch (which_alternative)
3497 if (get_attr_mode (insn) == MODE_V4SF)
3498 return "%vmovaps\t{%1, %0|%0, %1}";
3500 return "%vmovdqa\t{%1, %0|%0, %1}";
3502 if (get_attr_mode (insn) == MODE_V4SF)
3503 return "%vxorps\t%0, %d0";
3505 return "%vpxor\t%0, %d0";
3513 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3514 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3516 (cond [(eq_attr "alternative" "0,2")
3518 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3520 (const_string "V4SF")
3521 (const_string "TI"))
3522 (eq_attr "alternative" "1")
3524 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3526 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3528 (const_string "V4SF")
3529 (const_string "TI"))]
3530 (const_string "DI")))])
3532 (define_insn "*pushtf_sse"
3533 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3534 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3537 /* This insn should be already split before reg-stack. */
3540 [(set_attr "type" "multi")
3541 (set_attr "unit" "sse,*,*")
3542 (set_attr "mode" "TF,SI,SI")])
3545 [(set (match_operand:TF 0 "push_operand" "")
3546 (match_operand:TF 1 "general_operand" ""))]
3547 "TARGET_SSE2 && reload_completed
3548 && !SSE_REG_P (operands[1])"
3550 "ix86_split_long_move (operands); DONE;")
3553 [(set (match_operand:TF 0 "push_operand" "")
3554 (match_operand:TF 1 "any_fp_register_operand" ""))]
3556 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3557 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3561 [(set (match_operand 0 "nonimmediate_operand" "")
3562 (match_operand 1 "general_operand" ""))]
3564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3565 && GET_MODE (operands[0]) == XFmode
3566 && ! (ANY_FP_REG_P (operands[0]) ||
3567 (GET_CODE (operands[0]) == SUBREG
3568 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3569 && ! (ANY_FP_REG_P (operands[1]) ||
3570 (GET_CODE (operands[1]) == SUBREG
3571 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3573 "ix86_split_long_move (operands); DONE;")
3576 [(set (match_operand 0 "register_operand" "")
3577 (match_operand 1 "memory_operand" ""))]
3579 && MEM_P (operands[1])
3580 && (GET_MODE (operands[0]) == TFmode
3581 || GET_MODE (operands[0]) == XFmode
3582 || GET_MODE (operands[0]) == SFmode
3583 || GET_MODE (operands[0]) == DFmode)
3584 && (operands[2] = find_constant_src (insn))"
3585 [(set (match_dup 0) (match_dup 2))]
3587 rtx c = operands[2];
3588 rtx r = operands[0];
3590 if (GET_CODE (r) == SUBREG)
3595 if (!standard_sse_constant_p (c))
3598 else if (FP_REG_P (r))
3600 if (!standard_80387_constant_p (c))
3603 else if (MMX_REG_P (r))
3608 [(set (match_operand 0 "register_operand" "")
3609 (float_extend (match_operand 1 "memory_operand" "")))]
3611 && MEM_P (operands[1])
3612 && (GET_MODE (operands[0]) == TFmode
3613 || GET_MODE (operands[0]) == XFmode
3614 || GET_MODE (operands[0]) == SFmode
3615 || GET_MODE (operands[0]) == DFmode)
3616 && (operands[2] = find_constant_src (insn))"
3617 [(set (match_dup 0) (match_dup 2))]
3619 rtx c = operands[2];
3620 rtx r = operands[0];
3622 if (GET_CODE (r) == SUBREG)
3627 if (!standard_sse_constant_p (c))
3630 else if (FP_REG_P (r))
3632 if (!standard_80387_constant_p (c))
3635 else if (MMX_REG_P (r))
3639 (define_insn "swapxf"
3640 [(set (match_operand:XF 0 "register_operand" "+f")
3641 (match_operand:XF 1 "register_operand" "+f"))
3646 if (STACK_TOP_P (operands[0]))
3651 [(set_attr "type" "fxch")
3652 (set_attr "mode" "XF")])
3654 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3656 [(set (match_operand:X87MODEF 0 "register_operand" "")
3657 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3658 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3659 && (standard_80387_constant_p (operands[1]) == 8
3660 || standard_80387_constant_p (operands[1]) == 9)"
3661 [(set (match_dup 0)(match_dup 1))
3663 (neg:X87MODEF (match_dup 0)))]
3667 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3668 if (real_isnegzero (&r))
3669 operands[1] = CONST0_RTX (<MODE>mode);
3671 operands[1] = CONST1_RTX (<MODE>mode);
3675 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3676 (match_operand:TF 1 "general_operand" ""))]
3678 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3680 "ix86_split_long_move (operands); DONE;")
3682 ;; Zero extension instructions
3684 (define_expand "zero_extendhisi2"
3685 [(set (match_operand:SI 0 "register_operand" "")
3686 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3689 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3691 operands[1] = force_reg (HImode, operands[1]);
3692 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3697 (define_insn "zero_extendhisi2_and"
3698 [(set (match_operand:SI 0 "register_operand" "=r")
3699 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3700 (clobber (reg:CC FLAGS_REG))]
3701 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3703 [(set_attr "type" "alu1")
3704 (set_attr "mode" "SI")])
3707 [(set (match_operand:SI 0 "register_operand" "")
3708 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3709 (clobber (reg:CC FLAGS_REG))]
3710 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3711 && optimize_function_for_speed_p (cfun)"
3712 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3713 (clobber (reg:CC FLAGS_REG))])]
3716 (define_insn "*zero_extendhisi2_movzwl"
3717 [(set (match_operand:SI 0 "register_operand" "=r")
3718 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3719 "!TARGET_ZERO_EXTEND_WITH_AND
3720 || optimize_function_for_size_p (cfun)"
3721 "movz{wl|x}\t{%1, %0|%0, %1}"
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")])
3725 (define_expand "zero_extendqihi2"
3727 [(set (match_operand:HI 0 "register_operand" "")
3728 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))])]
3733 (define_insn "*zero_extendqihi2_and"
3734 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3735 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3736 (clobber (reg:CC FLAGS_REG))]
3737 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3739 [(set_attr "type" "alu1")
3740 (set_attr "mode" "HI")])
3742 (define_insn "*zero_extendqihi2_movzbw_and"
3743 [(set (match_operand:HI 0 "register_operand" "=r,r")
3744 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3745 (clobber (reg:CC FLAGS_REG))]
3746 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3748 [(set_attr "type" "imovx,alu1")
3749 (set_attr "mode" "HI")])
3751 ; zero extend to SImode here to avoid partial register stalls
3752 (define_insn "*zero_extendqihi2_movzbl"
3753 [(set (match_operand:HI 0 "register_operand" "=r")
3754 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3755 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3756 && reload_completed"
3757 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")])
3761 ;; For the movzbw case strip only the clobber
3763 [(set (match_operand:HI 0 "register_operand" "")
3764 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3765 (clobber (reg:CC FLAGS_REG))]
3767 && (!TARGET_ZERO_EXTEND_WITH_AND
3768 || optimize_function_for_size_p (cfun))
3769 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3770 [(set (match_operand:HI 0 "register_operand" "")
3771 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3773 ;; When source and destination does not overlap, clear destination
3774 ;; first and then do the movb
3776 [(set (match_operand:HI 0 "register_operand" "")
3777 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3778 (clobber (reg:CC FLAGS_REG))]
3780 && ANY_QI_REG_P (operands[0])
3781 && (TARGET_ZERO_EXTEND_WITH_AND
3782 && optimize_function_for_speed_p (cfun))
3783 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3784 [(set (match_dup 0) (const_int 0))
3785 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3786 "operands[2] = gen_lowpart (QImode, operands[0]);")
3788 ;; Rest is handled by single and.
3790 [(set (match_operand:HI 0 "register_operand" "")
3791 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3792 (clobber (reg:CC FLAGS_REG))]
3794 && true_regnum (operands[0]) == true_regnum (operands[1])"
3795 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3796 (clobber (reg:CC FLAGS_REG))])]
3799 (define_expand "zero_extendqisi2"
3801 [(set (match_operand:SI 0 "register_operand" "")
3802 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3803 (clobber (reg:CC FLAGS_REG))])]
3807 (define_insn "*zero_extendqisi2_and"
3808 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3809 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3810 (clobber (reg:CC FLAGS_REG))]
3811 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3813 [(set_attr "type" "alu1")
3814 (set_attr "mode" "SI")])
3816 (define_insn "*zero_extendqisi2_movzbw_and"
3817 [(set (match_operand:SI 0 "register_operand" "=r,r")
3818 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3819 (clobber (reg:CC FLAGS_REG))]
3820 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3822 [(set_attr "type" "imovx,alu1")
3823 (set_attr "mode" "SI")])
3825 (define_insn "*zero_extendqisi2_movzbw"
3826 [(set (match_operand:SI 0 "register_operand" "=r")
3827 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3828 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3829 && reload_completed"
3830 "movz{bl|x}\t{%1, %0|%0, %1}"
3831 [(set_attr "type" "imovx")
3832 (set_attr "mode" "SI")])
3834 ;; For the movzbl case strip only the clobber
3836 [(set (match_operand:SI 0 "register_operand" "")
3837 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3838 (clobber (reg:CC FLAGS_REG))]
3840 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3841 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3843 (zero_extend:SI (match_dup 1)))])
3845 ;; When source and destination does not overlap, clear destination
3846 ;; first and then do the movb
3848 [(set (match_operand:SI 0 "register_operand" "")
3849 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3850 (clobber (reg:CC FLAGS_REG))]
3852 && ANY_QI_REG_P (operands[0])
3853 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3854 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3855 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3856 [(set (match_dup 0) (const_int 0))
3857 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3858 "operands[2] = gen_lowpart (QImode, operands[0]);")
3860 ;; Rest is handled by single and.
3862 [(set (match_operand:SI 0 "register_operand" "")
3863 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3864 (clobber (reg:CC FLAGS_REG))]
3866 && true_regnum (operands[0]) == true_regnum (operands[1])"
3867 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3868 (clobber (reg:CC FLAGS_REG))])]
3871 ;; %%% Kill me once multi-word ops are sane.
3872 (define_expand "zero_extendsidi2"
3873 [(set (match_operand:DI 0 "register_operand" "")
3874 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3879 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3884 (define_insn "zero_extendsidi2_32"
3885 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3887 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3888 (clobber (reg:CC FLAGS_REG))]
3894 movd\t{%1, %0|%0, %1}
3895 movd\t{%1, %0|%0, %1}
3896 %vmovd\t{%1, %0|%0, %1}
3897 %vmovd\t{%1, %0|%0, %1}"
3898 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3899 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3900 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3902 (define_insn "zero_extendsidi2_rex64"
3903 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3905 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3908 mov\t{%k1, %k0|%k0, %k1}
3910 movd\t{%1, %0|%0, %1}
3911 movd\t{%1, %0|%0, %1}
3912 %vmovd\t{%1, %0|%0, %1}
3913 %vmovd\t{%1, %0|%0, %1}"
3914 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3915 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3916 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3919 [(set (match_operand:DI 0 "memory_operand" "")
3920 (zero_extend:DI (match_dup 0)))]
3922 [(set (match_dup 4) (const_int 0))]
3923 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3926 [(set (match_operand:DI 0 "register_operand" "")
3927 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3928 (clobber (reg:CC FLAGS_REG))]
3929 "!TARGET_64BIT && reload_completed
3930 && true_regnum (operands[0]) == true_regnum (operands[1])"
3931 [(set (match_dup 4) (const_int 0))]
3932 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3936 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3937 (clobber (reg:CC FLAGS_REG))]
3938 "!TARGET_64BIT && reload_completed
3939 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3940 [(set (match_dup 3) (match_dup 1))
3941 (set (match_dup 4) (const_int 0))]
3942 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3944 (define_insn "zero_extendhidi2"
3945 [(set (match_operand:DI 0 "register_operand" "=r")
3946 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3948 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "DI")])
3952 (define_insn "zero_extendqidi2"
3953 [(set (match_operand:DI 0 "register_operand" "=r")
3954 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3956 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3957 [(set_attr "type" "imovx")
3958 (set_attr "mode" "DI")])
3960 ;; Sign extension instructions
3962 (define_expand "extendsidi2"
3963 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3964 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3965 (clobber (reg:CC FLAGS_REG))
3966 (clobber (match_scratch:SI 2 ""))])]
3971 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3976 (define_insn "*extendsidi2_1"
3977 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3978 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3979 (clobber (reg:CC FLAGS_REG))
3980 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3984 (define_insn "extendsidi2_rex64"
3985 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3986 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3990 movs{lq|x}\t{%1,%0|%0, %1}"
3991 [(set_attr "type" "imovx")
3992 (set_attr "mode" "DI")
3993 (set_attr "prefix_0f" "0")
3994 (set_attr "modrm" "0,1")])
3996 (define_insn "extendhidi2"
3997 [(set (match_operand:DI 0 "register_operand" "=r")
3998 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4000 "movs{wq|x}\t{%1,%0|%0, %1}"
4001 [(set_attr "type" "imovx")
4002 (set_attr "mode" "DI")])
4004 (define_insn "extendqidi2"
4005 [(set (match_operand:DI 0 "register_operand" "=r")
4006 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4008 "movs{bq|x}\t{%1,%0|%0, %1}"
4009 [(set_attr "type" "imovx")
4010 (set_attr "mode" "DI")])
4012 ;; Extend to memory case when source register does die.
4014 [(set (match_operand:DI 0 "memory_operand" "")
4015 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4016 (clobber (reg:CC FLAGS_REG))
4017 (clobber (match_operand:SI 2 "register_operand" ""))]
4019 && dead_or_set_p (insn, operands[1])
4020 && !reg_mentioned_p (operands[1], operands[0]))"
4021 [(set (match_dup 3) (match_dup 1))
4022 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4023 (clobber (reg:CC FLAGS_REG))])
4024 (set (match_dup 4) (match_dup 1))]
4025 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4027 ;; Extend to memory case when source register does not die.
4029 [(set (match_operand:DI 0 "memory_operand" "")
4030 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4031 (clobber (reg:CC FLAGS_REG))
4032 (clobber (match_operand:SI 2 "register_operand" ""))]
4036 split_di (&operands[0], 1, &operands[3], &operands[4]);
4038 emit_move_insn (operands[3], operands[1]);
4040 /* Generate a cltd if possible and doing so it profitable. */
4041 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4042 && true_regnum (operands[1]) == AX_REG
4043 && true_regnum (operands[2]) == DX_REG)
4045 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4049 emit_move_insn (operands[2], operands[1]);
4050 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4052 emit_move_insn (operands[4], operands[2]);
4056 ;; Extend to register case. Optimize case where source and destination
4057 ;; registers match and cases where we can use cltd.
4059 [(set (match_operand:DI 0 "register_operand" "")
4060 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4061 (clobber (reg:CC FLAGS_REG))
4062 (clobber (match_scratch:SI 2 ""))]
4066 split_di (&operands[0], 1, &operands[3], &operands[4]);
4068 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4069 emit_move_insn (operands[3], operands[1]);
4071 /* Generate a cltd if possible and doing so it profitable. */
4072 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4073 && true_regnum (operands[3]) == AX_REG)
4075 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4079 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4080 emit_move_insn (operands[4], operands[1]);
4082 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4086 (define_insn "extendhisi2"
4087 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4088 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4091 switch (get_attr_prefix_0f (insn))
4094 return "{cwtl|cwde}";
4096 return "movs{wl|x}\t{%1,%0|%0, %1}";
4099 [(set_attr "type" "imovx")
4100 (set_attr "mode" "SI")
4101 (set (attr "prefix_0f")
4102 ;; movsx is short decodable while cwtl is vector decoded.
4103 (if_then_else (and (eq_attr "cpu" "!k6")
4104 (eq_attr "alternative" "0"))
4106 (const_string "1")))
4108 (if_then_else (eq_attr "prefix_0f" "0")
4110 (const_string "1")))])
4112 (define_insn "*extendhisi2_zext"
4113 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4115 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4118 switch (get_attr_prefix_0f (insn))
4121 return "{cwtl|cwde}";
4123 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4126 [(set_attr "type" "imovx")
4127 (set_attr "mode" "SI")
4128 (set (attr "prefix_0f")
4129 ;; movsx is short decodable while cwtl is vector decoded.
4130 (if_then_else (and (eq_attr "cpu" "!k6")
4131 (eq_attr "alternative" "0"))
4133 (const_string "1")))
4135 (if_then_else (eq_attr "prefix_0f" "0")
4137 (const_string "1")))])
4139 (define_insn "extendqihi2"
4140 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4141 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4144 switch (get_attr_prefix_0f (insn))
4147 return "{cbtw|cbw}";
4149 return "movs{bw|x}\t{%1,%0|%0, %1}";
4152 [(set_attr "type" "imovx")
4153 (set_attr "mode" "HI")
4154 (set (attr "prefix_0f")
4155 ;; movsx is short decodable while cwtl is vector decoded.
4156 (if_then_else (and (eq_attr "cpu" "!k6")
4157 (eq_attr "alternative" "0"))
4159 (const_string "1")))
4161 (if_then_else (eq_attr "prefix_0f" "0")
4163 (const_string "1")))])
4165 (define_insn "extendqisi2"
4166 [(set (match_operand:SI 0 "register_operand" "=r")
4167 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4169 "movs{bl|x}\t{%1,%0|%0, %1}"
4170 [(set_attr "type" "imovx")
4171 (set_attr "mode" "SI")])
4173 (define_insn "*extendqisi2_zext"
4174 [(set (match_operand:DI 0 "register_operand" "=r")
4176 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4178 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4179 [(set_attr "type" "imovx")
4180 (set_attr "mode" "SI")])
4182 ;; Conversions between float and double.
4184 ;; These are all no-ops in the model used for the 80387. So just
4187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4188 (define_insn "*dummy_extendsfdf2"
4189 [(set (match_operand:DF 0 "push_operand" "=<")
4190 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4195 [(set (match_operand:DF 0 "push_operand" "")
4196 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4198 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4199 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4201 (define_insn "*dummy_extendsfxf2"
4202 [(set (match_operand:XF 0 "push_operand" "=<")
4203 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4208 [(set (match_operand:XF 0 "push_operand" "")
4209 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4211 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4212 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4213 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4216 [(set (match_operand:XF 0 "push_operand" "")
4217 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4219 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4220 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4221 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4223 (define_expand "extendsfdf2"
4224 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4225 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4226 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4228 /* ??? Needed for compress_float_constant since all fp constants
4229 are LEGITIMATE_CONSTANT_P. */
4230 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4232 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4233 && standard_80387_constant_p (operands[1]) > 0)
4235 operands[1] = simplify_const_unary_operation
4236 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4237 emit_move_insn_1 (operands[0], operands[1]);
4240 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4244 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4246 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4248 We do the conversion post reload to avoid producing of 128bit spills
4249 that might lead to ICE on 32bit target. The sequence unlikely combine
4252 [(set (match_operand:DF 0 "register_operand" "")
4254 (match_operand:SF 1 "nonimmediate_operand" "")))]
4255 "TARGET_USE_VECTOR_FP_CONVERTS
4256 && optimize_insn_for_speed_p ()
4257 && reload_completed && SSE_REG_P (operands[0])"
4262 (parallel [(const_int 0) (const_int 1)]))))]
4264 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4265 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4266 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4267 Try to avoid move when unpacking can be done in source. */
4268 if (REG_P (operands[1]))
4270 /* If it is unsafe to overwrite upper half of source, we need
4271 to move to destination and unpack there. */
4272 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4273 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4274 && true_regnum (operands[0]) != true_regnum (operands[1]))
4276 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4277 emit_move_insn (tmp, operands[1]);
4280 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4281 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4284 emit_insn (gen_vec_setv4sf_0 (operands[3],
4285 CONST0_RTX (V4SFmode), operands[1]));
4288 (define_insn "*extendsfdf2_mixed"
4289 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4291 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4292 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4294 switch (which_alternative)
4298 return output_387_reg_move (insn, operands);
4301 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4307 [(set_attr "type" "fmov,fmov,ssecvt")
4308 (set_attr "prefix" "orig,orig,maybe_vex")
4309 (set_attr "mode" "SF,XF,DF")])
4311 (define_insn "*extendsfdf2_sse"
4312 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4313 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4314 "TARGET_SSE2 && TARGET_SSE_MATH"
4315 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4316 [(set_attr "type" "ssecvt")
4317 (set_attr "prefix" "maybe_vex")
4318 (set_attr "mode" "DF")])
4320 (define_insn "*extendsfdf2_i387"
4321 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4322 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4324 "* return output_387_reg_move (insn, operands);"
4325 [(set_attr "type" "fmov")
4326 (set_attr "mode" "SF,XF")])
4328 (define_expand "extend<mode>xf2"
4329 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4330 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4333 /* ??? Needed for compress_float_constant since all fp constants
4334 are LEGITIMATE_CONSTANT_P. */
4335 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4337 if (standard_80387_constant_p (operands[1]) > 0)
4339 operands[1] = simplify_const_unary_operation
4340 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4341 emit_move_insn_1 (operands[0], operands[1]);
4344 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4348 (define_insn "*extend<mode>xf2_i387"
4349 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4351 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4353 "* return output_387_reg_move (insn, operands);"
4354 [(set_attr "type" "fmov")
4355 (set_attr "mode" "<MODE>,XF")])
4357 ;; %%% This seems bad bad news.
4358 ;; This cannot output into an f-reg because there is no way to be sure
4359 ;; of truncating in that case. Otherwise this is just like a simple move
4360 ;; insn. So we pretend we can output to a reg in order to get better
4361 ;; register preferencing, but we really use a stack slot.
4363 ;; Conversion from DFmode to SFmode.
4365 (define_expand "truncdfsf2"
4366 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4368 (match_operand:DF 1 "nonimmediate_operand" "")))]
4369 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4371 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4373 else if (flag_unsafe_math_optimizations)
4377 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4378 rtx temp = assign_386_stack_local (SFmode, slot);
4379 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4384 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4386 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4388 We do the conversion post reload to avoid producing of 128bit spills
4389 that might lead to ICE on 32bit target. The sequence unlikely combine
4392 [(set (match_operand:SF 0 "register_operand" "")
4394 (match_operand:DF 1 "nonimmediate_operand" "")))]
4395 "TARGET_USE_VECTOR_FP_CONVERTS
4396 && optimize_insn_for_speed_p ()
4397 && reload_completed && SSE_REG_P (operands[0])"
4400 (float_truncate:V2SF
4404 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4405 operands[3] = CONST0_RTX (V2SFmode);
4406 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4407 /* Use movsd for loading from memory, unpcklpd for registers.
4408 Try to avoid move when unpacking can be done in source, or SSE3
4409 movddup is available. */
4410 if (REG_P (operands[1]))
4413 && true_regnum (operands[0]) != true_regnum (operands[1])
4414 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4415 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4417 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4418 emit_move_insn (tmp, operands[1]);
4421 else if (!TARGET_SSE3)
4422 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4423 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4426 emit_insn (gen_sse2_loadlpd (operands[4],
4427 CONST0_RTX (V2DFmode), operands[1]));
4430 (define_expand "truncdfsf2_with_temp"
4431 [(parallel [(set (match_operand:SF 0 "" "")
4432 (float_truncate:SF (match_operand:DF 1 "" "")))
4433 (clobber (match_operand:SF 2 "" ""))])]
4436 (define_insn "*truncdfsf_fast_mixed"
4437 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4439 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4440 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4442 switch (which_alternative)
4445 return output_387_reg_move (insn, operands);
4447 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4452 [(set_attr "type" "fmov,ssecvt")
4453 (set_attr "prefix" "orig,maybe_vex")
4454 (set_attr "mode" "SF")])
4456 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4457 ;; because nothing we do here is unsafe.
4458 (define_insn "*truncdfsf_fast_sse"
4459 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4461 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4462 "TARGET_SSE2 && TARGET_SSE_MATH"
4463 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4464 [(set_attr "type" "ssecvt")
4465 (set_attr "prefix" "maybe_vex")
4466 (set_attr "mode" "SF")])
4468 (define_insn "*truncdfsf_fast_i387"
4469 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4471 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4472 "TARGET_80387 && flag_unsafe_math_optimizations"
4473 "* return output_387_reg_move (insn, operands);"
4474 [(set_attr "type" "fmov")
4475 (set_attr "mode" "SF")])
4477 (define_insn "*truncdfsf_mixed"
4478 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4480 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4481 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4482 "TARGET_MIX_SSE_I387"
4484 switch (which_alternative)
4487 return output_387_reg_move (insn, operands);
4489 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4495 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4496 (set_attr "unit" "*,*,i387,i387,i387")
4497 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4498 (set_attr "mode" "SF")])
4500 (define_insn "*truncdfsf_i387"
4501 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4503 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4504 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4507 switch (which_alternative)
4510 return output_387_reg_move (insn, operands);
4516 [(set_attr "type" "fmov,multi,multi,multi")
4517 (set_attr "unit" "*,i387,i387,i387")
4518 (set_attr "mode" "SF")])
4520 (define_insn "*truncdfsf2_i387_1"
4521 [(set (match_operand:SF 0 "memory_operand" "=m")
4523 (match_operand:DF 1 "register_operand" "f")))]
4525 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4526 && !TARGET_MIX_SSE_I387"
4527 "* return output_387_reg_move (insn, operands);"
4528 [(set_attr "type" "fmov")
4529 (set_attr "mode" "SF")])
4532 [(set (match_operand:SF 0 "register_operand" "")
4534 (match_operand:DF 1 "fp_register_operand" "")))
4535 (clobber (match_operand 2 "" ""))]
4537 [(set (match_dup 2) (match_dup 1))
4538 (set (match_dup 0) (match_dup 2))]
4540 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4543 ;; Conversion from XFmode to {SF,DF}mode
4545 (define_expand "truncxf<mode>2"
4546 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4547 (float_truncate:MODEF
4548 (match_operand:XF 1 "register_operand" "")))
4549 (clobber (match_dup 2))])]
4552 if (flag_unsafe_math_optimizations)
4554 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4555 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4556 if (reg != operands[0])
4557 emit_move_insn (operands[0], reg);
4562 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4563 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4567 (define_insn "*truncxfsf2_mixed"
4568 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4570 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4571 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4574 gcc_assert (!which_alternative);
4575 return output_387_reg_move (insn, operands);
4577 [(set_attr "type" "fmov,multi,multi,multi")
4578 (set_attr "unit" "*,i387,i387,i387")
4579 (set_attr "mode" "SF")])
4581 (define_insn "*truncxfdf2_mixed"
4582 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4584 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4585 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4588 gcc_assert (!which_alternative);
4589 return output_387_reg_move (insn, operands);
4591 [(set_attr "type" "fmov,multi,multi,multi")
4592 (set_attr "unit" "*,i387,i387,i387")
4593 (set_attr "mode" "DF")])
4595 (define_insn "truncxf<mode>2_i387_noop"
4596 [(set (match_operand:MODEF 0 "register_operand" "=f")
4597 (float_truncate:MODEF
4598 (match_operand:XF 1 "register_operand" "f")))]
4599 "TARGET_80387 && flag_unsafe_math_optimizations"
4600 "* return output_387_reg_move (insn, operands);"
4601 [(set_attr "type" "fmov")
4602 (set_attr "mode" "<MODE>")])
4604 (define_insn "*truncxf<mode>2_i387"
4605 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4606 (float_truncate:MODEF
4607 (match_operand:XF 1 "register_operand" "f")))]
4609 "* return output_387_reg_move (insn, operands);"
4610 [(set_attr "type" "fmov")
4611 (set_attr "mode" "<MODE>")])
4614 [(set (match_operand:MODEF 0 "register_operand" "")
4615 (float_truncate:MODEF
4616 (match_operand:XF 1 "register_operand" "")))
4617 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4618 "TARGET_80387 && reload_completed"
4619 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4620 (set (match_dup 0) (match_dup 2))]
4624 [(set (match_operand:MODEF 0 "memory_operand" "")
4625 (float_truncate:MODEF
4626 (match_operand:XF 1 "register_operand" "")))
4627 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4629 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4632 ;; Signed conversion to DImode.
4634 (define_expand "fix_truncxfdi2"
4635 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4636 (fix:DI (match_operand:XF 1 "register_operand" "")))
4637 (clobber (reg:CC FLAGS_REG))])]
4642 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4647 (define_expand "fix_trunc<mode>di2"
4648 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4649 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4650 (clobber (reg:CC FLAGS_REG))])]
4651 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4654 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4656 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4659 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4661 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4662 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4663 if (out != operands[0])
4664 emit_move_insn (operands[0], out);
4669 ;; Signed conversion to SImode.
4671 (define_expand "fix_truncxfsi2"
4672 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4673 (fix:SI (match_operand:XF 1 "register_operand" "")))
4674 (clobber (reg:CC FLAGS_REG))])]
4679 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4684 (define_expand "fix_trunc<mode>si2"
4685 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4686 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4687 (clobber (reg:CC FLAGS_REG))])]
4688 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4691 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4693 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4696 if (SSE_FLOAT_MODE_P (<MODE>mode))
4698 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4699 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4700 if (out != operands[0])
4701 emit_move_insn (operands[0], out);
4706 ;; Signed conversion to HImode.
4708 (define_expand "fix_trunc<mode>hi2"
4709 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4710 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4711 (clobber (reg:CC FLAGS_REG))])]
4713 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4717 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4722 ;; Unsigned conversion to SImode.
4724 (define_expand "fixuns_trunc<mode>si2"
4726 [(set (match_operand:SI 0 "register_operand" "")
4728 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4730 (clobber (match_scratch:<ssevecmode> 3 ""))
4731 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4732 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4734 enum machine_mode mode = <MODE>mode;
4735 enum machine_mode vecmode = <ssevecmode>mode;
4736 REAL_VALUE_TYPE TWO31r;
4739 if (optimize_insn_for_size_p ())
4742 real_ldexp (&TWO31r, &dconst1, 31);
4743 two31 = const_double_from_real_value (TWO31r, mode);
4744 two31 = ix86_build_const_vector (mode, true, two31);
4745 operands[2] = force_reg (vecmode, two31);
4748 (define_insn_and_split "*fixuns_trunc<mode>_1"
4749 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4751 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4752 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4753 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4754 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4755 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4756 && optimize_function_for_speed_p (cfun)"
4758 "&& reload_completed"
4761 ix86_split_convert_uns_si_sse (operands);
4765 ;; Unsigned conversion to HImode.
4766 ;; Without these patterns, we'll try the unsigned SI conversion which
4767 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4769 (define_expand "fixuns_trunc<mode>hi2"
4771 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4772 (set (match_operand:HI 0 "nonimmediate_operand" "")
4773 (subreg:HI (match_dup 2) 0))]
4774 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4775 "operands[2] = gen_reg_rtx (SImode);")
4777 ;; When SSE is available, it is always faster to use it!
4778 (define_insn "fix_trunc<mode>di_sse"
4779 [(set (match_operand:DI 0 "register_operand" "=r,r")
4780 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4781 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4782 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4783 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4784 [(set_attr "type" "sseicvt")
4785 (set_attr "prefix" "maybe_vex")
4786 (set_attr "mode" "<MODE>")
4787 (set_attr "athlon_decode" "double,vector")
4788 (set_attr "amdfam10_decode" "double,double")])
4790 (define_insn "fix_trunc<mode>si_sse"
4791 [(set (match_operand:SI 0 "register_operand" "=r,r")
4792 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4793 "SSE_FLOAT_MODE_P (<MODE>mode)
4794 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4795 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4796 [(set_attr "type" "sseicvt")
4797 (set_attr "prefix" "maybe_vex")
4798 (set_attr "mode" "<MODE>")
4799 (set_attr "athlon_decode" "double,vector")
4800 (set_attr "amdfam10_decode" "double,double")])
4802 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4804 [(set (match_operand:MODEF 0 "register_operand" "")
4805 (match_operand:MODEF 1 "memory_operand" ""))
4806 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4807 (fix:SSEMODEI24 (match_dup 0)))]
4808 "TARGET_SHORTEN_X87_SSE
4809 && peep2_reg_dead_p (2, operands[0])"
4810 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4813 ;; Avoid vector decoded forms of the instruction.
4815 [(match_scratch:DF 2 "Y2")
4816 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4817 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4818 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4819 [(set (match_dup 2) (match_dup 1))
4820 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4824 [(match_scratch:SF 2 "x")
4825 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4826 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4827 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4828 [(set (match_dup 2) (match_dup 1))
4829 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4832 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4833 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4834 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && (TARGET_64BIT || <MODE>mode != DImode))
4840 && !(reload_completed || reload_in_progress)"
4845 if (memory_operand (operands[0], VOIDmode))
4846 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4849 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4850 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4856 [(set_attr "type" "fisttp")
4857 (set_attr "mode" "<MODE>")])
4859 (define_insn "fix_trunc<mode>_i387_fisttp"
4860 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4861 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4862 (clobber (match_scratch:XF 2 "=&1f"))]
4863 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4865 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4866 && (TARGET_64BIT || <MODE>mode != DImode))
4867 && TARGET_SSE_MATH)"
4868 "* return output_fix_trunc (insn, operands, 1);"
4869 [(set_attr "type" "fisttp")
4870 (set_attr "mode" "<MODE>")])
4872 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4873 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4874 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4875 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4876 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4877 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4879 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4880 && (TARGET_64BIT || <MODE>mode != DImode))
4881 && TARGET_SSE_MATH)"
4883 [(set_attr "type" "fisttp")
4884 (set_attr "mode" "<MODE>")])
4887 [(set (match_operand:X87MODEI 0 "register_operand" "")
4888 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4889 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4890 (clobber (match_scratch 3 ""))]
4892 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4893 (clobber (match_dup 3))])
4894 (set (match_dup 0) (match_dup 2))]
4898 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4899 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4900 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4901 (clobber (match_scratch 3 ""))]
4903 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4904 (clobber (match_dup 3))])]
4907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4911 ;; function in i386.c.
4912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4913 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4914 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4915 (clobber (reg:CC FLAGS_REG))]
4916 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4918 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4919 && (TARGET_64BIT || <MODE>mode != DImode))
4920 && !(reload_completed || reload_in_progress)"
4925 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4927 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4928 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4929 if (memory_operand (operands[0], VOIDmode))
4930 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4931 operands[2], operands[3]));
4934 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4935 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4936 operands[2], operands[3],
4941 [(set_attr "type" "fistp")
4942 (set_attr "i387_cw" "trunc")
4943 (set_attr "mode" "<MODE>")])
4945 (define_insn "fix_truncdi_i387"
4946 [(set (match_operand:DI 0 "memory_operand" "=m")
4947 (fix:DI (match_operand 1 "register_operand" "f")))
4948 (use (match_operand:HI 2 "memory_operand" "m"))
4949 (use (match_operand:HI 3 "memory_operand" "m"))
4950 (clobber (match_scratch:XF 4 "=&1f"))]
4951 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4953 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4954 "* return output_fix_trunc (insn, operands, 0);"
4955 [(set_attr "type" "fistp")
4956 (set_attr "i387_cw" "trunc")
4957 (set_attr "mode" "DI")])
4959 (define_insn "fix_truncdi_i387_with_temp"
4960 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4961 (fix:DI (match_operand 1 "register_operand" "f,f")))
4962 (use (match_operand:HI 2 "memory_operand" "m,m"))
4963 (use (match_operand:HI 3 "memory_operand" "m,m"))
4964 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4965 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4966 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4968 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4970 [(set_attr "type" "fistp")
4971 (set_attr "i387_cw" "trunc")
4972 (set_attr "mode" "DI")])
4975 [(set (match_operand:DI 0 "register_operand" "")
4976 (fix:DI (match_operand 1 "register_operand" "")))
4977 (use (match_operand:HI 2 "memory_operand" ""))
4978 (use (match_operand:HI 3 "memory_operand" ""))
4979 (clobber (match_operand:DI 4 "memory_operand" ""))
4980 (clobber (match_scratch 5 ""))]
4982 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4985 (clobber (match_dup 5))])
4986 (set (match_dup 0) (match_dup 4))]
4990 [(set (match_operand:DI 0 "memory_operand" "")
4991 (fix:DI (match_operand 1 "register_operand" "")))
4992 (use (match_operand:HI 2 "memory_operand" ""))
4993 (use (match_operand:HI 3 "memory_operand" ""))
4994 (clobber (match_operand:DI 4 "memory_operand" ""))
4995 (clobber (match_scratch 5 ""))]
4997 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5000 (clobber (match_dup 5))])]
5003 (define_insn "fix_trunc<mode>_i387"
5004 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5005 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5006 (use (match_operand:HI 2 "memory_operand" "m"))
5007 (use (match_operand:HI 3 "memory_operand" "m"))]
5008 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5010 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5011 "* return output_fix_trunc (insn, operands, 0);"
5012 [(set_attr "type" "fistp")
5013 (set_attr "i387_cw" "trunc")
5014 (set_attr "mode" "<MODE>")])
5016 (define_insn "fix_trunc<mode>_i387_with_temp"
5017 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5018 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5019 (use (match_operand:HI 2 "memory_operand" "m,m"))
5020 (use (match_operand:HI 3 "memory_operand" "m,m"))
5021 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5022 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5024 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5026 [(set_attr "type" "fistp")
5027 (set_attr "i387_cw" "trunc")
5028 (set_attr "mode" "<MODE>")])
5031 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5032 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5033 (use (match_operand:HI 2 "memory_operand" ""))
5034 (use (match_operand:HI 3 "memory_operand" ""))
5035 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5037 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5039 (use (match_dup 3))])
5040 (set (match_dup 0) (match_dup 4))]
5044 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5045 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5046 (use (match_operand:HI 2 "memory_operand" ""))
5047 (use (match_operand:HI 3 "memory_operand" ""))
5048 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5050 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5052 (use (match_dup 3))])]
5055 (define_insn "x86_fnstcw_1"
5056 [(set (match_operand:HI 0 "memory_operand" "=m")
5057 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5060 [(set_attr "length" "2")
5061 (set_attr "mode" "HI")
5062 (set_attr "unit" "i387")])
5064 (define_insn "x86_fldcw_1"
5065 [(set (reg:HI FPCR_REG)
5066 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5069 [(set_attr "length" "2")
5070 (set_attr "mode" "HI")
5071 (set_attr "unit" "i387")
5072 (set_attr "athlon_decode" "vector")
5073 (set_attr "amdfam10_decode" "vector")])
5075 ;; Conversion between fixed point and floating point.
5077 ;; Even though we only accept memory inputs, the backend _really_
5078 ;; wants to be able to do this between registers.
5080 (define_expand "floathi<mode>2"
5081 [(set (match_operand:X87MODEF 0 "register_operand" "")
5082 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5085 || TARGET_MIX_SSE_I387)"
5088 ;; Pre-reload splitter to add memory clobber to the pattern.
5089 (define_insn_and_split "*floathi<mode>2_1"
5090 [(set (match_operand:X87MODEF 0 "register_operand" "")
5091 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5093 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5094 || TARGET_MIX_SSE_I387)
5095 && !(reload_completed || reload_in_progress)"
5098 [(parallel [(set (match_dup 0)
5099 (float:X87MODEF (match_dup 1)))
5100 (clobber (match_dup 2))])]
5101 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5103 (define_insn "*floathi<mode>2_i387_with_temp"
5104 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5105 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5106 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5109 || TARGET_MIX_SSE_I387)"
5111 [(set_attr "type" "fmov,multi")
5112 (set_attr "mode" "<MODE>")
5113 (set_attr "unit" "*,i387")
5114 (set_attr "fp_int_src" "true")])
5116 (define_insn "*floathi<mode>2_i387"
5117 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5118 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5121 || TARGET_MIX_SSE_I387)"
5123 [(set_attr "type" "fmov")
5124 (set_attr "mode" "<MODE>")
5125 (set_attr "fp_int_src" "true")])
5128 [(set (match_operand:X87MODEF 0 "register_operand" "")
5129 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5130 (clobber (match_operand:HI 2 "memory_operand" ""))]
5132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5133 || TARGET_MIX_SSE_I387)
5134 && reload_completed"
5135 [(set (match_dup 2) (match_dup 1))
5136 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5140 [(set (match_operand:X87MODEF 0 "register_operand" "")
5141 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5142 (clobber (match_operand:HI 2 "memory_operand" ""))]
5144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5145 || TARGET_MIX_SSE_I387)
5146 && reload_completed"
5147 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5150 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5151 [(set (match_operand:X87MODEF 0 "register_operand" "")
5153 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5155 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5156 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5159 ;; Pre-reload splitter to add memory clobber to the pattern.
5160 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5161 [(set (match_operand:X87MODEF 0 "register_operand" "")
5162 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5164 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5165 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5166 || TARGET_MIX_SSE_I387))
5167 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5168 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5169 && ((<SSEMODEI24:MODE>mode == SImode
5170 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5171 && optimize_function_for_speed_p (cfun)
5172 && flag_trapping_math)
5173 || !(TARGET_INTER_UNIT_CONVERSIONS
5174 || optimize_function_for_size_p (cfun)))))
5175 && !(reload_completed || reload_in_progress)"
5178 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5179 (clobber (match_dup 2))])]
5181 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5183 /* Avoid store forwarding (partial memory) stall penalty
5184 by passing DImode value through XMM registers. */
5185 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5186 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5187 && optimize_function_for_speed_p (cfun))
5189 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5196 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5197 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5199 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5200 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5201 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5202 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5204 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5205 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5206 (set_attr "unit" "*,i387,*,*,*")
5207 (set_attr "athlon_decode" "*,*,double,direct,double")
5208 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5209 (set_attr "fp_int_src" "true")])
5211 (define_insn "*floatsi<mode>2_vector_mixed"
5212 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5213 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5214 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5215 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5219 [(set_attr "type" "fmov,sseicvt")
5220 (set_attr "mode" "<MODE>,<ssevecmode>")
5221 (set_attr "unit" "i387,*")
5222 (set_attr "athlon_decode" "*,direct")
5223 (set_attr "amdfam10_decode" "*,double")
5224 (set_attr "fp_int_src" "true")])
5226 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5227 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5229 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5230 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5231 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5234 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5235 (set_attr "mode" "<MODEF:MODE>")
5236 (set_attr "unit" "*,i387,*,*")
5237 (set_attr "athlon_decode" "*,*,double,direct")
5238 (set_attr "amdfam10_decode" "*,*,vector,double")
5239 (set_attr "fp_int_src" "true")])
5242 [(set (match_operand:MODEF 0 "register_operand" "")
5243 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5244 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5247 && TARGET_INTER_UNIT_CONVERSIONS
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (operands[0])))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5256 [(set (match_operand:MODEF 0 "register_operand" "")
5257 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5258 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5259 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5261 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5263 && (SSE_REG_P (operands[0])
5264 || (GET_CODE (operands[0]) == SUBREG
5265 && SSE_REG_P (operands[0])))"
5266 [(set (match_dup 2) (match_dup 1))
5267 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5270 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5271 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5273 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5274 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5275 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5276 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5279 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5280 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5281 [(set_attr "type" "fmov,sseicvt,sseicvt")
5282 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5283 (set_attr "mode" "<MODEF:MODE>")
5284 (set_attr "unit" "i387,*,*")
5285 (set_attr "athlon_decode" "*,double,direct")
5286 (set_attr "amdfam10_decode" "*,vector,double")
5287 (set_attr "fp_int_src" "true")])
5289 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5290 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5292 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5293 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5295 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5298 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5299 [(set_attr "type" "fmov,sseicvt")
5300 (set_attr "prefix" "orig,maybe_vex")
5301 (set_attr "mode" "<MODEF:MODE>")
5302 (set_attr "athlon_decode" "*,direct")
5303 (set_attr "amdfam10_decode" "*,double")
5304 (set_attr "fp_int_src" "true")])
5306 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5307 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5309 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5310 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5311 "TARGET_SSE2 && TARGET_SSE_MATH
5312 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5314 [(set_attr "type" "sseicvt")
5315 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5316 (set_attr "athlon_decode" "double,direct,double")
5317 (set_attr "amdfam10_decode" "vector,double,double")
5318 (set_attr "fp_int_src" "true")])
5320 (define_insn "*floatsi<mode>2_vector_sse"
5321 [(set (match_operand:MODEF 0 "register_operand" "=x")
5322 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5323 "TARGET_SSE2 && TARGET_SSE_MATH
5324 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5326 [(set_attr "type" "sseicvt")
5327 (set_attr "mode" "<MODE>")
5328 (set_attr "athlon_decode" "direct")
5329 (set_attr "amdfam10_decode" "double")
5330 (set_attr "fp_int_src" "true")])
5333 [(set (match_operand:MODEF 0 "register_operand" "")
5334 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5335 (clobber (match_operand:SI 2 "memory_operand" ""))]
5336 "TARGET_SSE2 && TARGET_SSE_MATH
5337 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5339 && (SSE_REG_P (operands[0])
5340 || (GET_CODE (operands[0]) == SUBREG
5341 && SSE_REG_P (operands[0])))"
5344 rtx op1 = operands[1];
5346 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5348 if (GET_CODE (op1) == SUBREG)
5349 op1 = SUBREG_REG (op1);
5351 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5353 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5354 emit_insn (gen_sse2_loadld (operands[4],
5355 CONST0_RTX (V4SImode), operands[1]));
5357 /* We can ignore possible trapping value in the
5358 high part of SSE register for non-trapping math. */
5359 else if (SSE_REG_P (op1) && !flag_trapping_math)
5360 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5363 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5364 emit_move_insn (operands[2], operands[1]);
5365 emit_insn (gen_sse2_loadld (operands[4],
5366 CONST0_RTX (V4SImode), operands[2]));
5369 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5374 [(set (match_operand:MODEF 0 "register_operand" "")
5375 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5376 (clobber (match_operand:SI 2 "memory_operand" ""))]
5377 "TARGET_SSE2 && TARGET_SSE_MATH
5378 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5380 && (SSE_REG_P (operands[0])
5381 || (GET_CODE (operands[0]) == SUBREG
5382 && SSE_REG_P (operands[0])))"
5385 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5387 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5389 emit_insn (gen_sse2_loadld (operands[4],
5390 CONST0_RTX (V4SImode), operands[1]));
5392 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5397 [(set (match_operand:MODEF 0 "register_operand" "")
5398 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5399 "TARGET_SSE2 && TARGET_SSE_MATH
5400 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5402 && (SSE_REG_P (operands[0])
5403 || (GET_CODE (operands[0]) == SUBREG
5404 && SSE_REG_P (operands[0])))"
5407 rtx op1 = operands[1];
5409 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411 if (GET_CODE (op1) == SUBREG)
5412 op1 = SUBREG_REG (op1);
5414 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5416 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5417 emit_insn (gen_sse2_loadld (operands[4],
5418 CONST0_RTX (V4SImode), operands[1]));
5420 /* We can ignore possible trapping value in the
5421 high part of SSE register for non-trapping math. */
5422 else if (SSE_REG_P (op1) && !flag_trapping_math)
5423 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5427 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5432 [(set (match_operand:MODEF 0 "register_operand" "")
5433 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5434 "TARGET_SSE2 && TARGET_SSE_MATH
5435 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5437 && (SSE_REG_P (operands[0])
5438 || (GET_CODE (operands[0]) == SUBREG
5439 && SSE_REG_P (operands[0])))"
5442 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5444 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5446 emit_insn (gen_sse2_loadld (operands[4],
5447 CONST0_RTX (V4SImode), operands[1]));
5449 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5453 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5454 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5456 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5457 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5458 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5461 [(set_attr "type" "sseicvt")
5462 (set_attr "mode" "<MODEF:MODE>")
5463 (set_attr "athlon_decode" "double,direct")
5464 (set_attr "amdfam10_decode" "vector,double")
5465 (set_attr "fp_int_src" "true")])
5467 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5468 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5470 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5471 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5472 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5473 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5474 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5475 [(set_attr "type" "sseicvt")
5476 (set_attr "prefix" "maybe_vex")
5477 (set_attr "mode" "<MODEF:MODE>")
5478 (set_attr "athlon_decode" "double,direct")
5479 (set_attr "amdfam10_decode" "vector,double")
5480 (set_attr "fp_int_src" "true")])
5483 [(set (match_operand:MODEF 0 "register_operand" "")
5484 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5485 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5486 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5487 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5488 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5490 && (SSE_REG_P (operands[0])
5491 || (GET_CODE (operands[0]) == SUBREG
5492 && SSE_REG_P (operands[0])))"
5493 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5496 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5497 [(set (match_operand:MODEF 0 "register_operand" "=x")
5499 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5500 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5501 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5502 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5503 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5504 [(set_attr "type" "sseicvt")
5505 (set_attr "prefix" "maybe_vex")
5506 (set_attr "mode" "<MODEF:MODE>")
5507 (set_attr "athlon_decode" "direct")
5508 (set_attr "amdfam10_decode" "double")
5509 (set_attr "fp_int_src" "true")])
5512 [(set (match_operand:MODEF 0 "register_operand" "")
5513 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5514 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5515 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5516 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5517 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5519 && (SSE_REG_P (operands[0])
5520 || (GET_CODE (operands[0]) == SUBREG
5521 && SSE_REG_P (operands[0])))"
5522 [(set (match_dup 2) (match_dup 1))
5523 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5527 [(set (match_operand:MODEF 0 "register_operand" "")
5528 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5529 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5530 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5531 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5533 && (SSE_REG_P (operands[0])
5534 || (GET_CODE (operands[0]) == SUBREG
5535 && SSE_REG_P (operands[0])))"
5536 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5539 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5540 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5542 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5543 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5548 [(set_attr "type" "fmov,multi")
5549 (set_attr "mode" "<X87MODEF:MODE>")
5550 (set_attr "unit" "*,i387")
5551 (set_attr "fp_int_src" "true")])
5553 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5554 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5556 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5559 [(set_attr "type" "fmov")
5560 (set_attr "mode" "<X87MODEF:MODE>")
5561 (set_attr "fp_int_src" "true")])
5564 [(set (match_operand:X87MODEF 0 "register_operand" "")
5565 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5566 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5569 && FP_REG_P (operands[0])"
5570 [(set (match_dup 2) (match_dup 1))
5571 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5575 [(set (match_operand:X87MODEF 0 "register_operand" "")
5576 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5577 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5580 && FP_REG_P (operands[0])"
5581 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5584 ;; Avoid store forwarding (partial memory) stall penalty
5585 ;; by passing DImode value through XMM registers. */
5587 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5588 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5590 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5591 (clobber (match_scratch:V4SI 3 "=X,x"))
5592 (clobber (match_scratch:V4SI 4 "=X,x"))
5593 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5594 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5595 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5597 [(set_attr "type" "multi")
5598 (set_attr "mode" "<X87MODEF:MODE>")
5599 (set_attr "unit" "i387")
5600 (set_attr "fp_int_src" "true")])
5603 [(set (match_operand:X87MODEF 0 "register_operand" "")
5604 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5605 (clobber (match_scratch:V4SI 3 ""))
5606 (clobber (match_scratch:V4SI 4 ""))
5607 (clobber (match_operand:DI 2 "memory_operand" ""))]
5608 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5609 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5611 && FP_REG_P (operands[0])"
5612 [(set (match_dup 2) (match_dup 3))
5613 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5615 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5616 Assemble the 64-bit DImode value in an xmm register. */
5617 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5618 gen_rtx_SUBREG (SImode, operands[1], 0)));
5619 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5620 gen_rtx_SUBREG (SImode, operands[1], 4)));
5621 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5623 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5627 [(set (match_operand:X87MODEF 0 "register_operand" "")
5628 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5629 (clobber (match_scratch:V4SI 3 ""))
5630 (clobber (match_scratch:V4SI 4 ""))
5631 (clobber (match_operand:DI 2 "memory_operand" ""))]
5632 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5633 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5635 && FP_REG_P (operands[0])"
5636 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5639 ;; Avoid store forwarding (partial memory) stall penalty by extending
5640 ;; SImode value to DImode through XMM register instead of pushing two
5641 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5642 ;; targets benefit from this optimization. Also note that fild
5643 ;; loads from memory only.
5645 (define_insn "*floatunssi<mode>2_1"
5646 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5647 (unsigned_float:X87MODEF
5648 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5649 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5650 (clobber (match_scratch:SI 3 "=X,x"))]
5652 && TARGET_80387 && TARGET_SSE"
5654 [(set_attr "type" "multi")
5655 (set_attr "mode" "<MODE>")])
5658 [(set (match_operand:X87MODEF 0 "register_operand" "")
5659 (unsigned_float:X87MODEF
5660 (match_operand:SI 1 "register_operand" "")))
5661 (clobber (match_operand:DI 2 "memory_operand" ""))
5662 (clobber (match_scratch:SI 3 ""))]
5664 && TARGET_80387 && TARGET_SSE
5665 && reload_completed"
5666 [(set (match_dup 2) (match_dup 1))
5668 (float:X87MODEF (match_dup 2)))]
5669 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5672 [(set (match_operand:X87MODEF 0 "register_operand" "")
5673 (unsigned_float:X87MODEF
5674 (match_operand:SI 1 "memory_operand" "")))
5675 (clobber (match_operand:DI 2 "memory_operand" ""))
5676 (clobber (match_scratch:SI 3 ""))]
5678 && TARGET_80387 && TARGET_SSE
5679 && reload_completed"
5680 [(set (match_dup 2) (match_dup 3))
5682 (float:X87MODEF (match_dup 2)))]
5684 emit_move_insn (operands[3], operands[1]);
5685 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5688 (define_expand "floatunssi<mode>2"
5690 [(set (match_operand:X87MODEF 0 "register_operand" "")
5691 (unsigned_float:X87MODEF
5692 (match_operand:SI 1 "nonimmediate_operand" "")))
5693 (clobber (match_dup 2))
5694 (clobber (match_scratch:SI 3 ""))])]
5696 && ((TARGET_80387 && TARGET_SSE)
5697 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5699 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5701 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5706 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5707 operands[2] = assign_386_stack_local (DImode, slot);
5711 (define_expand "floatunsdisf2"
5712 [(use (match_operand:SF 0 "register_operand" ""))
5713 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5714 "TARGET_64BIT && TARGET_SSE_MATH"
5715 "x86_emit_floatuns (operands); DONE;")
5717 (define_expand "floatunsdidf2"
5718 [(use (match_operand:DF 0 "register_operand" ""))
5719 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5720 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5721 && TARGET_SSE2 && TARGET_SSE_MATH"
5724 x86_emit_floatuns (operands);
5726 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5732 ;; %%% splits for addditi3
5734 (define_expand "addti3"
5735 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5736 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5737 (match_operand:TI 2 "x86_64_general_operand" "")))]
5739 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5741 (define_insn "*addti3_1"
5742 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5743 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5744 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5750 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5751 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5752 (match_operand:TI 2 "x86_64_general_operand" "")))
5753 (clobber (reg:CC FLAGS_REG))]
5754 "TARGET_64BIT && reload_completed"
5755 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5757 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5758 (parallel [(set (match_dup 3)
5759 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5762 (clobber (reg:CC FLAGS_REG))])]
5763 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5765 ;; %%% splits for addsidi3
5766 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5767 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5768 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5770 (define_expand "adddi3"
5771 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5772 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5773 (match_operand:DI 2 "x86_64_general_operand" "")))]
5775 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5777 (define_insn "*adddi3_1"
5778 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5779 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5780 (match_operand:DI 2 "general_operand" "roiF,riF")))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5786 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5787 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5788 (match_operand:DI 2 "general_operand" "")))
5789 (clobber (reg:CC FLAGS_REG))]
5790 "!TARGET_64BIT && reload_completed"
5791 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5793 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5794 (parallel [(set (match_dup 3)
5795 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5798 (clobber (reg:CC FLAGS_REG))])]
5799 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5801 (define_insn "adddi3_carry_rex64"
5802 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5803 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5804 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5805 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5806 (clobber (reg:CC FLAGS_REG))]
5807 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5808 "adc{q}\t{%2, %0|%0, %2}"
5809 [(set_attr "type" "alu")
5810 (set_attr "pent_pair" "pu")
5811 (set_attr "mode" "DI")])
5813 (define_insn "*adddi3_cc_rex64"
5814 [(set (reg:CC FLAGS_REG)
5815 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5816 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5818 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5819 (plus:DI (match_dup 1) (match_dup 2)))]
5820 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5821 "add{q}\t{%2, %0|%0, %2}"
5822 [(set_attr "type" "alu")
5823 (set_attr "mode" "DI")])
5825 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5826 [(set (reg:CCC FLAGS_REG)
5829 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5830 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5832 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5833 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5834 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5835 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5836 [(set_attr "type" "alu")
5837 (set_attr "mode" "<MODE>")])
5839 (define_insn "*add<mode>3_cconly_overflow"
5840 [(set (reg:CCC FLAGS_REG)
5842 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5843 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5845 (clobber (match_scratch:SWI 0 "=<r>"))]
5846 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5847 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5848 [(set_attr "type" "alu")
5849 (set_attr "mode" "<MODE>")])
5851 (define_insn "*sub<mode>3_cconly_overflow"
5852 [(set (reg:CCC FLAGS_REG)
5854 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5855 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5858 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5859 [(set_attr "type" "icmp")
5860 (set_attr "mode" "<MODE>")])
5862 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5863 [(set (reg:CCC FLAGS_REG)
5865 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5866 (match_operand:SI 2 "general_operand" "g"))
5868 (set (match_operand:DI 0 "register_operand" "=r")
5869 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5870 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5871 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5872 [(set_attr "type" "alu")
5873 (set_attr "mode" "SI")])
5875 (define_insn "addqi3_carry"
5876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5877 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5878 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5879 (match_operand:QI 2 "general_operand" "qn,qm")))
5880 (clobber (reg:CC FLAGS_REG))]
5881 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5882 "adc{b}\t{%2, %0|%0, %2}"
5883 [(set_attr "type" "alu")
5884 (set_attr "pent_pair" "pu")
5885 (set_attr "mode" "QI")])
5887 (define_insn "addhi3_carry"
5888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5889 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5890 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5891 (match_operand:HI 2 "general_operand" "rn,rm")))
5892 (clobber (reg:CC FLAGS_REG))]
5893 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5894 "adc{w}\t{%2, %0|%0, %2}"
5895 [(set_attr "type" "alu")
5896 (set_attr "pent_pair" "pu")
5897 (set_attr "mode" "HI")])
5899 (define_insn "addsi3_carry"
5900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5901 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5902 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5903 (match_operand:SI 2 "general_operand" "ri,rm")))
5904 (clobber (reg:CC FLAGS_REG))]
5905 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5906 "adc{l}\t{%2, %0|%0, %2}"
5907 [(set_attr "type" "alu")
5908 (set_attr "pent_pair" "pu")
5909 (set_attr "mode" "SI")])
5911 (define_insn "*addsi3_carry_zext"
5912 [(set (match_operand:DI 0 "register_operand" "=r")
5914 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5915 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5916 (match_operand:SI 2 "general_operand" "g"))))
5917 (clobber (reg:CC FLAGS_REG))]
5918 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5919 "adc{l}\t{%2, %k0|%k0, %2}"
5920 [(set_attr "type" "alu")
5921 (set_attr "pent_pair" "pu")
5922 (set_attr "mode" "SI")])
5924 (define_insn "*addsi3_cc"
5925 [(set (reg:CC FLAGS_REG)
5926 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5927 (match_operand:SI 2 "general_operand" "ri,rm")]
5929 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5930 (plus:SI (match_dup 1) (match_dup 2)))]
5931 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5932 "add{l}\t{%2, %0|%0, %2}"
5933 [(set_attr "type" "alu")
5934 (set_attr "mode" "SI")])
5936 (define_insn "addqi3_cc"
5937 [(set (reg:CC FLAGS_REG)
5938 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5939 (match_operand:QI 2 "general_operand" "qn,qm")]
5941 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5942 (plus:QI (match_dup 1) (match_dup 2)))]
5943 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5944 "add{b}\t{%2, %0|%0, %2}"
5945 [(set_attr "type" "alu")
5946 (set_attr "mode" "QI")])
5948 (define_expand "addsi3"
5949 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5950 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5951 (match_operand:SI 2 "general_operand" "")))]
5953 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5955 (define_insn "*lea_1"
5956 [(set (match_operand:SI 0 "register_operand" "=r")
5957 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5959 "lea{l}\t{%a1, %0|%0, %a1}"
5960 [(set_attr "type" "lea")
5961 (set_attr "mode" "SI")])
5963 (define_insn "*lea_1_rex64"
5964 [(set (match_operand:SI 0 "register_operand" "=r")
5965 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5967 "lea{l}\t{%a1, %0|%0, %a1}"
5968 [(set_attr "type" "lea")
5969 (set_attr "mode" "SI")])
5971 (define_insn "*lea_1_zext"
5972 [(set (match_operand:DI 0 "register_operand" "=r")
5974 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5976 "lea{l}\t{%a1, %k0|%k0, %a1}"
5977 [(set_attr "type" "lea")
5978 (set_attr "mode" "SI")])
5980 (define_insn "*lea_2_rex64"
5981 [(set (match_operand:DI 0 "register_operand" "=r")
5982 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5984 "lea{q}\t{%a1, %0|%0, %a1}"
5985 [(set_attr "type" "lea")
5986 (set_attr "mode" "DI")])
5988 ;; The lea patterns for non-Pmodes needs to be matched by several
5989 ;; insns converted to real lea by splitters.
5991 (define_insn_and_split "*lea_general_1"
5992 [(set (match_operand 0 "register_operand" "=r")
5993 (plus (plus (match_operand 1 "index_register_operand" "l")
5994 (match_operand 2 "register_operand" "r"))
5995 (match_operand 3 "immediate_operand" "i")))]
5996 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5997 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5998 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5999 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6000 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6001 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6002 || GET_MODE (operands[3]) == VOIDmode)"
6004 "&& reload_completed"
6008 operands[0] = gen_lowpart (SImode, operands[0]);
6009 operands[1] = gen_lowpart (Pmode, operands[1]);
6010 operands[2] = gen_lowpart (Pmode, operands[2]);
6011 operands[3] = gen_lowpart (Pmode, operands[3]);
6012 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6014 if (Pmode != SImode)
6015 pat = gen_rtx_SUBREG (SImode, pat, 0);
6016 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6019 [(set_attr "type" "lea")
6020 (set_attr "mode" "SI")])
6022 (define_insn_and_split "*lea_general_1_zext"
6023 [(set (match_operand:DI 0 "register_operand" "=r")
6025 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6026 (match_operand:SI 2 "register_operand" "r"))
6027 (match_operand:SI 3 "immediate_operand" "i"))))]
6030 "&& reload_completed"
6032 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6034 (match_dup 3)) 0)))]
6036 operands[1] = gen_lowpart (Pmode, operands[1]);
6037 operands[2] = gen_lowpart (Pmode, operands[2]);
6038 operands[3] = gen_lowpart (Pmode, operands[3]);
6040 [(set_attr "type" "lea")
6041 (set_attr "mode" "SI")])
6043 (define_insn_and_split "*lea_general_2"
6044 [(set (match_operand 0 "register_operand" "=r")
6045 (plus (mult (match_operand 1 "index_register_operand" "l")
6046 (match_operand 2 "const248_operand" "i"))
6047 (match_operand 3 "nonmemory_operand" "ri")))]
6048 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6049 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6050 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6051 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6052 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6053 || GET_MODE (operands[3]) == VOIDmode)"
6055 "&& reload_completed"
6059 operands[0] = gen_lowpart (SImode, operands[0]);
6060 operands[1] = gen_lowpart (Pmode, operands[1]);
6061 operands[3] = gen_lowpart (Pmode, operands[3]);
6062 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6064 if (Pmode != SImode)
6065 pat = gen_rtx_SUBREG (SImode, pat, 0);
6066 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6069 [(set_attr "type" "lea")
6070 (set_attr "mode" "SI")])
6072 (define_insn_and_split "*lea_general_2_zext"
6073 [(set (match_operand:DI 0 "register_operand" "=r")
6075 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6076 (match_operand:SI 2 "const248_operand" "n"))
6077 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6080 "&& reload_completed"
6082 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6084 (match_dup 3)) 0)))]
6086 operands[1] = gen_lowpart (Pmode, operands[1]);
6087 operands[3] = gen_lowpart (Pmode, operands[3]);
6089 [(set_attr "type" "lea")
6090 (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_3"
6093 [(set (match_operand 0 "register_operand" "=r")
6094 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6095 (match_operand 2 "const248_operand" "i"))
6096 (match_operand 3 "register_operand" "r"))
6097 (match_operand 4 "immediate_operand" "i")))]
6098 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6099 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6100 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6101 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6102 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6104 "&& reload_completed"
6108 operands[0] = gen_lowpart (SImode, operands[0]);
6109 operands[1] = gen_lowpart (Pmode, operands[1]);
6110 operands[3] = gen_lowpart (Pmode, operands[3]);
6111 operands[4] = gen_lowpart (Pmode, operands[4]);
6112 pat = gen_rtx_PLUS (Pmode,
6113 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6117 if (Pmode != SImode)
6118 pat = gen_rtx_SUBREG (SImode, pat, 0);
6119 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6122 [(set_attr "type" "lea")
6123 (set_attr "mode" "SI")])
6125 (define_insn_and_split "*lea_general_3_zext"
6126 [(set (match_operand:DI 0 "register_operand" "=r")
6128 (plus:SI (plus:SI (mult:SI
6129 (match_operand:SI 1 "index_register_operand" "l")
6130 (match_operand:SI 2 "const248_operand" "n"))
6131 (match_operand:SI 3 "register_operand" "r"))
6132 (match_operand:SI 4 "immediate_operand" "i"))))]
6135 "&& reload_completed"
6137 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6140 (match_dup 4)) 0)))]
6142 operands[1] = gen_lowpart (Pmode, operands[1]);
6143 operands[3] = gen_lowpart (Pmode, operands[3]);
6144 operands[4] = gen_lowpart (Pmode, operands[4]);
6146 [(set_attr "type" "lea")
6147 (set_attr "mode" "SI")])
6149 (define_insn "*adddi_1_rex64"
6150 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6151 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6152 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6153 (clobber (reg:CC FLAGS_REG))]
6154 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6156 switch (get_attr_type (insn))
6159 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6160 return "lea{q}\t{%a2, %0|%0, %a2}";
6163 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6164 if (operands[2] == const1_rtx)
6165 return "inc{q}\t%0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{q}\t%0";
6173 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6175 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6177 if (CONST_INT_P (operands[2])
6178 /* Avoid overflows. */
6179 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6180 && (INTVAL (operands[2]) == 128
6181 || (INTVAL (operands[2]) < 0
6182 && INTVAL (operands[2]) != -128)))
6184 operands[2] = GEN_INT (-INTVAL (operands[2]));
6185 return "sub{q}\t{%2, %0|%0, %2}";
6187 return "add{q}\t{%2, %0|%0, %2}";
6191 (cond [(eq_attr "alternative" "2")
6192 (const_string "lea")
6193 ; Current assemblers are broken and do not allow @GOTOFF in
6194 ; ought but a memory context.
6195 (match_operand:DI 2 "pic_symbolic_operand" "")
6196 (const_string "lea")
6197 (match_operand:DI 2 "incdec_operand" "")
6198 (const_string "incdec")
6200 (const_string "alu")))
6201 (set_attr "mode" "DI")])
6203 ;; Convert lea to the lea pattern to avoid flags dependency.
6205 [(set (match_operand:DI 0 "register_operand" "")
6206 (plus:DI (match_operand:DI 1 "register_operand" "")
6207 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6208 (clobber (reg:CC FLAGS_REG))]
6209 "TARGET_64BIT && reload_completed
6210 && true_regnum (operands[0]) != true_regnum (operands[1])"
6212 (plus:DI (match_dup 1)
6216 (define_insn "*adddi_2_rex64"
6217 [(set (reg FLAGS_REG)
6219 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6220 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6222 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6223 (plus:DI (match_dup 1) (match_dup 2)))]
6224 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6225 && ix86_binary_operator_ok (PLUS, DImode, operands)
6226 /* Current assemblers are broken and do not allow @GOTOFF in
6227 ought but a memory context. */
6228 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6230 switch (get_attr_type (insn))
6233 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6234 if (operands[2] == const1_rtx)
6235 return "inc{q}\t%0";
6238 gcc_assert (operands[2] == constm1_rtx);
6239 return "dec{q}\t%0";
6243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6244 /* ???? We ought to handle there the 32bit case too
6245 - do we need new constraint? */
6246 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6247 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6248 if (CONST_INT_P (operands[2])
6249 /* Avoid overflows. */
6250 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6251 && (INTVAL (operands[2]) == 128
6252 || (INTVAL (operands[2]) < 0
6253 && INTVAL (operands[2]) != -128)))
6255 operands[2] = GEN_INT (-INTVAL (operands[2]));
6256 return "sub{q}\t{%2, %0|%0, %2}";
6258 return "add{q}\t{%2, %0|%0, %2}";
6262 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6263 (const_string "incdec")
6264 (const_string "alu")))
6265 (set_attr "mode" "DI")])
6267 (define_insn "*adddi_3_rex64"
6268 [(set (reg FLAGS_REG)
6269 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6270 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6271 (clobber (match_scratch:DI 0 "=r"))]
6273 && ix86_match_ccmode (insn, CCZmode)
6274 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6275 /* Current assemblers are broken and do not allow @GOTOFF in
6276 ought but a memory context. */
6277 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6279 switch (get_attr_type (insn))
6282 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6283 if (operands[2] == const1_rtx)
6284 return "inc{q}\t%0";
6287 gcc_assert (operands[2] == constm1_rtx);
6288 return "dec{q}\t%0";
6292 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6293 /* ???? We ought to handle there the 32bit case too
6294 - do we need new constraint? */
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 /* Avoid overflows. */
6299 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6300 && (INTVAL (operands[2]) == 128
6301 || (INTVAL (operands[2]) < 0
6302 && INTVAL (operands[2]) != -128)))
6304 operands[2] = GEN_INT (-INTVAL (operands[2]));
6305 return "sub{q}\t{%2, %0|%0, %2}";
6307 return "add{q}\t{%2, %0|%0, %2}";
6311 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6312 (const_string "incdec")
6313 (const_string "alu")))
6314 (set_attr "mode" "DI")])
6316 ; For comparisons against 1, -1 and 128, we may generate better code
6317 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6318 ; is matched then. We can't accept general immediate, because for
6319 ; case of overflows, the result is messed up.
6320 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6322 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6323 ; only for comparisons not depending on it.
6324 (define_insn "*adddi_4_rex64"
6325 [(set (reg FLAGS_REG)
6326 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6327 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6328 (clobber (match_scratch:DI 0 "=rm"))]
6330 && ix86_match_ccmode (insn, CCGCmode)"
6332 switch (get_attr_type (insn))
6335 if (operands[2] == constm1_rtx)
6336 return "inc{q}\t%0";
6339 gcc_assert (operands[2] == const1_rtx);
6340 return "dec{q}\t%0";
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6346 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6347 if ((INTVAL (operands[2]) == -128
6348 || (INTVAL (operands[2]) > 0
6349 && INTVAL (operands[2]) != 128))
6350 /* Avoid overflows. */
6351 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6352 return "sub{q}\t{%2, %0|%0, %2}";
6353 operands[2] = GEN_INT (-INTVAL (operands[2]));
6354 return "add{q}\t{%2, %0|%0, %2}";
6358 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "DI")])
6363 (define_insn "*adddi_5_rex64"
6364 [(set (reg FLAGS_REG)
6366 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6367 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6369 (clobber (match_scratch:DI 0 "=r"))]
6371 && ix86_match_ccmode (insn, CCGOCmode)
6372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6373 /* Current assemblers are broken and do not allow @GOTOFF in
6374 ought but a memory context. */
6375 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6377 switch (get_attr_type (insn))
6380 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6381 if (operands[2] == const1_rtx)
6382 return "inc{q}\t%0";
6385 gcc_assert (operands[2] == constm1_rtx);
6386 return "dec{q}\t%0";
6390 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6391 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6392 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6393 if (CONST_INT_P (operands[2])
6394 /* Avoid overflows. */
6395 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6396 && (INTVAL (operands[2]) == 128
6397 || (INTVAL (operands[2]) < 0
6398 && INTVAL (operands[2]) != -128)))
6400 operands[2] = GEN_INT (-INTVAL (operands[2]));
6401 return "sub{q}\t{%2, %0|%0, %2}";
6403 return "add{q}\t{%2, %0|%0, %2}";
6407 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6408 (const_string "incdec")
6409 (const_string "alu")))
6410 (set_attr "mode" "DI")])
6413 (define_insn "*addsi_1"
6414 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6415 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6416 (match_operand:SI 2 "general_operand" "g,ri,li")))
6417 (clobber (reg:CC FLAGS_REG))]
6418 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6420 switch (get_attr_type (insn))
6423 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6424 return "lea{l}\t{%a2, %0|%0, %a2}";
6427 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6428 if (operands[2] == const1_rtx)
6429 return "inc{l}\t%0";
6432 gcc_assert (operands[2] == constm1_rtx);
6433 return "dec{l}\t%0";
6437 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6439 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6440 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6441 if (CONST_INT_P (operands[2])
6442 && (INTVAL (operands[2]) == 128
6443 || (INTVAL (operands[2]) < 0
6444 && INTVAL (operands[2]) != -128)))
6446 operands[2] = GEN_INT (-INTVAL (operands[2]));
6447 return "sub{l}\t{%2, %0|%0, %2}";
6449 return "add{l}\t{%2, %0|%0, %2}";
6453 (cond [(eq_attr "alternative" "2")
6454 (const_string "lea")
6455 ; Current assemblers are broken and do not allow @GOTOFF in
6456 ; ought but a memory context.
6457 (match_operand:SI 2 "pic_symbolic_operand" "")
6458 (const_string "lea")
6459 (match_operand:SI 2 "incdec_operand" "")
6460 (const_string "incdec")
6462 (const_string "alu")))
6463 (set_attr "mode" "SI")])
6465 ;; Convert lea to the lea pattern to avoid flags dependency.
6467 [(set (match_operand 0 "register_operand" "")
6468 (plus (match_operand 1 "register_operand" "")
6469 (match_operand 2 "nonmemory_operand" "")))
6470 (clobber (reg:CC FLAGS_REG))]
6472 && true_regnum (operands[0]) != true_regnum (operands[1])"
6476 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6477 may confuse gen_lowpart. */
6478 if (GET_MODE (operands[0]) != Pmode)
6480 operands[1] = gen_lowpart (Pmode, operands[1]);
6481 operands[2] = gen_lowpart (Pmode, operands[2]);
6483 operands[0] = gen_lowpart (SImode, operands[0]);
6484 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6485 if (Pmode != SImode)
6486 pat = gen_rtx_SUBREG (SImode, pat, 0);
6487 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6491 ;; It may seem that nonimmediate operand is proper one for operand 1.
6492 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6493 ;; we take care in ix86_binary_operator_ok to not allow two memory
6494 ;; operands so proper swapping will be done in reload. This allow
6495 ;; patterns constructed from addsi_1 to match.
6496 (define_insn "addsi_1_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r,r")
6499 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6500 (match_operand:SI 2 "general_operand" "g,li"))))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6504 switch (get_attr_type (insn))
6507 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6508 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6511 if (operands[2] == const1_rtx)
6512 return "inc{l}\t%k0";
6515 gcc_assert (operands[2] == constm1_rtx);
6516 return "dec{l}\t%k0";
6520 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6521 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6522 if (CONST_INT_P (operands[2])
6523 && (INTVAL (operands[2]) == 128
6524 || (INTVAL (operands[2]) < 0
6525 && INTVAL (operands[2]) != -128)))
6527 operands[2] = GEN_INT (-INTVAL (operands[2]));
6528 return "sub{l}\t{%2, %k0|%k0, %2}";
6530 return "add{l}\t{%2, %k0|%k0, %2}";
6534 (cond [(eq_attr "alternative" "1")
6535 (const_string "lea")
6536 ; Current assemblers are broken and do not allow @GOTOFF in
6537 ; ought but a memory context.
6538 (match_operand:SI 2 "pic_symbolic_operand" "")
6539 (const_string "lea")
6540 (match_operand:SI 2 "incdec_operand" "")
6541 (const_string "incdec")
6543 (const_string "alu")))
6544 (set_attr "mode" "SI")])
6546 ;; Convert lea to the lea pattern to avoid flags dependency.
6548 [(set (match_operand:DI 0 "register_operand" "")
6550 (plus:SI (match_operand:SI 1 "register_operand" "")
6551 (match_operand:SI 2 "nonmemory_operand" ""))))
6552 (clobber (reg:CC FLAGS_REG))]
6553 "TARGET_64BIT && reload_completed
6554 && true_regnum (operands[0]) != true_regnum (operands[1])"
6556 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6558 operands[1] = gen_lowpart (Pmode, operands[1]);
6559 operands[2] = gen_lowpart (Pmode, operands[2]);
6562 (define_insn "*addsi_2"
6563 [(set (reg FLAGS_REG)
6565 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6566 (match_operand:SI 2 "general_operand" "g,ri"))
6568 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6569 (plus:SI (match_dup 1) (match_dup 2)))]
6570 "ix86_match_ccmode (insn, CCGOCmode)
6571 && ix86_binary_operator_ok (PLUS, SImode, operands)
6572 /* Current assemblers are broken and do not allow @GOTOFF in
6573 ought but a memory context. */
6574 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6576 switch (get_attr_type (insn))
6579 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6580 if (operands[2] == const1_rtx)
6581 return "inc{l}\t%0";
6584 gcc_assert (operands[2] == constm1_rtx);
6585 return "dec{l}\t%0";
6589 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6590 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6591 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6592 if (CONST_INT_P (operands[2])
6593 && (INTVAL (operands[2]) == 128
6594 || (INTVAL (operands[2]) < 0
6595 && INTVAL (operands[2]) != -128)))
6597 operands[2] = GEN_INT (-INTVAL (operands[2]));
6598 return "sub{l}\t{%2, %0|%0, %2}";
6600 return "add{l}\t{%2, %0|%0, %2}";
6604 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6605 (const_string "incdec")
6606 (const_string "alu")))
6607 (set_attr "mode" "SI")])
6609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6610 (define_insn "*addsi_2_zext"
6611 [(set (reg FLAGS_REG)
6613 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6614 (match_operand:SI 2 "general_operand" "g"))
6616 (set (match_operand:DI 0 "register_operand" "=r")
6617 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6618 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6619 && ix86_binary_operator_ok (PLUS, SImode, operands)
6620 /* Current assemblers are broken and do not allow @GOTOFF in
6621 ought but a memory context. */
6622 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6624 switch (get_attr_type (insn))
6627 if (operands[2] == const1_rtx)
6628 return "inc{l}\t%k0";
6631 gcc_assert (operands[2] == constm1_rtx);
6632 return "dec{l}\t%k0";
6636 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6637 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6638 if (CONST_INT_P (operands[2])
6639 && (INTVAL (operands[2]) == 128
6640 || (INTVAL (operands[2]) < 0
6641 && INTVAL (operands[2]) != -128)))
6643 operands[2] = GEN_INT (-INTVAL (operands[2]));
6644 return "sub{l}\t{%2, %k0|%k0, %2}";
6646 return "add{l}\t{%2, %k0|%k0, %2}";
6650 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6651 (const_string "incdec")
6652 (const_string "alu")))
6653 (set_attr "mode" "SI")])
6655 (define_insn "*addsi_3"
6656 [(set (reg FLAGS_REG)
6657 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6658 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6659 (clobber (match_scratch:SI 0 "=r"))]
6660 "ix86_match_ccmode (insn, CCZmode)
6661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6662 /* Current assemblers are broken and do not allow @GOTOFF in
6663 ought but a memory context. */
6664 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6666 switch (get_attr_type (insn))
6669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6670 if (operands[2] == const1_rtx)
6671 return "inc{l}\t%0";
6674 gcc_assert (operands[2] == constm1_rtx);
6675 return "dec{l}\t%0";
6679 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6680 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6681 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6682 if (CONST_INT_P (operands[2])
6683 && (INTVAL (operands[2]) == 128
6684 || (INTVAL (operands[2]) < 0
6685 && INTVAL (operands[2]) != -128)))
6687 operands[2] = GEN_INT (-INTVAL (operands[2]));
6688 return "sub{l}\t{%2, %0|%0, %2}";
6690 return "add{l}\t{%2, %0|%0, %2}";
6694 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6695 (const_string "incdec")
6696 (const_string "alu")))
6697 (set_attr "mode" "SI")])
6699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6700 (define_insn "*addsi_3_zext"
6701 [(set (reg FLAGS_REG)
6702 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6703 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6704 (set (match_operand:DI 0 "register_operand" "=r")
6705 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6706 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6707 && ix86_binary_operator_ok (PLUS, SImode, operands)
6708 /* Current assemblers are broken and do not allow @GOTOFF in
6709 ought but a memory context. */
6710 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6712 switch (get_attr_type (insn))
6715 if (operands[2] == const1_rtx)
6716 return "inc{l}\t%k0";
6719 gcc_assert (operands[2] == constm1_rtx);
6720 return "dec{l}\t%k0";
6724 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6725 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6726 if (CONST_INT_P (operands[2])
6727 && (INTVAL (operands[2]) == 128
6728 || (INTVAL (operands[2]) < 0
6729 && INTVAL (operands[2]) != -128)))
6731 operands[2] = GEN_INT (-INTVAL (operands[2]));
6732 return "sub{l}\t{%2, %k0|%k0, %2}";
6734 return "add{l}\t{%2, %k0|%k0, %2}";
6738 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6739 (const_string "incdec")
6740 (const_string "alu")))
6741 (set_attr "mode" "SI")])
6743 ; For comparisons against 1, -1 and 128, we may generate better code
6744 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6745 ; is matched then. We can't accept general immediate, because for
6746 ; case of overflows, the result is messed up.
6747 ; This pattern also don't hold of 0x80000000, since the value overflows
6749 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6750 ; only for comparisons not depending on it.
6751 (define_insn "*addsi_4"
6752 [(set (reg FLAGS_REG)
6753 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6754 (match_operand:SI 2 "const_int_operand" "n")))
6755 (clobber (match_scratch:SI 0 "=rm"))]
6756 "ix86_match_ccmode (insn, CCGCmode)
6757 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6759 switch (get_attr_type (insn))
6762 if (operands[2] == constm1_rtx)
6763 return "inc{l}\t%0";
6766 gcc_assert (operands[2] == const1_rtx);
6767 return "dec{l}\t%0";
6771 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6773 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6774 if ((INTVAL (operands[2]) == -128
6775 || (INTVAL (operands[2]) > 0
6776 && INTVAL (operands[2]) != 128)))
6777 return "sub{l}\t{%2, %0|%0, %2}";
6778 operands[2] = GEN_INT (-INTVAL (operands[2]));
6779 return "add{l}\t{%2, %0|%0, %2}";
6783 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6784 (const_string "incdec")
6785 (const_string "alu")))
6786 (set_attr "mode" "SI")])
6788 (define_insn "*addsi_5"
6789 [(set (reg FLAGS_REG)
6791 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6792 (match_operand:SI 2 "general_operand" "g"))
6794 (clobber (match_scratch:SI 0 "=r"))]
6795 "ix86_match_ccmode (insn, CCGOCmode)
6796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6797 /* Current assemblers are broken and do not allow @GOTOFF in
6798 ought but a memory context. */
6799 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6801 switch (get_attr_type (insn))
6804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805 if (operands[2] == const1_rtx)
6806 return "inc{l}\t%0";
6809 gcc_assert (operands[2] == constm1_rtx);
6810 return "dec{l}\t%0";
6814 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6815 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6816 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6817 if (CONST_INT_P (operands[2])
6818 && (INTVAL (operands[2]) == 128
6819 || (INTVAL (operands[2]) < 0
6820 && INTVAL (operands[2]) != -128)))
6822 operands[2] = GEN_INT (-INTVAL (operands[2]));
6823 return "sub{l}\t{%2, %0|%0, %2}";
6825 return "add{l}\t{%2, %0|%0, %2}";
6829 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6830 (const_string "incdec")
6831 (const_string "alu")))
6832 (set_attr "mode" "SI")])
6834 (define_expand "addhi3"
6835 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6836 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6837 (match_operand:HI 2 "general_operand" "")))]
6838 "TARGET_HIMODE_MATH"
6839 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6841 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6842 ;; type optimizations enabled by define-splits. This is not important
6843 ;; for PII, and in fact harmful because of partial register stalls.
6845 (define_insn "*addhi_1_lea"
6846 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6847 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6848 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6849 (clobber (reg:CC FLAGS_REG))]
6850 "!TARGET_PARTIAL_REG_STALL
6851 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6853 switch (get_attr_type (insn))
6858 if (operands[2] == const1_rtx)
6859 return "inc{w}\t%0";
6862 gcc_assert (operands[2] == constm1_rtx);
6863 return "dec{w}\t%0";
6867 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6868 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6869 if (CONST_INT_P (operands[2])
6870 && (INTVAL (operands[2]) == 128
6871 || (INTVAL (operands[2]) < 0
6872 && INTVAL (operands[2]) != -128)))
6874 operands[2] = GEN_INT (-INTVAL (operands[2]));
6875 return "sub{w}\t{%2, %0|%0, %2}";
6877 return "add{w}\t{%2, %0|%0, %2}";
6881 (if_then_else (eq_attr "alternative" "2")
6882 (const_string "lea")
6883 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6884 (const_string "incdec")
6885 (const_string "alu"))))
6886 (set_attr "mode" "HI,HI,SI")])
6888 (define_insn "*addhi_1"
6889 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6890 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6891 (match_operand:HI 2 "general_operand" "rn,rm")))
6892 (clobber (reg:CC FLAGS_REG))]
6893 "TARGET_PARTIAL_REG_STALL
6894 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6896 switch (get_attr_type (insn))
6899 if (operands[2] == const1_rtx)
6900 return "inc{w}\t%0";
6903 gcc_assert (operands[2] == constm1_rtx);
6904 return "dec{w}\t%0";
6908 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6909 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6910 if (CONST_INT_P (operands[2])
6911 && (INTVAL (operands[2]) == 128
6912 || (INTVAL (operands[2]) < 0
6913 && INTVAL (operands[2]) != -128)))
6915 operands[2] = GEN_INT (-INTVAL (operands[2]));
6916 return "sub{w}\t{%2, %0|%0, %2}";
6918 return "add{w}\t{%2, %0|%0, %2}";
6922 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6923 (const_string "incdec")
6924 (const_string "alu")))
6925 (set_attr "mode" "HI")])
6927 (define_insn "*addhi_2"
6928 [(set (reg FLAGS_REG)
6930 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6931 (match_operand:HI 2 "general_operand" "rmn,rn"))
6933 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6934 (plus:HI (match_dup 1) (match_dup 2)))]
6935 "ix86_match_ccmode (insn, CCGOCmode)
6936 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6938 switch (get_attr_type (insn))
6941 if (operands[2] == const1_rtx)
6942 return "inc{w}\t%0";
6945 gcc_assert (operands[2] == constm1_rtx);
6946 return "dec{w}\t%0";
6950 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6951 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6952 if (CONST_INT_P (operands[2])
6953 && (INTVAL (operands[2]) == 128
6954 || (INTVAL (operands[2]) < 0
6955 && INTVAL (operands[2]) != -128)))
6957 operands[2] = GEN_INT (-INTVAL (operands[2]));
6958 return "sub{w}\t{%2, %0|%0, %2}";
6960 return "add{w}\t{%2, %0|%0, %2}";
6964 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6965 (const_string "incdec")
6966 (const_string "alu")))
6967 (set_attr "mode" "HI")])
6969 (define_insn "*addhi_3"
6970 [(set (reg FLAGS_REG)
6971 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6972 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6973 (clobber (match_scratch:HI 0 "=r"))]
6974 "ix86_match_ccmode (insn, CCZmode)
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977 switch (get_attr_type (insn))
6980 if (operands[2] == const1_rtx)
6981 return "inc{w}\t%0";
6984 gcc_assert (operands[2] == constm1_rtx);
6985 return "dec{w}\t%0";
6989 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6990 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6991 if (CONST_INT_P (operands[2])
6992 && (INTVAL (operands[2]) == 128
6993 || (INTVAL (operands[2]) < 0
6994 && INTVAL (operands[2]) != -128)))
6996 operands[2] = GEN_INT (-INTVAL (operands[2]));
6997 return "sub{w}\t{%2, %0|%0, %2}";
6999 return "add{w}\t{%2, %0|%0, %2}";
7003 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7004 (const_string "incdec")
7005 (const_string "alu")))
7006 (set_attr "mode" "HI")])
7008 ; See comments above addsi_4 for details.
7009 (define_insn "*addhi_4"
7010 [(set (reg FLAGS_REG)
7011 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7012 (match_operand:HI 2 "const_int_operand" "n")))
7013 (clobber (match_scratch:HI 0 "=rm"))]
7014 "ix86_match_ccmode (insn, CCGCmode)
7015 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7017 switch (get_attr_type (insn))
7020 if (operands[2] == constm1_rtx)
7021 return "inc{w}\t%0";
7024 gcc_assert (operands[2] == const1_rtx);
7025 return "dec{w}\t%0";
7029 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7030 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7031 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7032 if ((INTVAL (operands[2]) == -128
7033 || (INTVAL (operands[2]) > 0
7034 && INTVAL (operands[2]) != 128)))
7035 return "sub{w}\t{%2, %0|%0, %2}";
7036 operands[2] = GEN_INT (-INTVAL (operands[2]));
7037 return "add{w}\t{%2, %0|%0, %2}";
7041 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7042 (const_string "incdec")
7043 (const_string "alu")))
7044 (set_attr "mode" "SI")])
7047 (define_insn "*addhi_5"
7048 [(set (reg FLAGS_REG)
7050 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7051 (match_operand:HI 2 "general_operand" "rmn"))
7053 (clobber (match_scratch:HI 0 "=r"))]
7054 "ix86_match_ccmode (insn, CCGOCmode)
7055 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7057 switch (get_attr_type (insn))
7060 if (operands[2] == const1_rtx)
7061 return "inc{w}\t%0";
7064 gcc_assert (operands[2] == constm1_rtx);
7065 return "dec{w}\t%0";
7069 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7070 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7071 if (CONST_INT_P (operands[2])
7072 && (INTVAL (operands[2]) == 128
7073 || (INTVAL (operands[2]) < 0
7074 && INTVAL (operands[2]) != -128)))
7076 operands[2] = GEN_INT (-INTVAL (operands[2]));
7077 return "sub{w}\t{%2, %0|%0, %2}";
7079 return "add{w}\t{%2, %0|%0, %2}";
7083 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7084 (const_string "incdec")
7085 (const_string "alu")))
7086 (set_attr "mode" "HI")])
7088 (define_expand "addqi3"
7089 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7090 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7091 (match_operand:QI 2 "general_operand" "")))]
7092 "TARGET_QIMODE_MATH"
7093 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7095 ;; %%% Potential partial reg stall on alternative 2. What to do?
7096 (define_insn "*addqi_1_lea"
7097 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7098 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7099 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7100 (clobber (reg:CC FLAGS_REG))]
7101 "!TARGET_PARTIAL_REG_STALL
7102 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7104 int widen = (which_alternative == 2);
7105 switch (get_attr_type (insn))
7110 if (operands[2] == const1_rtx)
7111 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7114 gcc_assert (operands[2] == constm1_rtx);
7115 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7119 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7120 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7121 if (CONST_INT_P (operands[2])
7122 && (INTVAL (operands[2]) == 128
7123 || (INTVAL (operands[2]) < 0
7124 && INTVAL (operands[2]) != -128)))
7126 operands[2] = GEN_INT (-INTVAL (operands[2]));
7128 return "sub{l}\t{%2, %k0|%k0, %2}";
7130 return "sub{b}\t{%2, %0|%0, %2}";
7133 return "add{l}\t{%k2, %k0|%k0, %k2}";
7135 return "add{b}\t{%2, %0|%0, %2}";
7139 (if_then_else (eq_attr "alternative" "3")
7140 (const_string "lea")
7141 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7142 (const_string "incdec")
7143 (const_string "alu"))))
7144 (set_attr "mode" "QI,QI,SI,SI")])
7146 (define_insn "*addqi_1"
7147 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7148 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7149 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7150 (clobber (reg:CC FLAGS_REG))]
7151 "TARGET_PARTIAL_REG_STALL
7152 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7154 int widen = (which_alternative == 2);
7155 switch (get_attr_type (insn))
7158 if (operands[2] == const1_rtx)
7159 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7162 gcc_assert (operands[2] == constm1_rtx);
7163 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7167 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7168 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7169 if (CONST_INT_P (operands[2])
7170 && (INTVAL (operands[2]) == 128
7171 || (INTVAL (operands[2]) < 0
7172 && INTVAL (operands[2]) != -128)))
7174 operands[2] = GEN_INT (-INTVAL (operands[2]));
7176 return "sub{l}\t{%2, %k0|%k0, %2}";
7178 return "sub{b}\t{%2, %0|%0, %2}";
7181 return "add{l}\t{%k2, %k0|%k0, %k2}";
7183 return "add{b}\t{%2, %0|%0, %2}";
7187 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7188 (const_string "incdec")
7189 (const_string "alu")))
7190 (set_attr "mode" "QI,QI,SI")])
7192 (define_insn "*addqi_1_slp"
7193 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7194 (plus:QI (match_dup 0)
7195 (match_operand:QI 1 "general_operand" "qn,qnm")))
7196 (clobber (reg:CC FLAGS_REG))]
7197 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7198 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7200 switch (get_attr_type (insn))
7203 if (operands[1] == const1_rtx)
7204 return "inc{b}\t%0";
7207 gcc_assert (operands[1] == constm1_rtx);
7208 return "dec{b}\t%0";
7212 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7213 if (CONST_INT_P (operands[1])
7214 && INTVAL (operands[1]) < 0)
7216 operands[1] = GEN_INT (-INTVAL (operands[1]));
7217 return "sub{b}\t{%1, %0|%0, %1}";
7219 return "add{b}\t{%1, %0|%0, %1}";
7223 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7224 (const_string "incdec")
7225 (const_string "alu1")))
7226 (set (attr "memory")
7227 (if_then_else (match_operand 1 "memory_operand" "")
7228 (const_string "load")
7229 (const_string "none")))
7230 (set_attr "mode" "QI")])
7232 (define_insn "*addqi_2"
7233 [(set (reg FLAGS_REG)
7235 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7236 (match_operand:QI 2 "general_operand" "qmn,qn"))
7238 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7239 (plus:QI (match_dup 1) (match_dup 2)))]
7240 "ix86_match_ccmode (insn, CCGOCmode)
7241 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7243 switch (get_attr_type (insn))
7246 if (operands[2] == const1_rtx)
7247 return "inc{b}\t%0";
7250 gcc_assert (operands[2] == constm1_rtx
7251 || (CONST_INT_P (operands[2])
7252 && INTVAL (operands[2]) == 255));
7253 return "dec{b}\t%0";
7257 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7258 if (CONST_INT_P (operands[2])
7259 && INTVAL (operands[2]) < 0)
7261 operands[2] = GEN_INT (-INTVAL (operands[2]));
7262 return "sub{b}\t{%2, %0|%0, %2}";
7264 return "add{b}\t{%2, %0|%0, %2}";
7268 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7269 (const_string "incdec")
7270 (const_string "alu")))
7271 (set_attr "mode" "QI")])
7273 (define_insn "*addqi_3"
7274 [(set (reg FLAGS_REG)
7275 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7276 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7277 (clobber (match_scratch:QI 0 "=q"))]
7278 "ix86_match_ccmode (insn, CCZmode)
7279 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7281 switch (get_attr_type (insn))
7284 if (operands[2] == const1_rtx)
7285 return "inc{b}\t%0";
7288 gcc_assert (operands[2] == constm1_rtx
7289 || (CONST_INT_P (operands[2])
7290 && INTVAL (operands[2]) == 255));
7291 return "dec{b}\t%0";
7295 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7296 if (CONST_INT_P (operands[2])
7297 && INTVAL (operands[2]) < 0)
7299 operands[2] = GEN_INT (-INTVAL (operands[2]));
7300 return "sub{b}\t{%2, %0|%0, %2}";
7302 return "add{b}\t{%2, %0|%0, %2}";
7306 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7307 (const_string "incdec")
7308 (const_string "alu")))
7309 (set_attr "mode" "QI")])
7311 ; See comments above addsi_4 for details.
7312 (define_insn "*addqi_4"
7313 [(set (reg FLAGS_REG)
7314 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7315 (match_operand:QI 2 "const_int_operand" "n")))
7316 (clobber (match_scratch:QI 0 "=qm"))]
7317 "ix86_match_ccmode (insn, CCGCmode)
7318 && (INTVAL (operands[2]) & 0xff) != 0x80"
7320 switch (get_attr_type (insn))
7323 if (operands[2] == constm1_rtx
7324 || (CONST_INT_P (operands[2])
7325 && INTVAL (operands[2]) == 255))
7326 return "inc{b}\t%0";
7329 gcc_assert (operands[2] == const1_rtx);
7330 return "dec{b}\t%0";
7334 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7335 if (INTVAL (operands[2]) < 0)
7337 operands[2] = GEN_INT (-INTVAL (operands[2]));
7338 return "add{b}\t{%2, %0|%0, %2}";
7340 return "sub{b}\t{%2, %0|%0, %2}";
7344 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7345 (const_string "incdec")
7346 (const_string "alu")))
7347 (set_attr "mode" "QI")])
7350 (define_insn "*addqi_5"
7351 [(set (reg FLAGS_REG)
7353 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7354 (match_operand:QI 2 "general_operand" "qmn"))
7356 (clobber (match_scratch:QI 0 "=q"))]
7357 "ix86_match_ccmode (insn, CCGOCmode)
7358 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7360 switch (get_attr_type (insn))
7363 if (operands[2] == const1_rtx)
7364 return "inc{b}\t%0";
7367 gcc_assert (operands[2] == constm1_rtx
7368 || (CONST_INT_P (operands[2])
7369 && INTVAL (operands[2]) == 255));
7370 return "dec{b}\t%0";
7374 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7375 if (CONST_INT_P (operands[2])
7376 && INTVAL (operands[2]) < 0)
7378 operands[2] = GEN_INT (-INTVAL (operands[2]));
7379 return "sub{b}\t{%2, %0|%0, %2}";
7381 return "add{b}\t{%2, %0|%0, %2}";
7385 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7386 (const_string "incdec")
7387 (const_string "alu")))
7388 (set_attr "mode" "QI")])
7391 (define_insn "addqi_ext_1"
7392 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7397 (match_operand 1 "ext_register_operand" "0")
7400 (match_operand:QI 2 "general_operand" "Qmn")))
7401 (clobber (reg:CC FLAGS_REG))]
7404 switch (get_attr_type (insn))
7407 if (operands[2] == const1_rtx)
7408 return "inc{b}\t%h0";
7411 gcc_assert (operands[2] == constm1_rtx
7412 || (CONST_INT_P (operands[2])
7413 && INTVAL (operands[2]) == 255));
7414 return "dec{b}\t%h0";
7418 return "add{b}\t{%2, %h0|%h0, %2}";
7422 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7423 (const_string "incdec")
7424 (const_string "alu")))
7425 (set_attr "mode" "QI")])
7427 (define_insn "*addqi_ext_1_rex64"
7428 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7433 (match_operand 1 "ext_register_operand" "0")
7436 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7437 (clobber (reg:CC FLAGS_REG))]
7440 switch (get_attr_type (insn))
7443 if (operands[2] == const1_rtx)
7444 return "inc{b}\t%h0";
7447 gcc_assert (operands[2] == constm1_rtx
7448 || (CONST_INT_P (operands[2])
7449 && INTVAL (operands[2]) == 255));
7450 return "dec{b}\t%h0";
7454 return "add{b}\t{%2, %h0|%h0, %2}";
7458 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7459 (const_string "incdec")
7460 (const_string "alu")))
7461 (set_attr "mode" "QI")])
7463 (define_insn "*addqi_ext_2"
7464 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7469 (match_operand 1 "ext_register_operand" "%0")
7473 (match_operand 2 "ext_register_operand" "Q")
7476 (clobber (reg:CC FLAGS_REG))]
7478 "add{b}\t{%h2, %h0|%h0, %h2}"
7479 [(set_attr "type" "alu")
7480 (set_attr "mode" "QI")])
7482 ;; The patterns that match these are at the end of this file.
7484 (define_expand "addxf3"
7485 [(set (match_operand:XF 0 "register_operand" "")
7486 (plus:XF (match_operand:XF 1 "register_operand" "")
7487 (match_operand:XF 2 "register_operand" "")))]
7491 (define_expand "add<mode>3"
7492 [(set (match_operand:MODEF 0 "register_operand" "")
7493 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7494 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7495 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7498 ;; Subtract instructions
7500 ;; %%% splits for subditi3
7502 (define_expand "subti3"
7503 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7504 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7505 (match_operand:TI 2 "x86_64_general_operand" "")))]
7507 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7509 (define_insn "*subti3_1"
7510 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7511 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7512 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7513 (clobber (reg:CC FLAGS_REG))]
7514 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7518 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7519 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7520 (match_operand:TI 2 "x86_64_general_operand" "")))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "TARGET_64BIT && reload_completed"
7523 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7525 (parallel [(set (match_dup 3)
7526 (minus:DI (match_dup 4)
7527 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7529 (clobber (reg:CC FLAGS_REG))])]
7530 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7532 ;; %%% splits for subsidi3
7534 (define_expand "subdi3"
7535 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7536 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7537 (match_operand:DI 2 "x86_64_general_operand" "")))]
7539 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7541 (define_insn "*subdi3_1"
7542 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7543 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7544 (match_operand:DI 2 "general_operand" "roiF,riF")))
7545 (clobber (reg:CC FLAGS_REG))]
7546 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7550 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7551 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7552 (match_operand:DI 2 "general_operand" "")))
7553 (clobber (reg:CC FLAGS_REG))]
7554 "!TARGET_64BIT && reload_completed"
7555 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7556 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7557 (parallel [(set (match_dup 3)
7558 (minus:SI (match_dup 4)
7559 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7561 (clobber (reg:CC FLAGS_REG))])]
7562 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7564 (define_insn "subdi3_carry_rex64"
7565 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7566 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7567 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7568 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7569 (clobber (reg:CC FLAGS_REG))]
7570 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7571 "sbb{q}\t{%2, %0|%0, %2}"
7572 [(set_attr "type" "alu")
7573 (set_attr "pent_pair" "pu")
7574 (set_attr "mode" "DI")])
7576 (define_insn "*subdi_1_rex64"
7577 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7578 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7579 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7580 (clobber (reg:CC FLAGS_REG))]
7581 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7582 "sub{q}\t{%2, %0|%0, %2}"
7583 [(set_attr "type" "alu")
7584 (set_attr "mode" "DI")])
7586 (define_insn "*subdi_2_rex64"
7587 [(set (reg FLAGS_REG)
7589 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7590 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7592 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7593 (minus:DI (match_dup 1) (match_dup 2)))]
7594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7595 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7596 "sub{q}\t{%2, %0|%0, %2}"
7597 [(set_attr "type" "alu")
7598 (set_attr "mode" "DI")])
7600 (define_insn "*subdi_3_rex63"
7601 [(set (reg FLAGS_REG)
7602 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7603 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7604 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7605 (minus:DI (match_dup 1) (match_dup 2)))]
7606 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7607 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7608 "sub{q}\t{%2, %0|%0, %2}"
7609 [(set_attr "type" "alu")
7610 (set_attr "mode" "DI")])
7612 (define_insn "subqi3_carry"
7613 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7614 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7615 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7616 (match_operand:QI 2 "general_operand" "qn,qm"))))
7617 (clobber (reg:CC FLAGS_REG))]
7618 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7619 "sbb{b}\t{%2, %0|%0, %2}"
7620 [(set_attr "type" "alu")
7621 (set_attr "pent_pair" "pu")
7622 (set_attr "mode" "QI")])
7624 (define_insn "subhi3_carry"
7625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7626 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7627 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7628 (match_operand:HI 2 "general_operand" "rn,rm"))))
7629 (clobber (reg:CC FLAGS_REG))]
7630 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7631 "sbb{w}\t{%2, %0|%0, %2}"
7632 [(set_attr "type" "alu")
7633 (set_attr "pent_pair" "pu")
7634 (set_attr "mode" "HI")])
7636 (define_insn "subsi3_carry"
7637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7640 (match_operand:SI 2 "general_operand" "ri,rm"))))
7641 (clobber (reg:CC FLAGS_REG))]
7642 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7643 "sbb{l}\t{%2, %0|%0, %2}"
7644 [(set_attr "type" "alu")
7645 (set_attr "pent_pair" "pu")
7646 (set_attr "mode" "SI")])
7648 (define_insn "subsi3_carry_zext"
7649 [(set (match_operand:DI 0 "register_operand" "=r")
7651 (minus:SI (match_operand:SI 1 "register_operand" "0")
7652 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7653 (match_operand:SI 2 "general_operand" "g")))))
7654 (clobber (reg:CC FLAGS_REG))]
7655 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7656 "sbb{l}\t{%2, %k0|%k0, %2}"
7657 [(set_attr "type" "alu")
7658 (set_attr "pent_pair" "pu")
7659 (set_attr "mode" "SI")])
7661 (define_expand "subsi3"
7662 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7663 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7664 (match_operand:SI 2 "general_operand" "")))]
7666 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7668 (define_insn "*subsi_1"
7669 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7670 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7671 (match_operand:SI 2 "general_operand" "ri,rm")))
7672 (clobber (reg:CC FLAGS_REG))]
7673 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7674 "sub{l}\t{%2, %0|%0, %2}"
7675 [(set_attr "type" "alu")
7676 (set_attr "mode" "SI")])
7678 (define_insn "*subsi_1_zext"
7679 [(set (match_operand:DI 0 "register_operand" "=r")
7681 (minus:SI (match_operand:SI 1 "register_operand" "0")
7682 (match_operand:SI 2 "general_operand" "g"))))
7683 (clobber (reg:CC FLAGS_REG))]
7684 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7685 "sub{l}\t{%2, %k0|%k0, %2}"
7686 [(set_attr "type" "alu")
7687 (set_attr "mode" "SI")])
7689 (define_insn "*subsi_2"
7690 [(set (reg FLAGS_REG)
7692 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7693 (match_operand:SI 2 "general_operand" "ri,rm"))
7695 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7696 (minus:SI (match_dup 1) (match_dup 2)))]
7697 "ix86_match_ccmode (insn, CCGOCmode)
7698 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7699 "sub{l}\t{%2, %0|%0, %2}"
7700 [(set_attr "type" "alu")
7701 (set_attr "mode" "SI")])
7703 (define_insn "*subsi_2_zext"
7704 [(set (reg FLAGS_REG)
7706 (minus:SI (match_operand:SI 1 "register_operand" "0")
7707 (match_operand:SI 2 "general_operand" "g"))
7709 (set (match_operand:DI 0 "register_operand" "=r")
7711 (minus:SI (match_dup 1)
7713 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7714 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7715 "sub{l}\t{%2, %k0|%k0, %2}"
7716 [(set_attr "type" "alu")
7717 (set_attr "mode" "SI")])
7719 (define_insn "*subsi_3"
7720 [(set (reg FLAGS_REG)
7721 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7722 (match_operand:SI 2 "general_operand" "ri,rm")))
7723 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7724 (minus:SI (match_dup 1) (match_dup 2)))]
7725 "ix86_match_ccmode (insn, CCmode)
7726 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7727 "sub{l}\t{%2, %0|%0, %2}"
7728 [(set_attr "type" "alu")
7729 (set_attr "mode" "SI")])
7731 (define_insn "*subsi_3_zext"
7732 [(set (reg FLAGS_REG)
7733 (compare (match_operand:SI 1 "register_operand" "0")
7734 (match_operand:SI 2 "general_operand" "g")))
7735 (set (match_operand:DI 0 "register_operand" "=r")
7737 (minus:SI (match_dup 1)
7739 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7740 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7741 "sub{l}\t{%2, %1|%1, %2}"
7742 [(set_attr "type" "alu")
7743 (set_attr "mode" "DI")])
7745 (define_expand "subhi3"
7746 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7747 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7748 (match_operand:HI 2 "general_operand" "")))]
7749 "TARGET_HIMODE_MATH"
7750 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7752 (define_insn "*subhi_1"
7753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7754 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7755 (match_operand:HI 2 "general_operand" "rn,rm")))
7756 (clobber (reg:CC FLAGS_REG))]
7757 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7758 "sub{w}\t{%2, %0|%0, %2}"
7759 [(set_attr "type" "alu")
7760 (set_attr "mode" "HI")])
7762 (define_insn "*subhi_2"
7763 [(set (reg FLAGS_REG)
7765 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:HI 2 "general_operand" "rn,rm"))
7768 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7769 (minus:HI (match_dup 1) (match_dup 2)))]
7770 "ix86_match_ccmode (insn, CCGOCmode)
7771 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7772 "sub{w}\t{%2, %0|%0, %2}"
7773 [(set_attr "type" "alu")
7774 (set_attr "mode" "HI")])
7776 (define_insn "*subhi_3"
7777 [(set (reg FLAGS_REG)
7778 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7779 (match_operand:HI 2 "general_operand" "rn,rm")))
7780 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7781 (minus:HI (match_dup 1) (match_dup 2)))]
7782 "ix86_match_ccmode (insn, CCmode)
7783 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7784 "sub{w}\t{%2, %0|%0, %2}"
7785 [(set_attr "type" "alu")
7786 (set_attr "mode" "HI")])
7788 (define_expand "subqi3"
7789 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7790 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7791 (match_operand:QI 2 "general_operand" "")))]
7792 "TARGET_QIMODE_MATH"
7793 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7795 (define_insn "*subqi_1"
7796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7797 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7798 (match_operand:QI 2 "general_operand" "qn,qm")))
7799 (clobber (reg:CC FLAGS_REG))]
7800 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7801 "sub{b}\t{%2, %0|%0, %2}"
7802 [(set_attr "type" "alu")
7803 (set_attr "mode" "QI")])
7805 (define_insn "*subqi_1_slp"
7806 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7807 (minus:QI (match_dup 0)
7808 (match_operand:QI 1 "general_operand" "qn,qm")))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7812 "sub{b}\t{%1, %0|%0, %1}"
7813 [(set_attr "type" "alu1")
7814 (set_attr "mode" "QI")])
7816 (define_insn "*subqi_2"
7817 [(set (reg FLAGS_REG)
7819 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7820 (match_operand:QI 2 "general_operand" "qn,qm"))
7822 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7823 (minus:QI (match_dup 1) (match_dup 2)))]
7824 "ix86_match_ccmode (insn, CCGOCmode)
7825 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7826 "sub{b}\t{%2, %0|%0, %2}"
7827 [(set_attr "type" "alu")
7828 (set_attr "mode" "QI")])
7830 (define_insn "*subqi_3"
7831 [(set (reg FLAGS_REG)
7832 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7833 (match_operand:QI 2 "general_operand" "qn,qm")))
7834 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7835 (minus:QI (match_dup 1) (match_dup 2)))]
7836 "ix86_match_ccmode (insn, CCmode)
7837 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7838 "sub{b}\t{%2, %0|%0, %2}"
7839 [(set_attr "type" "alu")
7840 (set_attr "mode" "QI")])
7842 ;; The patterns that match these are at the end of this file.
7844 (define_expand "subxf3"
7845 [(set (match_operand:XF 0 "register_operand" "")
7846 (minus:XF (match_operand:XF 1 "register_operand" "")
7847 (match_operand:XF 2 "register_operand" "")))]
7851 (define_expand "sub<mode>3"
7852 [(set (match_operand:MODEF 0 "register_operand" "")
7853 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7854 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7855 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7858 ;; Multiply instructions
7860 (define_expand "muldi3"
7861 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7862 (mult:DI (match_operand:DI 1 "register_operand" "")
7863 (match_operand:DI 2 "x86_64_general_operand" "")))
7864 (clobber (reg:CC FLAGS_REG))])]
7869 ;; IMUL reg64, reg64, imm8 Direct
7870 ;; IMUL reg64, mem64, imm8 VectorPath
7871 ;; IMUL reg64, reg64, imm32 Direct
7872 ;; IMUL reg64, mem64, imm32 VectorPath
7873 ;; IMUL reg64, reg64 Direct
7874 ;; IMUL reg64, mem64 Direct
7876 (define_insn "*muldi3_1_rex64"
7877 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7878 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7879 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7880 (clobber (reg:CC FLAGS_REG))]
7882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7884 imul{q}\t{%2, %1, %0|%0, %1, %2}
7885 imul{q}\t{%2, %1, %0|%0, %1, %2}
7886 imul{q}\t{%2, %0|%0, %2}"
7887 [(set_attr "type" "imul")
7888 (set_attr "prefix_0f" "0,0,1")
7889 (set (attr "athlon_decode")
7890 (cond [(eq_attr "cpu" "athlon")
7891 (const_string "vector")
7892 (eq_attr "alternative" "1")
7893 (const_string "vector")
7894 (and (eq_attr "alternative" "2")
7895 (match_operand 1 "memory_operand" ""))
7896 (const_string "vector")]
7897 (const_string "direct")))
7898 (set (attr "amdfam10_decode")
7899 (cond [(and (eq_attr "alternative" "0,1")
7900 (match_operand 1 "memory_operand" ""))
7901 (const_string "vector")]
7902 (const_string "direct")))
7903 (set_attr "mode" "DI")])
7905 (define_expand "mulsi3"
7906 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7907 (mult:SI (match_operand:SI 1 "register_operand" "")
7908 (match_operand:SI 2 "general_operand" "")))
7909 (clobber (reg:CC FLAGS_REG))])]
7914 ;; IMUL reg32, reg32, imm8 Direct
7915 ;; IMUL reg32, mem32, imm8 VectorPath
7916 ;; IMUL reg32, reg32, imm32 Direct
7917 ;; IMUL reg32, mem32, imm32 VectorPath
7918 ;; IMUL reg32, reg32 Direct
7919 ;; IMUL reg32, mem32 Direct
7921 (define_insn "*mulsi3_1"
7922 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7923 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7924 (match_operand:SI 2 "general_operand" "K,i,mr")))
7925 (clobber (reg:CC FLAGS_REG))]
7926 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7928 imul{l}\t{%2, %1, %0|%0, %1, %2}
7929 imul{l}\t{%2, %1, %0|%0, %1, %2}
7930 imul{l}\t{%2, %0|%0, %2}"
7931 [(set_attr "type" "imul")
7932 (set_attr "prefix_0f" "0,0,1")
7933 (set (attr "athlon_decode")
7934 (cond [(eq_attr "cpu" "athlon")
7935 (const_string "vector")
7936 (eq_attr "alternative" "1")
7937 (const_string "vector")
7938 (and (eq_attr "alternative" "2")
7939 (match_operand 1 "memory_operand" ""))
7940 (const_string "vector")]
7941 (const_string "direct")))
7942 (set (attr "amdfam10_decode")
7943 (cond [(and (eq_attr "alternative" "0,1")
7944 (match_operand 1 "memory_operand" ""))
7945 (const_string "vector")]
7946 (const_string "direct")))
7947 (set_attr "mode" "SI")])
7949 (define_insn "*mulsi3_1_zext"
7950 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7953 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7954 (clobber (reg:CC FLAGS_REG))]
7956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7958 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7959 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7960 imul{l}\t{%2, %k0|%k0, %2}"
7961 [(set_attr "type" "imul")
7962 (set_attr "prefix_0f" "0,0,1")
7963 (set (attr "athlon_decode")
7964 (cond [(eq_attr "cpu" "athlon")
7965 (const_string "vector")
7966 (eq_attr "alternative" "1")
7967 (const_string "vector")
7968 (and (eq_attr "alternative" "2")
7969 (match_operand 1 "memory_operand" ""))
7970 (const_string "vector")]
7971 (const_string "direct")))
7972 (set (attr "amdfam10_decode")
7973 (cond [(and (eq_attr "alternative" "0,1")
7974 (match_operand 1 "memory_operand" ""))
7975 (const_string "vector")]
7976 (const_string "direct")))
7977 (set_attr "mode" "SI")])
7979 (define_expand "mulhi3"
7980 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7981 (mult:HI (match_operand:HI 1 "register_operand" "")
7982 (match_operand:HI 2 "general_operand" "")))
7983 (clobber (reg:CC FLAGS_REG))])]
7984 "TARGET_HIMODE_MATH"
7988 ;; IMUL reg16, reg16, imm8 VectorPath
7989 ;; IMUL reg16, mem16, imm8 VectorPath
7990 ;; IMUL reg16, reg16, imm16 VectorPath
7991 ;; IMUL reg16, mem16, imm16 VectorPath
7992 ;; IMUL reg16, reg16 Direct
7993 ;; IMUL reg16, mem16 Direct
7994 (define_insn "*mulhi3_1"
7995 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7996 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7997 (match_operand:HI 2 "general_operand" "K,n,mr")))
7998 (clobber (reg:CC FLAGS_REG))]
7999 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8001 imul{w}\t{%2, %1, %0|%0, %1, %2}
8002 imul{w}\t{%2, %1, %0|%0, %1, %2}
8003 imul{w}\t{%2, %0|%0, %2}"
8004 [(set_attr "type" "imul")
8005 (set_attr "prefix_0f" "0,0,1")
8006 (set (attr "athlon_decode")
8007 (cond [(eq_attr "cpu" "athlon")
8008 (const_string "vector")
8009 (eq_attr "alternative" "1,2")
8010 (const_string "vector")]
8011 (const_string "direct")))
8012 (set (attr "amdfam10_decode")
8013 (cond [(eq_attr "alternative" "0,1")
8014 (const_string "vector")]
8015 (const_string "direct")))
8016 (set_attr "mode" "HI")])
8018 (define_expand "mulqi3"
8019 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8020 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8021 (match_operand:QI 2 "register_operand" "")))
8022 (clobber (reg:CC FLAGS_REG))])]
8023 "TARGET_QIMODE_MATH"
8030 (define_insn "*mulqi3_1"
8031 [(set (match_operand:QI 0 "register_operand" "=a")
8032 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8033 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8034 (clobber (reg:CC FLAGS_REG))]
8036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8038 [(set_attr "type" "imul")
8039 (set_attr "length_immediate" "0")
8040 (set (attr "athlon_decode")
8041 (if_then_else (eq_attr "cpu" "athlon")
8042 (const_string "vector")
8043 (const_string "direct")))
8044 (set_attr "amdfam10_decode" "direct")
8045 (set_attr "mode" "QI")])
8047 (define_expand "umulqihi3"
8048 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8049 (mult:HI (zero_extend:HI
8050 (match_operand:QI 1 "nonimmediate_operand" ""))
8052 (match_operand:QI 2 "register_operand" ""))))
8053 (clobber (reg:CC FLAGS_REG))])]
8054 "TARGET_QIMODE_MATH"
8057 (define_insn "*umulqihi3_1"
8058 [(set (match_operand:HI 0 "register_operand" "=a")
8059 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8060 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8061 (clobber (reg:CC FLAGS_REG))]
8063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8065 [(set_attr "type" "imul")
8066 (set_attr "length_immediate" "0")
8067 (set (attr "athlon_decode")
8068 (if_then_else (eq_attr "cpu" "athlon")
8069 (const_string "vector")
8070 (const_string "direct")))
8071 (set_attr "amdfam10_decode" "direct")
8072 (set_attr "mode" "QI")])
8074 (define_expand "mulqihi3"
8075 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8076 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8077 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8078 (clobber (reg:CC FLAGS_REG))])]
8079 "TARGET_QIMODE_MATH"
8082 (define_insn "*mulqihi3_insn"
8083 [(set (match_operand:HI 0 "register_operand" "=a")
8084 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8085 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8086 (clobber (reg:CC FLAGS_REG))]
8088 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8090 [(set_attr "type" "imul")
8091 (set_attr "length_immediate" "0")
8092 (set (attr "athlon_decode")
8093 (if_then_else (eq_attr "cpu" "athlon")
8094 (const_string "vector")
8095 (const_string "direct")))
8096 (set_attr "amdfam10_decode" "direct")
8097 (set_attr "mode" "QI")])
8099 (define_expand "umulditi3"
8100 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8101 (mult:TI (zero_extend:TI
8102 (match_operand:DI 1 "nonimmediate_operand" ""))
8104 (match_operand:DI 2 "register_operand" ""))))
8105 (clobber (reg:CC FLAGS_REG))])]
8109 (define_insn "*umulditi3_insn"
8110 [(set (match_operand:TI 0 "register_operand" "=A")
8111 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8112 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8113 (clobber (reg:CC FLAGS_REG))]
8115 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8117 [(set_attr "type" "imul")
8118 (set_attr "length_immediate" "0")
8119 (set (attr "athlon_decode")
8120 (if_then_else (eq_attr "cpu" "athlon")
8121 (const_string "vector")
8122 (const_string "double")))
8123 (set_attr "amdfam10_decode" "double")
8124 (set_attr "mode" "DI")])
8126 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8127 (define_expand "umulsidi3"
8128 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8129 (mult:DI (zero_extend:DI
8130 (match_operand:SI 1 "nonimmediate_operand" ""))
8132 (match_operand:SI 2 "register_operand" ""))))
8133 (clobber (reg:CC FLAGS_REG))])]
8137 (define_insn "*umulsidi3_insn"
8138 [(set (match_operand:DI 0 "register_operand" "=A")
8139 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8140 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8141 (clobber (reg:CC FLAGS_REG))]
8143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8145 [(set_attr "type" "imul")
8146 (set_attr "length_immediate" "0")
8147 (set (attr "athlon_decode")
8148 (if_then_else (eq_attr "cpu" "athlon")
8149 (const_string "vector")
8150 (const_string "double")))
8151 (set_attr "amdfam10_decode" "double")
8152 (set_attr "mode" "SI")])
8154 (define_expand "mulditi3"
8155 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8156 (mult:TI (sign_extend:TI
8157 (match_operand:DI 1 "nonimmediate_operand" ""))
8159 (match_operand:DI 2 "register_operand" ""))))
8160 (clobber (reg:CC FLAGS_REG))])]
8164 (define_insn "*mulditi3_insn"
8165 [(set (match_operand:TI 0 "register_operand" "=A")
8166 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8167 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8168 (clobber (reg:CC FLAGS_REG))]
8170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8172 [(set_attr "type" "imul")
8173 (set_attr "length_immediate" "0")
8174 (set (attr "athlon_decode")
8175 (if_then_else (eq_attr "cpu" "athlon")
8176 (const_string "vector")
8177 (const_string "double")))
8178 (set_attr "amdfam10_decode" "double")
8179 (set_attr "mode" "DI")])
8181 (define_expand "mulsidi3"
8182 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8183 (mult:DI (sign_extend:DI
8184 (match_operand:SI 1 "nonimmediate_operand" ""))
8186 (match_operand:SI 2 "register_operand" ""))))
8187 (clobber (reg:CC FLAGS_REG))])]
8191 (define_insn "*mulsidi3_insn"
8192 [(set (match_operand:DI 0 "register_operand" "=A")
8193 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8194 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8197 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8199 [(set_attr "type" "imul")
8200 (set_attr "length_immediate" "0")
8201 (set (attr "athlon_decode")
8202 (if_then_else (eq_attr "cpu" "athlon")
8203 (const_string "vector")
8204 (const_string "double")))
8205 (set_attr "amdfam10_decode" "double")
8206 (set_attr "mode" "SI")])
8208 (define_expand "umuldi3_highpart"
8209 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8212 (mult:TI (zero_extend:TI
8213 (match_operand:DI 1 "nonimmediate_operand" ""))
8215 (match_operand:DI 2 "register_operand" "")))
8217 (clobber (match_scratch:DI 3 ""))
8218 (clobber (reg:CC FLAGS_REG))])]
8222 (define_insn "*umuldi3_highpart_rex64"
8223 [(set (match_operand:DI 0 "register_operand" "=d")
8226 (mult:TI (zero_extend:TI
8227 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8229 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8231 (clobber (match_scratch:DI 3 "=1"))
8232 (clobber (reg:CC FLAGS_REG))]
8234 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8236 [(set_attr "type" "imul")
8237 (set_attr "length_immediate" "0")
8238 (set (attr "athlon_decode")
8239 (if_then_else (eq_attr "cpu" "athlon")
8240 (const_string "vector")
8241 (const_string "double")))
8242 (set_attr "amdfam10_decode" "double")
8243 (set_attr "mode" "DI")])
8245 (define_expand "umulsi3_highpart"
8246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8249 (mult:DI (zero_extend:DI
8250 (match_operand:SI 1 "nonimmediate_operand" ""))
8252 (match_operand:SI 2 "register_operand" "")))
8254 (clobber (match_scratch:SI 3 ""))
8255 (clobber (reg:CC FLAGS_REG))])]
8259 (define_insn "*umulsi3_highpart_insn"
8260 [(set (match_operand:SI 0 "register_operand" "=d")
8263 (mult:DI (zero_extend:DI
8264 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8266 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8268 (clobber (match_scratch:SI 3 "=1"))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8272 [(set_attr "type" "imul")
8273 (set_attr "length_immediate" "0")
8274 (set (attr "athlon_decode")
8275 (if_then_else (eq_attr "cpu" "athlon")
8276 (const_string "vector")
8277 (const_string "double")))
8278 (set_attr "amdfam10_decode" "double")
8279 (set_attr "mode" "SI")])
8281 (define_insn "*umulsi3_highpart_zext"
8282 [(set (match_operand:DI 0 "register_operand" "=d")
8283 (zero_extend:DI (truncate:SI
8285 (mult:DI (zero_extend:DI
8286 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8288 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8290 (clobber (match_scratch:SI 3 "=1"))
8291 (clobber (reg:CC FLAGS_REG))]
8293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8295 [(set_attr "type" "imul")
8296 (set_attr "length_immediate" "0")
8297 (set (attr "athlon_decode")
8298 (if_then_else (eq_attr "cpu" "athlon")
8299 (const_string "vector")
8300 (const_string "double")))
8301 (set_attr "amdfam10_decode" "double")
8302 (set_attr "mode" "SI")])
8304 (define_expand "smuldi3_highpart"
8305 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8308 (mult:TI (sign_extend:TI
8309 (match_operand:DI 1 "nonimmediate_operand" ""))
8311 (match_operand:DI 2 "register_operand" "")))
8313 (clobber (match_scratch:DI 3 ""))
8314 (clobber (reg:CC FLAGS_REG))])]
8318 (define_insn "*smuldi3_highpart_rex64"
8319 [(set (match_operand:DI 0 "register_operand" "=d")
8322 (mult:TI (sign_extend:TI
8323 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8325 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8327 (clobber (match_scratch:DI 3 "=1"))
8328 (clobber (reg:CC FLAGS_REG))]
8330 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8332 [(set_attr "type" "imul")
8333 (set (attr "athlon_decode")
8334 (if_then_else (eq_attr "cpu" "athlon")
8335 (const_string "vector")
8336 (const_string "double")))
8337 (set_attr "amdfam10_decode" "double")
8338 (set_attr "mode" "DI")])
8340 (define_expand "smulsi3_highpart"
8341 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8344 (mult:DI (sign_extend:DI
8345 (match_operand:SI 1 "nonimmediate_operand" ""))
8347 (match_operand:SI 2 "register_operand" "")))
8349 (clobber (match_scratch:SI 3 ""))
8350 (clobber (reg:CC FLAGS_REG))])]
8354 (define_insn "*smulsi3_highpart_insn"
8355 [(set (match_operand:SI 0 "register_operand" "=d")
8358 (mult:DI (sign_extend:DI
8359 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8361 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8363 (clobber (match_scratch:SI 3 "=1"))
8364 (clobber (reg:CC FLAGS_REG))]
8365 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8367 [(set_attr "type" "imul")
8368 (set (attr "athlon_decode")
8369 (if_then_else (eq_attr "cpu" "athlon")
8370 (const_string "vector")
8371 (const_string "double")))
8372 (set_attr "amdfam10_decode" "double")
8373 (set_attr "mode" "SI")])
8375 (define_insn "*smulsi3_highpart_zext"
8376 [(set (match_operand:DI 0 "register_operand" "=d")
8377 (zero_extend:DI (truncate:SI
8379 (mult:DI (sign_extend:DI
8380 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8382 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8384 (clobber (match_scratch:SI 3 "=1"))
8385 (clobber (reg:CC FLAGS_REG))]
8387 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8389 [(set_attr "type" "imul")
8390 (set (attr "athlon_decode")
8391 (if_then_else (eq_attr "cpu" "athlon")
8392 (const_string "vector")
8393 (const_string "double")))
8394 (set_attr "amdfam10_decode" "double")
8395 (set_attr "mode" "SI")])
8397 ;; The patterns that match these are at the end of this file.
8399 (define_expand "mulxf3"
8400 [(set (match_operand:XF 0 "register_operand" "")
8401 (mult:XF (match_operand:XF 1 "register_operand" "")
8402 (match_operand:XF 2 "register_operand" "")))]
8406 (define_expand "mul<mode>3"
8407 [(set (match_operand:MODEF 0 "register_operand" "")
8408 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8409 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8410 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8413 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8416 ;; Divide instructions
8418 (define_insn "divqi3"
8419 [(set (match_operand:QI 0 "register_operand" "=a")
8420 (div:QI (match_operand:HI 1 "register_operand" "0")
8421 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "TARGET_QIMODE_MATH"
8425 [(set_attr "type" "idiv")
8426 (set_attr "mode" "QI")])
8428 (define_insn "udivqi3"
8429 [(set (match_operand:QI 0 "register_operand" "=a")
8430 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8431 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "TARGET_QIMODE_MATH"
8435 [(set_attr "type" "idiv")
8436 (set_attr "mode" "QI")])
8438 ;; The patterns that match these are at the end of this file.
8440 (define_expand "divxf3"
8441 [(set (match_operand:XF 0 "register_operand" "")
8442 (div:XF (match_operand:XF 1 "register_operand" "")
8443 (match_operand:XF 2 "register_operand" "")))]
8447 (define_expand "divdf3"
8448 [(set (match_operand:DF 0 "register_operand" "")
8449 (div:DF (match_operand:DF 1 "register_operand" "")
8450 (match_operand:DF 2 "nonimmediate_operand" "")))]
8451 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8454 (define_expand "divsf3"
8455 [(set (match_operand:SF 0 "register_operand" "")
8456 (div:SF (match_operand:SF 1 "register_operand" "")
8457 (match_operand:SF 2 "nonimmediate_operand" "")))]
8458 "TARGET_80387 || TARGET_SSE_MATH"
8460 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8461 && flag_finite_math_only && !flag_trapping_math
8462 && flag_unsafe_math_optimizations)
8464 ix86_emit_swdivsf (operands[0], operands[1],
8465 operands[2], SFmode);
8470 ;; Remainder instructions.
8472 (define_expand "divmoddi4"
8473 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8474 (div:DI (match_operand:DI 1 "register_operand" "")
8475 (match_operand:DI 2 "nonimmediate_operand" "")))
8476 (set (match_operand:DI 3 "register_operand" "")
8477 (mod:DI (match_dup 1) (match_dup 2)))
8478 (clobber (reg:CC FLAGS_REG))])]
8482 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8483 ;; Penalize eax case slightly because it results in worse scheduling
8485 (define_insn "*divmoddi4_nocltd_rex64"
8486 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8487 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8488 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8489 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8490 (mod:DI (match_dup 2) (match_dup 3)))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8494 [(set_attr "type" "multi")])
8496 (define_insn "*divmoddi4_cltd_rex64"
8497 [(set (match_operand:DI 0 "register_operand" "=a")
8498 (div:DI (match_operand:DI 2 "register_operand" "a")
8499 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8500 (set (match_operand:DI 1 "register_operand" "=&d")
8501 (mod:DI (match_dup 2) (match_dup 3)))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8505 [(set_attr "type" "multi")])
8507 (define_insn "*divmoddi_noext_rex64"
8508 [(set (match_operand:DI 0 "register_operand" "=a")
8509 (div:DI (match_operand:DI 1 "register_operand" "0")
8510 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8511 (set (match_operand:DI 3 "register_operand" "=d")
8512 (mod:DI (match_dup 1) (match_dup 2)))
8513 (use (match_operand:DI 4 "register_operand" "3"))
8514 (clobber (reg:CC FLAGS_REG))]
8517 [(set_attr "type" "idiv")
8518 (set_attr "mode" "DI")])
8521 [(set (match_operand:DI 0 "register_operand" "")
8522 (div:DI (match_operand:DI 1 "register_operand" "")
8523 (match_operand:DI 2 "nonimmediate_operand" "")))
8524 (set (match_operand:DI 3 "register_operand" "")
8525 (mod:DI (match_dup 1) (match_dup 2)))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "TARGET_64BIT && reload_completed"
8528 [(parallel [(set (match_dup 3)
8529 (ashiftrt:DI (match_dup 4) (const_int 63)))
8530 (clobber (reg:CC FLAGS_REG))])
8531 (parallel [(set (match_dup 0)
8532 (div:DI (reg:DI 0) (match_dup 2)))
8534 (mod:DI (reg:DI 0) (match_dup 2)))
8536 (clobber (reg:CC FLAGS_REG))])]
8538 /* Avoid use of cltd in favor of a mov+shift. */
8539 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8541 if (true_regnum (operands[1]))
8542 emit_move_insn (operands[0], operands[1]);
8544 emit_move_insn (operands[3], operands[1]);
8545 operands[4] = operands[3];
8549 gcc_assert (!true_regnum (operands[1]));
8550 operands[4] = operands[1];
8555 (define_expand "divmodsi4"
8556 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8557 (div:SI (match_operand:SI 1 "register_operand" "")
8558 (match_operand:SI 2 "nonimmediate_operand" "")))
8559 (set (match_operand:SI 3 "register_operand" "")
8560 (mod:SI (match_dup 1) (match_dup 2)))
8561 (clobber (reg:CC FLAGS_REG))])]
8565 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8566 ;; Penalize eax case slightly because it results in worse scheduling
8568 (define_insn "*divmodsi4_nocltd"
8569 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8570 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8571 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8572 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8573 (mod:SI (match_dup 2) (match_dup 3)))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8577 [(set_attr "type" "multi")])
8579 (define_insn "*divmodsi4_cltd"
8580 [(set (match_operand:SI 0 "register_operand" "=a")
8581 (div:SI (match_operand:SI 2 "register_operand" "a")
8582 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8583 (set (match_operand:SI 1 "register_operand" "=&d")
8584 (mod:SI (match_dup 2) (match_dup 3)))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8588 [(set_attr "type" "multi")])
8590 (define_insn "*divmodsi_noext"
8591 [(set (match_operand:SI 0 "register_operand" "=a")
8592 (div:SI (match_operand:SI 1 "register_operand" "0")
8593 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8594 (set (match_operand:SI 3 "register_operand" "=d")
8595 (mod:SI (match_dup 1) (match_dup 2)))
8596 (use (match_operand:SI 4 "register_operand" "3"))
8597 (clobber (reg:CC FLAGS_REG))]
8600 [(set_attr "type" "idiv")
8601 (set_attr "mode" "SI")])
8604 [(set (match_operand:SI 0 "register_operand" "")
8605 (div:SI (match_operand:SI 1 "register_operand" "")
8606 (match_operand:SI 2 "nonimmediate_operand" "")))
8607 (set (match_operand:SI 3 "register_operand" "")
8608 (mod:SI (match_dup 1) (match_dup 2)))
8609 (clobber (reg:CC FLAGS_REG))]
8611 [(parallel [(set (match_dup 3)
8612 (ashiftrt:SI (match_dup 4) (const_int 31)))
8613 (clobber (reg:CC FLAGS_REG))])
8614 (parallel [(set (match_dup 0)
8615 (div:SI (reg:SI 0) (match_dup 2)))
8617 (mod:SI (reg:SI 0) (match_dup 2)))
8619 (clobber (reg:CC FLAGS_REG))])]
8621 /* Avoid use of cltd in favor of a mov+shift. */
8622 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8624 if (true_regnum (operands[1]))
8625 emit_move_insn (operands[0], operands[1]);
8627 emit_move_insn (operands[3], operands[1]);
8628 operands[4] = operands[3];
8632 gcc_assert (!true_regnum (operands[1]));
8633 operands[4] = operands[1];
8637 (define_insn "divmodhi4"
8638 [(set (match_operand:HI 0 "register_operand" "=a")
8639 (div:HI (match_operand:HI 1 "register_operand" "0")
8640 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8641 (set (match_operand:HI 3 "register_operand" "=&d")
8642 (mod:HI (match_dup 1) (match_dup 2)))
8643 (clobber (reg:CC FLAGS_REG))]
8644 "TARGET_HIMODE_MATH"
8646 [(set_attr "type" "multi")
8647 (set_attr "length_immediate" "0")
8648 (set_attr "mode" "SI")])
8650 (define_insn "udivmoddi4"
8651 [(set (match_operand:DI 0 "register_operand" "=a")
8652 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8653 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8654 (set (match_operand:DI 3 "register_operand" "=&d")
8655 (umod:DI (match_dup 1) (match_dup 2)))
8656 (clobber (reg:CC FLAGS_REG))]
8658 "xor{q}\t%3, %3\;div{q}\t%2"
8659 [(set_attr "type" "multi")
8660 (set_attr "length_immediate" "0")
8661 (set_attr "mode" "DI")])
8663 (define_insn "*udivmoddi4_noext"
8664 [(set (match_operand:DI 0 "register_operand" "=a")
8665 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8666 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8667 (set (match_operand:DI 3 "register_operand" "=d")
8668 (umod:DI (match_dup 1) (match_dup 2)))
8670 (clobber (reg:CC FLAGS_REG))]
8673 [(set_attr "type" "idiv")
8674 (set_attr "mode" "DI")])
8677 [(set (match_operand:DI 0 "register_operand" "")
8678 (udiv:DI (match_operand:DI 1 "register_operand" "")
8679 (match_operand:DI 2 "nonimmediate_operand" "")))
8680 (set (match_operand:DI 3 "register_operand" "")
8681 (umod:DI (match_dup 1) (match_dup 2)))
8682 (clobber (reg:CC FLAGS_REG))]
8683 "TARGET_64BIT && reload_completed"
8684 [(set (match_dup 3) (const_int 0))
8685 (parallel [(set (match_dup 0)
8686 (udiv:DI (match_dup 1) (match_dup 2)))
8688 (umod:DI (match_dup 1) (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8693 (define_insn "udivmodsi4"
8694 [(set (match_operand:SI 0 "register_operand" "=a")
8695 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8696 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8697 (set (match_operand:SI 3 "register_operand" "=&d")
8698 (umod:SI (match_dup 1) (match_dup 2)))
8699 (clobber (reg:CC FLAGS_REG))]
8701 "xor{l}\t%3, %3\;div{l}\t%2"
8702 [(set_attr "type" "multi")
8703 (set_attr "length_immediate" "0")
8704 (set_attr "mode" "SI")])
8706 (define_insn "*udivmodsi4_noext"
8707 [(set (match_operand:SI 0 "register_operand" "=a")
8708 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8709 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8710 (set (match_operand:SI 3 "register_operand" "=d")
8711 (umod:SI (match_dup 1) (match_dup 2)))
8713 (clobber (reg:CC FLAGS_REG))]
8716 [(set_attr "type" "idiv")
8717 (set_attr "mode" "SI")])
8720 [(set (match_operand:SI 0 "register_operand" "")
8721 (udiv:SI (match_operand:SI 1 "register_operand" "")
8722 (match_operand:SI 2 "nonimmediate_operand" "")))
8723 (set (match_operand:SI 3 "register_operand" "")
8724 (umod:SI (match_dup 1) (match_dup 2)))
8725 (clobber (reg:CC FLAGS_REG))]
8727 [(set (match_dup 3) (const_int 0))
8728 (parallel [(set (match_dup 0)
8729 (udiv:SI (match_dup 1) (match_dup 2)))
8731 (umod:SI (match_dup 1) (match_dup 2)))
8733 (clobber (reg:CC FLAGS_REG))])]
8736 (define_expand "udivmodhi4"
8737 [(set (match_dup 4) (const_int 0))
8738 (parallel [(set (match_operand:HI 0 "register_operand" "")
8739 (udiv:HI (match_operand:HI 1 "register_operand" "")
8740 (match_operand:HI 2 "nonimmediate_operand" "")))
8741 (set (match_operand:HI 3 "register_operand" "")
8742 (umod:HI (match_dup 1) (match_dup 2)))
8744 (clobber (reg:CC FLAGS_REG))])]
8745 "TARGET_HIMODE_MATH"
8746 "operands[4] = gen_reg_rtx (HImode);")
8748 (define_insn "*udivmodhi_noext"
8749 [(set (match_operand:HI 0 "register_operand" "=a")
8750 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8751 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8752 (set (match_operand:HI 3 "register_operand" "=d")
8753 (umod:HI (match_dup 1) (match_dup 2)))
8754 (use (match_operand:HI 4 "register_operand" "3"))
8755 (clobber (reg:CC FLAGS_REG))]
8758 [(set_attr "type" "idiv")
8759 (set_attr "mode" "HI")])
8761 ;; We cannot use div/idiv for double division, because it causes
8762 ;; "division by zero" on the overflow and that's not what we expect
8763 ;; from truncate. Because true (non truncating) double division is
8764 ;; never generated, we can't create this insn anyway.
8767 ; [(set (match_operand:SI 0 "register_operand" "=a")
8769 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8771 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8772 ; (set (match_operand:SI 3 "register_operand" "=d")
8774 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8775 ; (clobber (reg:CC FLAGS_REG))]
8777 ; "div{l}\t{%2, %0|%0, %2}"
8778 ; [(set_attr "type" "idiv")])
8780 ;;- Logical AND instructions
8782 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8783 ;; Note that this excludes ah.
8785 (define_insn "*testdi_1_rex64"
8786 [(set (reg FLAGS_REG)
8788 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8789 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8791 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8792 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8794 test{l}\t{%k1, %k0|%k0, %k1}
8795 test{l}\t{%k1, %k0|%k0, %k1}
8796 test{q}\t{%1, %0|%0, %1}
8797 test{q}\t{%1, %0|%0, %1}
8798 test{q}\t{%1, %0|%0, %1}"
8799 [(set_attr "type" "test")
8800 (set_attr "modrm" "0,1,0,1,1")
8801 (set_attr "mode" "SI,SI,DI,DI,DI")
8802 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8804 (define_insn "testsi_1"
8805 [(set (reg FLAGS_REG)
8807 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8808 (match_operand:SI 1 "general_operand" "i,i,ri"))
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8812 "test{l}\t{%1, %0|%0, %1}"
8813 [(set_attr "type" "test")
8814 (set_attr "modrm" "0,1,1")
8815 (set_attr "mode" "SI")
8816 (set_attr "pent_pair" "uv,np,uv")])
8818 (define_expand "testsi_ccno_1"
8819 [(set (reg:CCNO FLAGS_REG)
8821 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8822 (match_operand:SI 1 "nonmemory_operand" ""))
8827 (define_insn "*testhi_1"
8828 [(set (reg FLAGS_REG)
8829 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8830 (match_operand:HI 1 "general_operand" "n,n,rn"))
8832 "ix86_match_ccmode (insn, CCNOmode)
8833 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8834 "test{w}\t{%1, %0|%0, %1}"
8835 [(set_attr "type" "test")
8836 (set_attr "modrm" "0,1,1")
8837 (set_attr "mode" "HI")
8838 (set_attr "pent_pair" "uv,np,uv")])
8840 (define_expand "testqi_ccz_1"
8841 [(set (reg:CCZ FLAGS_REG)
8842 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8843 (match_operand:QI 1 "nonmemory_operand" ""))
8848 (define_insn "*testqi_1_maybe_si"
8849 [(set (reg FLAGS_REG)
8852 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8853 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8855 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8856 && ix86_match_ccmode (insn,
8857 CONST_INT_P (operands[1])
8858 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8860 if (which_alternative == 3)
8862 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8863 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8864 return "test{l}\t{%1, %k0|%k0, %1}";
8866 return "test{b}\t{%1, %0|%0, %1}";
8868 [(set_attr "type" "test")
8869 (set_attr "modrm" "0,1,1,1")
8870 (set_attr "mode" "QI,QI,QI,SI")
8871 (set_attr "pent_pair" "uv,np,uv,np")])
8873 (define_insn "*testqi_1"
8874 [(set (reg FLAGS_REG)
8877 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8878 (match_operand:QI 1 "general_operand" "n,n,qn"))
8880 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8881 && ix86_match_ccmode (insn, CCNOmode)"
8882 "test{b}\t{%1, %0|%0, %1}"
8883 [(set_attr "type" "test")
8884 (set_attr "modrm" "0,1,1")
8885 (set_attr "mode" "QI")
8886 (set_attr "pent_pair" "uv,np,uv")])
8888 (define_expand "testqi_ext_ccno_0"
8889 [(set (reg:CCNO FLAGS_REG)
8893 (match_operand 0 "ext_register_operand" "")
8896 (match_operand 1 "const_int_operand" ""))
8901 (define_insn "*testqi_ext_0"
8902 [(set (reg FLAGS_REG)
8906 (match_operand 0 "ext_register_operand" "Q")
8909 (match_operand 1 "const_int_operand" "n"))
8911 "ix86_match_ccmode (insn, CCNOmode)"
8912 "test{b}\t{%1, %h0|%h0, %1}"
8913 [(set_attr "type" "test")
8914 (set_attr "mode" "QI")
8915 (set_attr "length_immediate" "1")
8916 (set_attr "pent_pair" "np")])
8918 (define_insn "*testqi_ext_1"
8919 [(set (reg FLAGS_REG)
8923 (match_operand 0 "ext_register_operand" "Q")
8927 (match_operand:QI 1 "general_operand" "Qm")))
8929 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8930 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8931 "test{b}\t{%1, %h0|%h0, %1}"
8932 [(set_attr "type" "test")
8933 (set_attr "mode" "QI")])
8935 (define_insn "*testqi_ext_1_rex64"
8936 [(set (reg FLAGS_REG)
8940 (match_operand 0 "ext_register_operand" "Q")
8944 (match_operand:QI 1 "register_operand" "Q")))
8946 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8947 "test{b}\t{%1, %h0|%h0, %1}"
8948 [(set_attr "type" "test")
8949 (set_attr "mode" "QI")])
8951 (define_insn "*testqi_ext_2"
8952 [(set (reg FLAGS_REG)
8956 (match_operand 0 "ext_register_operand" "Q")
8960 (match_operand 1 "ext_register_operand" "Q")
8964 "ix86_match_ccmode (insn, CCNOmode)"
8965 "test{b}\t{%h1, %h0|%h0, %h1}"
8966 [(set_attr "type" "test")
8967 (set_attr "mode" "QI")])
8969 ;; Combine likes to form bit extractions for some tests. Humor it.
8970 (define_insn "*testqi_ext_3"
8971 [(set (reg FLAGS_REG)
8972 (compare (zero_extract:SI
8973 (match_operand 0 "nonimmediate_operand" "rm")
8974 (match_operand:SI 1 "const_int_operand" "")
8975 (match_operand:SI 2 "const_int_operand" ""))
8977 "ix86_match_ccmode (insn, CCNOmode)
8978 && INTVAL (operands[1]) > 0
8979 && INTVAL (operands[2]) >= 0
8980 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8981 && (GET_MODE (operands[0]) == SImode
8982 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8983 || GET_MODE (operands[0]) == HImode
8984 || GET_MODE (operands[0]) == QImode)"
8987 (define_insn "*testqi_ext_3_rex64"
8988 [(set (reg FLAGS_REG)
8989 (compare (zero_extract:DI
8990 (match_operand 0 "nonimmediate_operand" "rm")
8991 (match_operand:DI 1 "const_int_operand" "")
8992 (match_operand:DI 2 "const_int_operand" ""))
8995 && ix86_match_ccmode (insn, CCNOmode)
8996 && INTVAL (operands[1]) > 0
8997 && INTVAL (operands[2]) >= 0
8998 /* Ensure that resulting mask is zero or sign extended operand. */
8999 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9000 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9001 && INTVAL (operands[1]) > 32))
9002 && (GET_MODE (operands[0]) == SImode
9003 || GET_MODE (operands[0]) == DImode
9004 || GET_MODE (operands[0]) == HImode
9005 || GET_MODE (operands[0]) == QImode)"
9009 [(set (match_operand 0 "flags_reg_operand" "")
9010 (match_operator 1 "compare_operator"
9012 (match_operand 2 "nonimmediate_operand" "")
9013 (match_operand 3 "const_int_operand" "")
9014 (match_operand 4 "const_int_operand" ""))
9016 "ix86_match_ccmode (insn, CCNOmode)"
9017 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9019 rtx val = operands[2];
9020 HOST_WIDE_INT len = INTVAL (operands[3]);
9021 HOST_WIDE_INT pos = INTVAL (operands[4]);
9023 enum machine_mode mode, submode;
9025 mode = GET_MODE (val);
9028 /* ??? Combine likes to put non-volatile mem extractions in QImode
9029 no matter the size of the test. So find a mode that works. */
9030 if (! MEM_VOLATILE_P (val))
9032 mode = smallest_mode_for_size (pos + len, MODE_INT);
9033 val = adjust_address (val, mode, 0);
9036 else if (GET_CODE (val) == SUBREG
9037 && (submode = GET_MODE (SUBREG_REG (val)),
9038 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9039 && pos + len <= GET_MODE_BITSIZE (submode)
9040 && GET_MODE_CLASS (submode) == MODE_INT)
9042 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9044 val = SUBREG_REG (val);
9046 else if (mode == HImode && pos + len <= 8)
9048 /* Small HImode tests can be converted to QImode. */
9050 val = gen_lowpart (QImode, val);
9053 if (len == HOST_BITS_PER_WIDE_INT)
9056 mask = ((HOST_WIDE_INT)1 << len) - 1;
9059 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9062 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9063 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9064 ;; this is relatively important trick.
9065 ;; Do the conversion only post-reload to avoid limiting of the register class
9068 [(set (match_operand 0 "flags_reg_operand" "")
9069 (match_operator 1 "compare_operator"
9070 [(and (match_operand 2 "register_operand" "")
9071 (match_operand 3 "const_int_operand" ""))
9074 && QI_REG_P (operands[2])
9075 && GET_MODE (operands[2]) != QImode
9076 && ((ix86_match_ccmode (insn, CCZmode)
9077 && !(INTVAL (operands[3]) & ~(255 << 8)))
9078 || (ix86_match_ccmode (insn, CCNOmode)
9079 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9082 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9085 "operands[2] = gen_lowpart (SImode, operands[2]);
9086 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9089 [(set (match_operand 0 "flags_reg_operand" "")
9090 (match_operator 1 "compare_operator"
9091 [(and (match_operand 2 "nonimmediate_operand" "")
9092 (match_operand 3 "const_int_operand" ""))
9095 && GET_MODE (operands[2]) != QImode
9096 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9097 && ((ix86_match_ccmode (insn, CCZmode)
9098 && !(INTVAL (operands[3]) & ~255))
9099 || (ix86_match_ccmode (insn, CCNOmode)
9100 && !(INTVAL (operands[3]) & ~127)))"
9102 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9104 "operands[2] = gen_lowpart (QImode, operands[2]);
9105 operands[3] = gen_lowpart (QImode, operands[3]);")
9108 ;; %%% This used to optimize known byte-wide and operations to memory,
9109 ;; and sometimes to QImode registers. If this is considered useful,
9110 ;; it should be done with splitters.
9112 (define_expand "anddi3"
9113 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9114 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9115 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9117 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9119 (define_insn "*anddi_1_rex64"
9120 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9121 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9122 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9123 (clobber (reg:CC FLAGS_REG))]
9124 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9126 switch (get_attr_type (insn))
9130 enum machine_mode mode;
9132 gcc_assert (CONST_INT_P (operands[2]));
9133 if (INTVAL (operands[2]) == 0xff)
9137 gcc_assert (INTVAL (operands[2]) == 0xffff);
9141 operands[1] = gen_lowpart (mode, operands[1]);
9143 return "movz{bq|x}\t{%1,%0|%0, %1}";
9145 return "movz{wq|x}\t{%1,%0|%0, %1}";
9149 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9150 if (get_attr_mode (insn) == MODE_SI)
9151 return "and{l}\t{%k2, %k0|%k0, %k2}";
9153 return "and{q}\t{%2, %0|%0, %2}";
9156 [(set_attr "type" "alu,alu,alu,imovx")
9157 (set_attr "length_immediate" "*,*,*,0")
9158 (set_attr "mode" "SI,DI,DI,DI")])
9160 (define_insn "*anddi_2"
9161 [(set (reg FLAGS_REG)
9162 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9163 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9165 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9166 (and:DI (match_dup 1) (match_dup 2)))]
9167 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9168 && ix86_binary_operator_ok (AND, DImode, operands)"
9170 and{l}\t{%k2, %k0|%k0, %k2}
9171 and{q}\t{%2, %0|%0, %2}
9172 and{q}\t{%2, %0|%0, %2}"
9173 [(set_attr "type" "alu")
9174 (set_attr "mode" "SI,DI,DI")])
9176 (define_expand "andsi3"
9177 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9178 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9179 (match_operand:SI 2 "general_operand" "")))]
9181 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9183 (define_insn "*andsi_1"
9184 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9185 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9186 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9187 (clobber (reg:CC FLAGS_REG))]
9188 "ix86_binary_operator_ok (AND, SImode, operands)"
9190 switch (get_attr_type (insn))
9194 enum machine_mode mode;
9196 gcc_assert (CONST_INT_P (operands[2]));
9197 if (INTVAL (operands[2]) == 0xff)
9201 gcc_assert (INTVAL (operands[2]) == 0xffff);
9205 operands[1] = gen_lowpart (mode, operands[1]);
9207 return "movz{bl|x}\t{%1,%0|%0, %1}";
9209 return "movz{wl|x}\t{%1,%0|%0, %1}";
9213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9214 return "and{l}\t{%2, %0|%0, %2}";
9217 [(set_attr "type" "alu,alu,imovx")
9218 (set_attr "length_immediate" "*,*,0")
9219 (set_attr "mode" "SI")])
9222 [(set (match_operand 0 "register_operand" "")
9224 (const_int -65536)))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9227 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9228 "operands[1] = gen_lowpart (HImode, operands[0]);")
9231 [(set (match_operand 0 "ext_register_operand" "")
9234 (clobber (reg:CC FLAGS_REG))]
9235 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9236 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9237 "operands[1] = gen_lowpart (QImode, operands[0]);")
9240 [(set (match_operand 0 "ext_register_operand" "")
9242 (const_int -65281)))
9243 (clobber (reg:CC FLAGS_REG))]
9244 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9245 [(parallel [(set (zero_extract:SI (match_dup 0)
9249 (zero_extract:SI (match_dup 0)
9252 (zero_extract:SI (match_dup 0)
9255 (clobber (reg:CC FLAGS_REG))])]
9256 "operands[0] = gen_lowpart (SImode, operands[0]);")
9258 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9259 (define_insn "*andsi_1_zext"
9260 [(set (match_operand:DI 0 "register_operand" "=r")
9262 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9263 (match_operand:SI 2 "general_operand" "g"))))
9264 (clobber (reg:CC FLAGS_REG))]
9265 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9266 "and{l}\t{%2, %k0|%k0, %2}"
9267 [(set_attr "type" "alu")
9268 (set_attr "mode" "SI")])
9270 (define_insn "*andsi_2"
9271 [(set (reg FLAGS_REG)
9272 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9273 (match_operand:SI 2 "general_operand" "g,ri"))
9275 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9276 (and:SI (match_dup 1) (match_dup 2)))]
9277 "ix86_match_ccmode (insn, CCNOmode)
9278 && ix86_binary_operator_ok (AND, SImode, operands)"
9279 "and{l}\t{%2, %0|%0, %2}"
9280 [(set_attr "type" "alu")
9281 (set_attr "mode" "SI")])
9283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9284 (define_insn "*andsi_2_zext"
9285 [(set (reg FLAGS_REG)
9286 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9287 (match_operand:SI 2 "general_operand" "g"))
9289 (set (match_operand:DI 0 "register_operand" "=r")
9290 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9291 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9292 && ix86_binary_operator_ok (AND, SImode, operands)"
9293 "and{l}\t{%2, %k0|%k0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "SI")])
9297 (define_expand "andhi3"
9298 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9299 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9300 (match_operand:HI 2 "general_operand" "")))]
9301 "TARGET_HIMODE_MATH"
9302 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9304 (define_insn "*andhi_1"
9305 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9306 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9307 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9308 (clobber (reg:CC FLAGS_REG))]
9309 "ix86_binary_operator_ok (AND, HImode, operands)"
9311 switch (get_attr_type (insn))
9314 gcc_assert (CONST_INT_P (operands[2]));
9315 gcc_assert (INTVAL (operands[2]) == 0xff);
9316 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9321 return "and{w}\t{%2, %0|%0, %2}";
9324 [(set_attr "type" "alu,alu,imovx")
9325 (set_attr "length_immediate" "*,*,0")
9326 (set_attr "mode" "HI,HI,SI")])
9328 (define_insn "*andhi_2"
9329 [(set (reg FLAGS_REG)
9330 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9331 (match_operand:HI 2 "general_operand" "rmn,rn"))
9333 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9334 (and:HI (match_dup 1) (match_dup 2)))]
9335 "ix86_match_ccmode (insn, CCNOmode)
9336 && ix86_binary_operator_ok (AND, HImode, operands)"
9337 "and{w}\t{%2, %0|%0, %2}"
9338 [(set_attr "type" "alu")
9339 (set_attr "mode" "HI")])
9341 (define_expand "andqi3"
9342 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9343 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9344 (match_operand:QI 2 "general_operand" "")))]
9345 "TARGET_QIMODE_MATH"
9346 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9348 ;; %%% Potential partial reg stall on alternative 2. What to do?
9349 (define_insn "*andqi_1"
9350 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9351 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9352 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "ix86_binary_operator_ok (AND, QImode, operands)"
9356 and{b}\t{%2, %0|%0, %2}
9357 and{b}\t{%2, %0|%0, %2}
9358 and{l}\t{%k2, %k0|%k0, %k2}"
9359 [(set_attr "type" "alu")
9360 (set_attr "mode" "QI,QI,SI")])
9362 (define_insn "*andqi_1_slp"
9363 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9364 (and:QI (match_dup 0)
9365 (match_operand:QI 1 "general_operand" "qn,qmn")))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9369 "and{b}\t{%1, %0|%0, %1}"
9370 [(set_attr "type" "alu1")
9371 (set_attr "mode" "QI")])
9373 (define_insn "*andqi_2_maybe_si"
9374 [(set (reg FLAGS_REG)
9376 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9377 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9379 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9380 (and:QI (match_dup 1) (match_dup 2)))]
9381 "ix86_binary_operator_ok (AND, QImode, operands)
9382 && ix86_match_ccmode (insn,
9383 CONST_INT_P (operands[2])
9384 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9386 if (which_alternative == 2)
9388 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9389 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9390 return "and{l}\t{%2, %k0|%k0, %2}";
9392 return "and{b}\t{%2, %0|%0, %2}";
9394 [(set_attr "type" "alu")
9395 (set_attr "mode" "QI,QI,SI")])
9397 (define_insn "*andqi_2"
9398 [(set (reg FLAGS_REG)
9400 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9401 (match_operand:QI 2 "general_operand" "qmn,qn"))
9403 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9404 (and:QI (match_dup 1) (match_dup 2)))]
9405 "ix86_match_ccmode (insn, CCNOmode)
9406 && ix86_binary_operator_ok (AND, QImode, operands)"
9407 "and{b}\t{%2, %0|%0, %2}"
9408 [(set_attr "type" "alu")
9409 (set_attr "mode" "QI")])
9411 (define_insn "*andqi_2_slp"
9412 [(set (reg FLAGS_REG)
9414 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9415 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9417 (set (strict_low_part (match_dup 0))
9418 (and:QI (match_dup 0) (match_dup 1)))]
9419 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9420 && ix86_match_ccmode (insn, CCNOmode)
9421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9422 "and{b}\t{%1, %0|%0, %1}"
9423 [(set_attr "type" "alu1")
9424 (set_attr "mode" "QI")])
9426 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9427 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9428 ;; for a QImode operand, which of course failed.
9430 (define_insn "andqi_ext_0"
9431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9436 (match_operand 1 "ext_register_operand" "0")
9439 (match_operand 2 "const_int_operand" "n")))
9440 (clobber (reg:CC FLAGS_REG))]
9442 "and{b}\t{%2, %h0|%h0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "length_immediate" "1")
9445 (set_attr "mode" "QI")])
9447 ;; Generated by peephole translating test to and. This shows up
9448 ;; often in fp comparisons.
9450 (define_insn "*andqi_ext_0_cc"
9451 [(set (reg FLAGS_REG)
9455 (match_operand 1 "ext_register_operand" "0")
9458 (match_operand 2 "const_int_operand" "n"))
9460 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9469 "ix86_match_ccmode (insn, CCNOmode)"
9470 "and{b}\t{%2, %h0|%h0, %2}"
9471 [(set_attr "type" "alu")
9472 (set_attr "length_immediate" "1")
9473 (set_attr "mode" "QI")])
9475 (define_insn "*andqi_ext_1"
9476 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9481 (match_operand 1 "ext_register_operand" "0")
9485 (match_operand:QI 2 "general_operand" "Qm"))))
9486 (clobber (reg:CC FLAGS_REG))]
9488 "and{b}\t{%2, %h0|%h0, %2}"
9489 [(set_attr "type" "alu")
9490 (set_attr "length_immediate" "0")
9491 (set_attr "mode" "QI")])
9493 (define_insn "*andqi_ext_1_rex64"
9494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9499 (match_operand 1 "ext_register_operand" "0")
9503 (match_operand 2 "ext_register_operand" "Q"))))
9504 (clobber (reg:CC FLAGS_REG))]
9506 "and{b}\t{%2, %h0|%h0, %2}"
9507 [(set_attr "type" "alu")
9508 (set_attr "length_immediate" "0")
9509 (set_attr "mode" "QI")])
9511 (define_insn "*andqi_ext_2"
9512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9517 (match_operand 1 "ext_register_operand" "%0")
9521 (match_operand 2 "ext_register_operand" "Q")
9524 (clobber (reg:CC FLAGS_REG))]
9526 "and{b}\t{%h2, %h0|%h0, %h2}"
9527 [(set_attr "type" "alu")
9528 (set_attr "length_immediate" "0")
9529 (set_attr "mode" "QI")])
9531 ;; Convert wide AND instructions with immediate operand to shorter QImode
9532 ;; equivalents when possible.
9533 ;; Don't do the splitting with memory operands, since it introduces risk
9534 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9535 ;; for size, but that can (should?) be handled by generic code instead.
9537 [(set (match_operand 0 "register_operand" "")
9538 (and (match_operand 1 "register_operand" "")
9539 (match_operand 2 "const_int_operand" "")))
9540 (clobber (reg:CC FLAGS_REG))]
9542 && QI_REG_P (operands[0])
9543 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9544 && !(~INTVAL (operands[2]) & ~(255 << 8))
9545 && GET_MODE (operands[0]) != QImode"
9546 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9547 (and:SI (zero_extract:SI (match_dup 1)
9548 (const_int 8) (const_int 8))
9550 (clobber (reg:CC FLAGS_REG))])]
9551 "operands[0] = gen_lowpart (SImode, operands[0]);
9552 operands[1] = gen_lowpart (SImode, operands[1]);
9553 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9555 ;; Since AND can be encoded with sign extended immediate, this is only
9556 ;; profitable when 7th bit is not set.
9558 [(set (match_operand 0 "register_operand" "")
9559 (and (match_operand 1 "general_operand" "")
9560 (match_operand 2 "const_int_operand" "")))
9561 (clobber (reg:CC FLAGS_REG))]
9563 && ANY_QI_REG_P (operands[0])
9564 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9565 && !(~INTVAL (operands[2]) & ~255)
9566 && !(INTVAL (operands[2]) & 128)
9567 && GET_MODE (operands[0]) != QImode"
9568 [(parallel [(set (strict_low_part (match_dup 0))
9569 (and:QI (match_dup 1)
9571 (clobber (reg:CC FLAGS_REG))])]
9572 "operands[0] = gen_lowpart (QImode, operands[0]);
9573 operands[1] = gen_lowpart (QImode, operands[1]);
9574 operands[2] = gen_lowpart (QImode, operands[2]);")
9576 ;; Logical inclusive OR instructions
9578 ;; %%% This used to optimize known byte-wide and operations to memory.
9579 ;; If this is considered useful, it should be done with splitters.
9581 (define_expand "iordi3"
9582 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9583 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9584 (match_operand:DI 2 "x86_64_general_operand" "")))]
9586 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9588 (define_insn "*iordi_1_rex64"
9589 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9590 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9591 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9592 (clobber (reg:CC FLAGS_REG))]
9594 && ix86_binary_operator_ok (IOR, DImode, operands)"
9595 "or{q}\t{%2, %0|%0, %2}"
9596 [(set_attr "type" "alu")
9597 (set_attr "mode" "DI")])
9599 (define_insn "*iordi_2_rex64"
9600 [(set (reg FLAGS_REG)
9601 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9602 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9604 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9605 (ior:DI (match_dup 1) (match_dup 2)))]
9607 && ix86_match_ccmode (insn, CCNOmode)
9608 && ix86_binary_operator_ok (IOR, DImode, operands)"
9609 "or{q}\t{%2, %0|%0, %2}"
9610 [(set_attr "type" "alu")
9611 (set_attr "mode" "DI")])
9613 (define_insn "*iordi_3_rex64"
9614 [(set (reg FLAGS_REG)
9615 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9616 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9618 (clobber (match_scratch:DI 0 "=r"))]
9620 && ix86_match_ccmode (insn, CCNOmode)
9621 && ix86_binary_operator_ok (IOR, DImode, operands)"
9622 "or{q}\t{%2, %0|%0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "mode" "DI")])
9627 (define_expand "iorsi3"
9628 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9629 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9630 (match_operand:SI 2 "general_operand" "")))]
9632 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9634 (define_insn "*iorsi_1"
9635 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9637 (match_operand:SI 2 "general_operand" "ri,g")))
9638 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_binary_operator_ok (IOR, SImode, operands)"
9640 "or{l}\t{%2, %0|%0, %2}"
9641 [(set_attr "type" "alu")
9642 (set_attr "mode" "SI")])
9644 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9645 (define_insn "*iorsi_1_zext"
9646 [(set (match_operand:DI 0 "register_operand" "=r")
9648 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9649 (match_operand:SI 2 "general_operand" "g"))))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9652 "or{l}\t{%2, %k0|%k0, %2}"
9653 [(set_attr "type" "alu")
9654 (set_attr "mode" "SI")])
9656 (define_insn "*iorsi_1_zext_imm"
9657 [(set (match_operand:DI 0 "register_operand" "=r")
9658 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9659 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9660 (clobber (reg:CC FLAGS_REG))]
9662 "or{l}\t{%2, %k0|%k0, %2}"
9663 [(set_attr "type" "alu")
9664 (set_attr "mode" "SI")])
9666 (define_insn "*iorsi_2"
9667 [(set (reg FLAGS_REG)
9668 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9669 (match_operand:SI 2 "general_operand" "g,ri"))
9671 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9672 (ior:SI (match_dup 1) (match_dup 2)))]
9673 "ix86_match_ccmode (insn, CCNOmode)
9674 && ix86_binary_operator_ok (IOR, SImode, operands)"
9675 "or{l}\t{%2, %0|%0, %2}"
9676 [(set_attr "type" "alu")
9677 (set_attr "mode" "SI")])
9679 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9680 ;; ??? Special case for immediate operand is missing - it is tricky.
9681 (define_insn "*iorsi_2_zext"
9682 [(set (reg FLAGS_REG)
9683 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9684 (match_operand:SI 2 "general_operand" "g"))
9686 (set (match_operand:DI 0 "register_operand" "=r")
9687 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9688 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9689 && ix86_binary_operator_ok (IOR, SImode, operands)"
9690 "or{l}\t{%2, %k0|%k0, %2}"
9691 [(set_attr "type" "alu")
9692 (set_attr "mode" "SI")])
9694 (define_insn "*iorsi_2_zext_imm"
9695 [(set (reg FLAGS_REG)
9696 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9699 (set (match_operand:DI 0 "register_operand" "=r")
9700 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702 && ix86_binary_operator_ok (IOR, SImode, operands)"
9703 "or{l}\t{%2, %k0|%k0, %2}"
9704 [(set_attr "type" "alu")
9705 (set_attr "mode" "SI")])
9707 (define_insn "*iorsi_3"
9708 [(set (reg FLAGS_REG)
9709 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710 (match_operand:SI 2 "general_operand" "g"))
9712 (clobber (match_scratch:SI 0 "=r"))]
9713 "ix86_match_ccmode (insn, CCNOmode)
9714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9715 "or{l}\t{%2, %0|%0, %2}"
9716 [(set_attr "type" "alu")
9717 (set_attr "mode" "SI")])
9719 (define_expand "iorhi3"
9720 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9721 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9722 (match_operand:HI 2 "general_operand" "")))]
9723 "TARGET_HIMODE_MATH"
9724 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9726 (define_insn "*iorhi_1"
9727 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9728 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9729 (match_operand:HI 2 "general_operand" "rmn,rn")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "ix86_binary_operator_ok (IOR, HImode, operands)"
9732 "or{w}\t{%2, %0|%0, %2}"
9733 [(set_attr "type" "alu")
9734 (set_attr "mode" "HI")])
9736 (define_insn "*iorhi_2"
9737 [(set (reg FLAGS_REG)
9738 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9739 (match_operand:HI 2 "general_operand" "rmn,rn"))
9741 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9742 (ior:HI (match_dup 1) (match_dup 2)))]
9743 "ix86_match_ccmode (insn, CCNOmode)
9744 && ix86_binary_operator_ok (IOR, HImode, operands)"
9745 "or{w}\t{%2, %0|%0, %2}"
9746 [(set_attr "type" "alu")
9747 (set_attr "mode" "HI")])
9749 (define_insn "*iorhi_3"
9750 [(set (reg FLAGS_REG)
9751 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9752 (match_operand:HI 2 "general_operand" "rmn"))
9754 (clobber (match_scratch:HI 0 "=r"))]
9755 "ix86_match_ccmode (insn, CCNOmode)
9756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9757 "or{w}\t{%2, %0|%0, %2}"
9758 [(set_attr "type" "alu")
9759 (set_attr "mode" "HI")])
9761 (define_expand "iorqi3"
9762 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9763 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9764 (match_operand:QI 2 "general_operand" "")))]
9765 "TARGET_QIMODE_MATH"
9766 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9768 ;; %%% Potential partial reg stall on alternative 2. What to do?
9769 (define_insn "*iorqi_1"
9770 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9771 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9772 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (IOR, QImode, operands)"
9776 or{b}\t{%2, %0|%0, %2}
9777 or{b}\t{%2, %0|%0, %2}
9778 or{l}\t{%k2, %k0|%k0, %k2}"
9779 [(set_attr "type" "alu")
9780 (set_attr "mode" "QI,QI,SI")])
9782 (define_insn "*iorqi_1_slp"
9783 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9784 (ior:QI (match_dup 0)
9785 (match_operand:QI 1 "general_operand" "qmn,qn")))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9788 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9789 "or{b}\t{%1, %0|%0, %1}"
9790 [(set_attr "type" "alu1")
9791 (set_attr "mode" "QI")])
9793 (define_insn "*iorqi_2"
9794 [(set (reg FLAGS_REG)
9795 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9796 (match_operand:QI 2 "general_operand" "qmn,qn"))
9798 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9799 (ior:QI (match_dup 1) (match_dup 2)))]
9800 "ix86_match_ccmode (insn, CCNOmode)
9801 && ix86_binary_operator_ok (IOR, QImode, operands)"
9802 "or{b}\t{%2, %0|%0, %2}"
9803 [(set_attr "type" "alu")
9804 (set_attr "mode" "QI")])
9806 (define_insn "*iorqi_2_slp"
9807 [(set (reg FLAGS_REG)
9808 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9809 (match_operand:QI 1 "general_operand" "qmn,qn"))
9811 (set (strict_low_part (match_dup 0))
9812 (ior:QI (match_dup 0) (match_dup 1)))]
9813 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9814 && ix86_match_ccmode (insn, CCNOmode)
9815 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9816 "or{b}\t{%1, %0|%0, %1}"
9817 [(set_attr "type" "alu1")
9818 (set_attr "mode" "QI")])
9820 (define_insn "*iorqi_3"
9821 [(set (reg FLAGS_REG)
9822 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9823 (match_operand:QI 2 "general_operand" "qmn"))
9825 (clobber (match_scratch:QI 0 "=q"))]
9826 "ix86_match_ccmode (insn, CCNOmode)
9827 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9828 "or{b}\t{%2, %0|%0, %2}"
9829 [(set_attr "type" "alu")
9830 (set_attr "mode" "QI")])
9832 (define_insn "*iorqi_ext_0"
9833 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9838 (match_operand 1 "ext_register_operand" "0")
9841 (match_operand 2 "const_int_operand" "n")))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9844 "or{b}\t{%2, %h0|%h0, %2}"
9845 [(set_attr "type" "alu")
9846 (set_attr "length_immediate" "1")
9847 (set_attr "mode" "QI")])
9849 (define_insn "*iorqi_ext_1"
9850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9855 (match_operand 1 "ext_register_operand" "0")
9859 (match_operand:QI 2 "general_operand" "Qm"))))
9860 (clobber (reg:CC FLAGS_REG))]
9862 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9863 "or{b}\t{%2, %h0|%h0, %2}"
9864 [(set_attr "type" "alu")
9865 (set_attr "length_immediate" "0")
9866 (set_attr "mode" "QI")])
9868 (define_insn "*iorqi_ext_1_rex64"
9869 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9874 (match_operand 1 "ext_register_operand" "0")
9878 (match_operand 2 "ext_register_operand" "Q"))))
9879 (clobber (reg:CC FLAGS_REG))]
9881 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9882 "or{b}\t{%2, %h0|%h0, %2}"
9883 [(set_attr "type" "alu")
9884 (set_attr "length_immediate" "0")
9885 (set_attr "mode" "QI")])
9887 (define_insn "*iorqi_ext_2"
9888 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9892 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9895 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9898 (clobber (reg:CC FLAGS_REG))]
9899 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9900 "or{b}\t{%h2, %h0|%h0, %h2}"
9901 [(set_attr "type" "alu")
9902 (set_attr "length_immediate" "0")
9903 (set_attr "mode" "QI")])
9906 [(set (match_operand 0 "register_operand" "")
9907 (ior (match_operand 1 "register_operand" "")
9908 (match_operand 2 "const_int_operand" "")))
9909 (clobber (reg:CC FLAGS_REG))]
9911 && QI_REG_P (operands[0])
9912 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9913 && !(INTVAL (operands[2]) & ~(255 << 8))
9914 && GET_MODE (operands[0]) != QImode"
9915 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9916 (ior:SI (zero_extract:SI (match_dup 1)
9917 (const_int 8) (const_int 8))
9919 (clobber (reg:CC FLAGS_REG))])]
9920 "operands[0] = gen_lowpart (SImode, operands[0]);
9921 operands[1] = gen_lowpart (SImode, operands[1]);
9922 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9924 ;; Since OR can be encoded with sign extended immediate, this is only
9925 ;; profitable when 7th bit is set.
9927 [(set (match_operand 0 "register_operand" "")
9928 (ior (match_operand 1 "general_operand" "")
9929 (match_operand 2 "const_int_operand" "")))
9930 (clobber (reg:CC FLAGS_REG))]
9932 && ANY_QI_REG_P (operands[0])
9933 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9934 && !(INTVAL (operands[2]) & ~255)
9935 && (INTVAL (operands[2]) & 128)
9936 && GET_MODE (operands[0]) != QImode"
9937 [(parallel [(set (strict_low_part (match_dup 0))
9938 (ior:QI (match_dup 1)
9940 (clobber (reg:CC FLAGS_REG))])]
9941 "operands[0] = gen_lowpart (QImode, operands[0]);
9942 operands[1] = gen_lowpart (QImode, operands[1]);
9943 operands[2] = gen_lowpart (QImode, operands[2]);")
9945 ;; Logical XOR instructions
9947 ;; %%% This used to optimize known byte-wide and operations to memory.
9948 ;; If this is considered useful, it should be done with splitters.
9950 (define_expand "xordi3"
9951 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9952 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9953 (match_operand:DI 2 "x86_64_general_operand" "")))]
9955 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9957 (define_insn "*xordi_1_rex64"
9958 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9959 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9960 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9961 (clobber (reg:CC FLAGS_REG))]
9963 && ix86_binary_operator_ok (XOR, DImode, operands)"
9964 "xor{q}\t{%2, %0|%0, %2}"
9965 [(set_attr "type" "alu")
9966 (set_attr "mode" "DI")])
9968 (define_insn "*xordi_2_rex64"
9969 [(set (reg FLAGS_REG)
9970 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9971 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9973 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9974 (xor:DI (match_dup 1) (match_dup 2)))]
9976 && ix86_match_ccmode (insn, CCNOmode)
9977 && ix86_binary_operator_ok (XOR, DImode, operands)"
9978 "xor{q}\t{%2, %0|%0, %2}"
9979 [(set_attr "type" "alu")
9980 (set_attr "mode" "DI")])
9982 (define_insn "*xordi_3_rex64"
9983 [(set (reg FLAGS_REG)
9984 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9985 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9987 (clobber (match_scratch:DI 0 "=r"))]
9989 && ix86_match_ccmode (insn, CCNOmode)
9990 && ix86_binary_operator_ok (XOR, DImode, operands)"
9991 "xor{q}\t{%2, %0|%0, %2}"
9992 [(set_attr "type" "alu")
9993 (set_attr "mode" "DI")])
9995 (define_expand "xorsi3"
9996 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9997 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9998 (match_operand:SI 2 "general_operand" "")))]
10000 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10002 (define_insn "*xorsi_1"
10003 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10004 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005 (match_operand:SI 2 "general_operand" "ri,rm")))
10006 (clobber (reg:CC FLAGS_REG))]
10007 "ix86_binary_operator_ok (XOR, SImode, operands)"
10008 "xor{l}\t{%2, %0|%0, %2}"
10009 [(set_attr "type" "alu")
10010 (set_attr "mode" "SI")])
10012 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10013 ;; Add speccase for immediates
10014 (define_insn "*xorsi_1_zext"
10015 [(set (match_operand:DI 0 "register_operand" "=r")
10017 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10018 (match_operand:SI 2 "general_operand" "g"))))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10021 "xor{l}\t{%2, %k0|%k0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "SI")])
10025 (define_insn "*xorsi_1_zext_imm"
10026 [(set (match_operand:DI 0 "register_operand" "=r")
10027 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10028 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10029 (clobber (reg:CC FLAGS_REG))]
10030 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10031 "xor{l}\t{%2, %k0|%k0, %2}"
10032 [(set_attr "type" "alu")
10033 (set_attr "mode" "SI")])
10035 (define_insn "*xorsi_2"
10036 [(set (reg FLAGS_REG)
10037 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10038 (match_operand:SI 2 "general_operand" "g,ri"))
10040 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10041 (xor:SI (match_dup 1) (match_dup 2)))]
10042 "ix86_match_ccmode (insn, CCNOmode)
10043 && ix86_binary_operator_ok (XOR, SImode, operands)"
10044 "xor{l}\t{%2, %0|%0, %2}"
10045 [(set_attr "type" "alu")
10046 (set_attr "mode" "SI")])
10048 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10049 ;; ??? Special case for immediate operand is missing - it is tricky.
10050 (define_insn "*xorsi_2_zext"
10051 [(set (reg FLAGS_REG)
10052 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10053 (match_operand:SI 2 "general_operand" "g"))
10055 (set (match_operand:DI 0 "register_operand" "=r")
10056 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10058 && ix86_binary_operator_ok (XOR, SImode, operands)"
10059 "xor{l}\t{%2, %k0|%k0, %2}"
10060 [(set_attr "type" "alu")
10061 (set_attr "mode" "SI")])
10063 (define_insn "*xorsi_2_zext_imm"
10064 [(set (reg FLAGS_REG)
10065 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10066 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10068 (set (match_operand:DI 0 "register_operand" "=r")
10069 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10070 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10071 && ix86_binary_operator_ok (XOR, SImode, operands)"
10072 "xor{l}\t{%2, %k0|%k0, %2}"
10073 [(set_attr "type" "alu")
10074 (set_attr "mode" "SI")])
10076 (define_insn "*xorsi_3"
10077 [(set (reg FLAGS_REG)
10078 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10079 (match_operand:SI 2 "general_operand" "g"))
10081 (clobber (match_scratch:SI 0 "=r"))]
10082 "ix86_match_ccmode (insn, CCNOmode)
10083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10084 "xor{l}\t{%2, %0|%0, %2}"
10085 [(set_attr "type" "alu")
10086 (set_attr "mode" "SI")])
10088 (define_expand "xorhi3"
10089 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10090 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10091 (match_operand:HI 2 "general_operand" "")))]
10092 "TARGET_HIMODE_MATH"
10093 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10095 (define_insn "*xorhi_1"
10096 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10097 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10098 (match_operand:HI 2 "general_operand" "rmn,rn")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "ix86_binary_operator_ok (XOR, HImode, operands)"
10101 "xor{w}\t{%2, %0|%0, %2}"
10102 [(set_attr "type" "alu")
10103 (set_attr "mode" "HI")])
10105 (define_insn "*xorhi_2"
10106 [(set (reg FLAGS_REG)
10107 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10108 (match_operand:HI 2 "general_operand" "rmn,rn"))
10110 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10111 (xor:HI (match_dup 1) (match_dup 2)))]
10112 "ix86_match_ccmode (insn, CCNOmode)
10113 && ix86_binary_operator_ok (XOR, HImode, operands)"
10114 "xor{w}\t{%2, %0|%0, %2}"
10115 [(set_attr "type" "alu")
10116 (set_attr "mode" "HI")])
10118 (define_insn "*xorhi_3"
10119 [(set (reg FLAGS_REG)
10120 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10121 (match_operand:HI 2 "general_operand" "rmn"))
10123 (clobber (match_scratch:HI 0 "=r"))]
10124 "ix86_match_ccmode (insn, CCNOmode)
10125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10126 "xor{w}\t{%2, %0|%0, %2}"
10127 [(set_attr "type" "alu")
10128 (set_attr "mode" "HI")])
10130 (define_expand "xorqi3"
10131 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10132 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10133 (match_operand:QI 2 "general_operand" "")))]
10134 "TARGET_QIMODE_MATH"
10135 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10137 ;; %%% Potential partial reg stall on alternative 2. What to do?
10138 (define_insn "*xorqi_1"
10139 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10140 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10141 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10142 (clobber (reg:CC FLAGS_REG))]
10143 "ix86_binary_operator_ok (XOR, QImode, operands)"
10145 xor{b}\t{%2, %0|%0, %2}
10146 xor{b}\t{%2, %0|%0, %2}
10147 xor{l}\t{%k2, %k0|%k0, %k2}"
10148 [(set_attr "type" "alu")
10149 (set_attr "mode" "QI,QI,SI")])
10151 (define_insn "*xorqi_1_slp"
10152 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10153 (xor:QI (match_dup 0)
10154 (match_operand:QI 1 "general_operand" "qn,qmn")))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10157 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10158 "xor{b}\t{%1, %0|%0, %1}"
10159 [(set_attr "type" "alu1")
10160 (set_attr "mode" "QI")])
10162 (define_insn "*xorqi_ext_0"
10163 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10168 (match_operand 1 "ext_register_operand" "0")
10171 (match_operand 2 "const_int_operand" "n")))
10172 (clobber (reg:CC FLAGS_REG))]
10173 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10174 "xor{b}\t{%2, %h0|%h0, %2}"
10175 [(set_attr "type" "alu")
10176 (set_attr "length_immediate" "1")
10177 (set_attr "mode" "QI")])
10179 (define_insn "*xorqi_ext_1"
10180 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10185 (match_operand 1 "ext_register_operand" "0")
10189 (match_operand:QI 2 "general_operand" "Qm"))))
10190 (clobber (reg:CC FLAGS_REG))]
10192 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10193 "xor{b}\t{%2, %h0|%h0, %2}"
10194 [(set_attr "type" "alu")
10195 (set_attr "length_immediate" "0")
10196 (set_attr "mode" "QI")])
10198 (define_insn "*xorqi_ext_1_rex64"
10199 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10204 (match_operand 1 "ext_register_operand" "0")
10208 (match_operand 2 "ext_register_operand" "Q"))))
10209 (clobber (reg:CC FLAGS_REG))]
10211 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10212 "xor{b}\t{%2, %h0|%h0, %2}"
10213 [(set_attr "type" "alu")
10214 (set_attr "length_immediate" "0")
10215 (set_attr "mode" "QI")])
10217 (define_insn "*xorqi_ext_2"
10218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10222 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10225 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10228 (clobber (reg:CC FLAGS_REG))]
10229 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10230 "xor{b}\t{%h2, %h0|%h0, %h2}"
10231 [(set_attr "type" "alu")
10232 (set_attr "length_immediate" "0")
10233 (set_attr "mode" "QI")])
10235 (define_insn "*xorqi_cc_1"
10236 [(set (reg FLAGS_REG)
10238 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10239 (match_operand:QI 2 "general_operand" "qmn,qn"))
10241 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10242 (xor:QI (match_dup 1) (match_dup 2)))]
10243 "ix86_match_ccmode (insn, CCNOmode)
10244 && ix86_binary_operator_ok (XOR, QImode, operands)"
10245 "xor{b}\t{%2, %0|%0, %2}"
10246 [(set_attr "type" "alu")
10247 (set_attr "mode" "QI")])
10249 (define_insn "*xorqi_2_slp"
10250 [(set (reg FLAGS_REG)
10251 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10252 (match_operand:QI 1 "general_operand" "qmn,qn"))
10254 (set (strict_low_part (match_dup 0))
10255 (xor:QI (match_dup 0) (match_dup 1)))]
10256 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10257 && ix86_match_ccmode (insn, CCNOmode)
10258 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10259 "xor{b}\t{%1, %0|%0, %1}"
10260 [(set_attr "type" "alu1")
10261 (set_attr "mode" "QI")])
10263 (define_insn "*xorqi_cc_2"
10264 [(set (reg FLAGS_REG)
10266 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10267 (match_operand:QI 2 "general_operand" "qmn"))
10269 (clobber (match_scratch:QI 0 "=q"))]
10270 "ix86_match_ccmode (insn, CCNOmode)
10271 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10272 "xor{b}\t{%2, %0|%0, %2}"
10273 [(set_attr "type" "alu")
10274 (set_attr "mode" "QI")])
10276 (define_insn "*xorqi_cc_ext_1"
10277 [(set (reg FLAGS_REG)
10281 (match_operand 1 "ext_register_operand" "0")
10284 (match_operand:QI 2 "general_operand" "qmn"))
10286 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10290 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10292 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10293 "xor{b}\t{%2, %h0|%h0, %2}"
10294 [(set_attr "type" "alu")
10295 (set_attr "mode" "QI")])
10297 (define_insn "*xorqi_cc_ext_1_rex64"
10298 [(set (reg FLAGS_REG)
10302 (match_operand 1 "ext_register_operand" "0")
10305 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10307 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10311 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10313 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10314 "xor{b}\t{%2, %h0|%h0, %2}"
10315 [(set_attr "type" "alu")
10316 (set_attr "mode" "QI")])
10318 (define_expand "xorqi_cc_ext_1"
10320 (set (reg:CCNO FLAGS_REG)
10324 (match_operand 1 "ext_register_operand" "")
10327 (match_operand:QI 2 "general_operand" ""))
10329 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10333 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10339 [(set (match_operand 0 "register_operand" "")
10340 (xor (match_operand 1 "register_operand" "")
10341 (match_operand 2 "const_int_operand" "")))
10342 (clobber (reg:CC FLAGS_REG))]
10344 && QI_REG_P (operands[0])
10345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10346 && !(INTVAL (operands[2]) & ~(255 << 8))
10347 && GET_MODE (operands[0]) != QImode"
10348 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10349 (xor:SI (zero_extract:SI (match_dup 1)
10350 (const_int 8) (const_int 8))
10352 (clobber (reg:CC FLAGS_REG))])]
10353 "operands[0] = gen_lowpart (SImode, operands[0]);
10354 operands[1] = gen_lowpart (SImode, operands[1]);
10355 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10357 ;; Since XOR can be encoded with sign extended immediate, this is only
10358 ;; profitable when 7th bit is set.
10360 [(set (match_operand 0 "register_operand" "")
10361 (xor (match_operand 1 "general_operand" "")
10362 (match_operand 2 "const_int_operand" "")))
10363 (clobber (reg:CC FLAGS_REG))]
10365 && ANY_QI_REG_P (operands[0])
10366 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10367 && !(INTVAL (operands[2]) & ~255)
10368 && (INTVAL (operands[2]) & 128)
10369 && GET_MODE (operands[0]) != QImode"
10370 [(parallel [(set (strict_low_part (match_dup 0))
10371 (xor:QI (match_dup 1)
10373 (clobber (reg:CC FLAGS_REG))])]
10374 "operands[0] = gen_lowpart (QImode, operands[0]);
10375 operands[1] = gen_lowpart (QImode, operands[1]);
10376 operands[2] = gen_lowpart (QImode, operands[2]);")
10378 ;; Negation instructions
10380 (define_expand "negti2"
10381 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10382 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10384 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10386 (define_insn "*negti2_1"
10387 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10388 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10389 (clobber (reg:CC FLAGS_REG))]
10391 && ix86_unary_operator_ok (NEG, TImode, operands)"
10395 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10396 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_64BIT && reload_completed"
10400 [(set (reg:CCZ FLAGS_REG)
10401 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10402 (set (match_dup 0) (neg:DI (match_dup 1)))])
10404 [(set (match_dup 2)
10405 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10408 (clobber (reg:CC FLAGS_REG))])
10410 [(set (match_dup 2)
10411 (neg:DI (match_dup 2)))
10412 (clobber (reg:CC FLAGS_REG))])]
10413 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10415 (define_expand "negdi2"
10416 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10417 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10419 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10421 (define_insn "*negdi2_1"
10422 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10423 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10424 (clobber (reg:CC FLAGS_REG))]
10426 && ix86_unary_operator_ok (NEG, DImode, operands)"
10430 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10431 (neg:DI (match_operand:DI 1 "general_operand" "")))
10432 (clobber (reg:CC FLAGS_REG))]
10433 "!TARGET_64BIT && reload_completed"
10435 [(set (reg:CCZ FLAGS_REG)
10436 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10437 (set (match_dup 0) (neg:SI (match_dup 1)))])
10439 [(set (match_dup 2)
10440 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10443 (clobber (reg:CC FLAGS_REG))])
10445 [(set (match_dup 2)
10446 (neg:SI (match_dup 2)))
10447 (clobber (reg:CC FLAGS_REG))])]
10448 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10450 (define_insn "*negdi2_1_rex64"
10451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10453 (clobber (reg:CC FLAGS_REG))]
10454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10456 [(set_attr "type" "negnot")
10457 (set_attr "mode" "DI")])
10459 ;; The problem with neg is that it does not perform (compare x 0),
10460 ;; it really performs (compare 0 x), which leaves us with the zero
10461 ;; flag being the only useful item.
10463 (define_insn "*negdi2_cmpz_rex64"
10464 [(set (reg:CCZ FLAGS_REG)
10465 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10467 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10468 (neg:DI (match_dup 1)))]
10469 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10471 [(set_attr "type" "negnot")
10472 (set_attr "mode" "DI")])
10475 (define_expand "negsi2"
10476 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10477 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10479 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10481 (define_insn "*negsi2_1"
10482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10483 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10484 (clobber (reg:CC FLAGS_REG))]
10485 "ix86_unary_operator_ok (NEG, SImode, operands)"
10487 [(set_attr "type" "negnot")
10488 (set_attr "mode" "SI")])
10490 ;; Combine is quite creative about this pattern.
10491 (define_insn "*negsi2_1_zext"
10492 [(set (match_operand:DI 0 "register_operand" "=r")
10493 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10496 (clobber (reg:CC FLAGS_REG))]
10497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10499 [(set_attr "type" "negnot")
10500 (set_attr "mode" "SI")])
10502 ;; The problem with neg is that it does not perform (compare x 0),
10503 ;; it really performs (compare 0 x), which leaves us with the zero
10504 ;; flag being the only useful item.
10506 (define_insn "*negsi2_cmpz"
10507 [(set (reg:CCZ FLAGS_REG)
10508 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10510 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10511 (neg:SI (match_dup 1)))]
10512 "ix86_unary_operator_ok (NEG, SImode, operands)"
10514 [(set_attr "type" "negnot")
10515 (set_attr "mode" "SI")])
10517 (define_insn "*negsi2_cmpz_zext"
10518 [(set (reg:CCZ FLAGS_REG)
10519 (compare:CCZ (lshiftrt:DI
10521 (match_operand:DI 1 "register_operand" "0")
10525 (set (match_operand:DI 0 "register_operand" "=r")
10526 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10529 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10531 [(set_attr "type" "negnot")
10532 (set_attr "mode" "SI")])
10534 (define_expand "neghi2"
10535 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10536 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10537 "TARGET_HIMODE_MATH"
10538 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10540 (define_insn "*neghi2_1"
10541 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10542 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10543 (clobber (reg:CC FLAGS_REG))]
10544 "ix86_unary_operator_ok (NEG, HImode, operands)"
10546 [(set_attr "type" "negnot")
10547 (set_attr "mode" "HI")])
10549 (define_insn "*neghi2_cmpz"
10550 [(set (reg:CCZ FLAGS_REG)
10551 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10553 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10554 (neg:HI (match_dup 1)))]
10555 "ix86_unary_operator_ok (NEG, HImode, operands)"
10557 [(set_attr "type" "negnot")
10558 (set_attr "mode" "HI")])
10560 (define_expand "negqi2"
10561 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10562 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10563 "TARGET_QIMODE_MATH"
10564 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10566 (define_insn "*negqi2_1"
10567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10568 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10569 (clobber (reg:CC FLAGS_REG))]
10570 "ix86_unary_operator_ok (NEG, QImode, operands)"
10572 [(set_attr "type" "negnot")
10573 (set_attr "mode" "QI")])
10575 (define_insn "*negqi2_cmpz"
10576 [(set (reg:CCZ FLAGS_REG)
10577 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10579 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580 (neg:QI (match_dup 1)))]
10581 "ix86_unary_operator_ok (NEG, QImode, operands)"
10583 [(set_attr "type" "negnot")
10584 (set_attr "mode" "QI")])
10586 ;; Changing of sign for FP values is doable using integer unit too.
10588 (define_expand "<code><mode>2"
10589 [(set (match_operand:X87MODEF 0 "register_operand" "")
10590 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10591 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10592 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10594 (define_insn "*absneg<mode>2_mixed"
10595 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10596 (match_operator:MODEF 3 "absneg_operator"
10597 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10598 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10599 (clobber (reg:CC FLAGS_REG))]
10600 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10603 (define_insn "*absneg<mode>2_sse"
10604 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10605 (match_operator:MODEF 3 "absneg_operator"
10606 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10607 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10608 (clobber (reg:CC FLAGS_REG))]
10609 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10612 (define_insn "*absneg<mode>2_i387"
10613 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10614 (match_operator:X87MODEF 3 "absneg_operator"
10615 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10616 (use (match_operand 2 "" ""))
10617 (clobber (reg:CC FLAGS_REG))]
10618 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10621 (define_expand "<code>tf2"
10622 [(set (match_operand:TF 0 "register_operand" "")
10623 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10625 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10627 (define_insn "*absnegtf2_sse"
10628 [(set (match_operand:TF 0 "register_operand" "=x,x")
10629 (match_operator:TF 3 "absneg_operator"
10630 [(match_operand:TF 1 "register_operand" "0,x")]))
10631 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10632 (clobber (reg:CC FLAGS_REG))]
10636 ;; Splitters for fp abs and neg.
10639 [(set (match_operand 0 "fp_register_operand" "")
10640 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10641 (use (match_operand 2 "" ""))
10642 (clobber (reg:CC FLAGS_REG))]
10644 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10647 [(set (match_operand 0 "register_operand" "")
10648 (match_operator 3 "absneg_operator"
10649 [(match_operand 1 "register_operand" "")]))
10650 (use (match_operand 2 "nonimmediate_operand" ""))
10651 (clobber (reg:CC FLAGS_REG))]
10652 "reload_completed && SSE_REG_P (operands[0])"
10653 [(set (match_dup 0) (match_dup 3))]
10655 enum machine_mode mode = GET_MODE (operands[0]);
10656 enum machine_mode vmode = GET_MODE (operands[2]);
10659 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10660 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10661 if (operands_match_p (operands[0], operands[2]))
10664 operands[1] = operands[2];
10667 if (GET_CODE (operands[3]) == ABS)
10668 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10670 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10675 [(set (match_operand:SF 0 "register_operand" "")
10676 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10677 (use (match_operand:V4SF 2 "" ""))
10678 (clobber (reg:CC FLAGS_REG))]
10680 [(parallel [(set (match_dup 0) (match_dup 1))
10681 (clobber (reg:CC FLAGS_REG))])]
10684 operands[0] = gen_lowpart (SImode, operands[0]);
10685 if (GET_CODE (operands[1]) == ABS)
10687 tmp = gen_int_mode (0x7fffffff, SImode);
10688 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10692 tmp = gen_int_mode (0x80000000, SImode);
10693 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10699 [(set (match_operand:DF 0 "register_operand" "")
10700 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10701 (use (match_operand 2 "" ""))
10702 (clobber (reg:CC FLAGS_REG))]
10704 [(parallel [(set (match_dup 0) (match_dup 1))
10705 (clobber (reg:CC FLAGS_REG))])]
10710 tmp = gen_lowpart (DImode, operands[0]);
10711 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10714 if (GET_CODE (operands[1]) == ABS)
10717 tmp = gen_rtx_NOT (DImode, tmp);
10721 operands[0] = gen_highpart (SImode, operands[0]);
10722 if (GET_CODE (operands[1]) == ABS)
10724 tmp = gen_int_mode (0x7fffffff, SImode);
10725 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10729 tmp = gen_int_mode (0x80000000, SImode);
10730 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10737 [(set (match_operand:XF 0 "register_operand" "")
10738 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10739 (use (match_operand 2 "" ""))
10740 (clobber (reg:CC FLAGS_REG))]
10742 [(parallel [(set (match_dup 0) (match_dup 1))
10743 (clobber (reg:CC FLAGS_REG))])]
10746 operands[0] = gen_rtx_REG (SImode,
10747 true_regnum (operands[0])
10748 + (TARGET_64BIT ? 1 : 2));
10749 if (GET_CODE (operands[1]) == ABS)
10751 tmp = GEN_INT (0x7fff);
10752 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10756 tmp = GEN_INT (0x8000);
10757 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10762 ;; Conditionalize these after reload. If they match before reload, we
10763 ;; lose the clobber and ability to use integer instructions.
10765 (define_insn "*<code><mode>2_1"
10766 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10767 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10769 && (reload_completed
10770 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10772 [(set_attr "type" "fsgn")
10773 (set_attr "mode" "<MODE>")])
10775 (define_insn "*<code>extendsfdf2"
10776 [(set (match_operand:DF 0 "register_operand" "=f")
10777 (absneg:DF (float_extend:DF
10778 (match_operand:SF 1 "register_operand" "0"))))]
10779 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10781 [(set_attr "type" "fsgn")
10782 (set_attr "mode" "DF")])
10784 (define_insn "*<code>extendsfxf2"
10785 [(set (match_operand:XF 0 "register_operand" "=f")
10786 (absneg:XF (float_extend:XF
10787 (match_operand:SF 1 "register_operand" "0"))))]
10790 [(set_attr "type" "fsgn")
10791 (set_attr "mode" "XF")])
10793 (define_insn "*<code>extenddfxf2"
10794 [(set (match_operand:XF 0 "register_operand" "=f")
10795 (absneg:XF (float_extend:XF
10796 (match_operand:DF 1 "register_operand" "0"))))]
10799 [(set_attr "type" "fsgn")
10800 (set_attr "mode" "XF")])
10802 ;; Copysign instructions
10804 (define_mode_iterator CSGNMODE [SF DF TF])
10805 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10807 (define_expand "copysign<mode>3"
10808 [(match_operand:CSGNMODE 0 "register_operand" "")
10809 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10810 (match_operand:CSGNMODE 2 "register_operand" "")]
10811 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10814 ix86_expand_copysign (operands);
10818 (define_insn_and_split "copysign<mode>3_const"
10819 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10821 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10822 (match_operand:CSGNMODE 2 "register_operand" "0")
10823 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10825 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10826 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10828 "&& reload_completed"
10831 ix86_split_copysign_const (operands);
10835 (define_insn "copysign<mode>3_var"
10836 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10838 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10839 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10840 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10841 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10843 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10844 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10845 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10849 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10851 [(match_operand:CSGNMODE 2 "register_operand" "")
10852 (match_operand:CSGNMODE 3 "register_operand" "")
10853 (match_operand:<CSGNVMODE> 4 "" "")
10854 (match_operand:<CSGNVMODE> 5 "" "")]
10856 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10857 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10858 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10859 && reload_completed"
10862 ix86_split_copysign_var (operands);
10866 ;; One complement instructions
10868 (define_expand "one_cmpldi2"
10869 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10870 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10872 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10874 (define_insn "*one_cmpldi2_1_rex64"
10875 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10876 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10877 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10879 [(set_attr "type" "negnot")
10880 (set_attr "mode" "DI")])
10882 (define_insn "*one_cmpldi2_2_rex64"
10883 [(set (reg FLAGS_REG)
10884 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10886 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10887 (not:DI (match_dup 1)))]
10888 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10889 && ix86_unary_operator_ok (NOT, DImode, operands)"
10891 [(set_attr "type" "alu1")
10892 (set_attr "mode" "DI")])
10895 [(set (match_operand 0 "flags_reg_operand" "")
10896 (match_operator 2 "compare_operator"
10897 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10899 (set (match_operand:DI 1 "nonimmediate_operand" "")
10900 (not:DI (match_dup 3)))]
10901 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10902 [(parallel [(set (match_dup 0)
10904 [(xor:DI (match_dup 3) (const_int -1))
10907 (xor:DI (match_dup 3) (const_int -1)))])]
10910 (define_expand "one_cmplsi2"
10911 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10912 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10914 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10916 (define_insn "*one_cmplsi2_1"
10917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10918 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10919 "ix86_unary_operator_ok (NOT, SImode, operands)"
10921 [(set_attr "type" "negnot")
10922 (set_attr "mode" "SI")])
10924 ;; ??? Currently never generated - xor is used instead.
10925 (define_insn "*one_cmplsi2_1_zext"
10926 [(set (match_operand:DI 0 "register_operand" "=r")
10927 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10928 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10930 [(set_attr "type" "negnot")
10931 (set_attr "mode" "SI")])
10933 (define_insn "*one_cmplsi2_2"
10934 [(set (reg FLAGS_REG)
10935 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10937 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10938 (not:SI (match_dup 1)))]
10939 "ix86_match_ccmode (insn, CCNOmode)
10940 && ix86_unary_operator_ok (NOT, SImode, operands)"
10942 [(set_attr "type" "alu1")
10943 (set_attr "mode" "SI")])
10946 [(set (match_operand 0 "flags_reg_operand" "")
10947 (match_operator 2 "compare_operator"
10948 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10950 (set (match_operand:SI 1 "nonimmediate_operand" "")
10951 (not:SI (match_dup 3)))]
10952 "ix86_match_ccmode (insn, CCNOmode)"
10953 [(parallel [(set (match_dup 0)
10954 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10957 (xor:SI (match_dup 3) (const_int -1)))])]
10960 ;; ??? Currently never generated - xor is used instead.
10961 (define_insn "*one_cmplsi2_2_zext"
10962 [(set (reg FLAGS_REG)
10963 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10965 (set (match_operand:DI 0 "register_operand" "=r")
10966 (zero_extend:DI (not:SI (match_dup 1))))]
10967 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10968 && ix86_unary_operator_ok (NOT, SImode, operands)"
10970 [(set_attr "type" "alu1")
10971 (set_attr "mode" "SI")])
10974 [(set (match_operand 0 "flags_reg_operand" "")
10975 (match_operator 2 "compare_operator"
10976 [(not:SI (match_operand:SI 3 "register_operand" ""))
10978 (set (match_operand:DI 1 "register_operand" "")
10979 (zero_extend:DI (not:SI (match_dup 3))))]
10980 "ix86_match_ccmode (insn, CCNOmode)"
10981 [(parallel [(set (match_dup 0)
10982 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10985 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10988 (define_expand "one_cmplhi2"
10989 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10990 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10991 "TARGET_HIMODE_MATH"
10992 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10994 (define_insn "*one_cmplhi2_1"
10995 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10996 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10997 "ix86_unary_operator_ok (NOT, HImode, operands)"
10999 [(set_attr "type" "negnot")
11000 (set_attr "mode" "HI")])
11002 (define_insn "*one_cmplhi2_2"
11003 [(set (reg FLAGS_REG)
11004 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11006 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11007 (not:HI (match_dup 1)))]
11008 "ix86_match_ccmode (insn, CCNOmode)
11009 && ix86_unary_operator_ok (NEG, HImode, operands)"
11011 [(set_attr "type" "alu1")
11012 (set_attr "mode" "HI")])
11015 [(set (match_operand 0 "flags_reg_operand" "")
11016 (match_operator 2 "compare_operator"
11017 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11019 (set (match_operand:HI 1 "nonimmediate_operand" "")
11020 (not:HI (match_dup 3)))]
11021 "ix86_match_ccmode (insn, CCNOmode)"
11022 [(parallel [(set (match_dup 0)
11023 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11026 (xor:HI (match_dup 3) (const_int -1)))])]
11029 ;; %%% Potential partial reg stall on alternative 1. What to do?
11030 (define_expand "one_cmplqi2"
11031 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11032 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11033 "TARGET_QIMODE_MATH"
11034 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11036 (define_insn "*one_cmplqi2_1"
11037 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11038 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11039 "ix86_unary_operator_ok (NOT, QImode, operands)"
11043 [(set_attr "type" "negnot")
11044 (set_attr "mode" "QI,SI")])
11046 (define_insn "*one_cmplqi2_2"
11047 [(set (reg FLAGS_REG)
11048 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11050 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11051 (not:QI (match_dup 1)))]
11052 "ix86_match_ccmode (insn, CCNOmode)
11053 && ix86_unary_operator_ok (NOT, QImode, operands)"
11055 [(set_attr "type" "alu1")
11056 (set_attr "mode" "QI")])
11059 [(set (match_operand 0 "flags_reg_operand" "")
11060 (match_operator 2 "compare_operator"
11061 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11063 (set (match_operand:QI 1 "nonimmediate_operand" "")
11064 (not:QI (match_dup 3)))]
11065 "ix86_match_ccmode (insn, CCNOmode)"
11066 [(parallel [(set (match_dup 0)
11067 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11070 (xor:QI (match_dup 3) (const_int -1)))])]
11073 ;; Arithmetic shift instructions
11075 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11076 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11077 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11078 ;; from the assembler input.
11080 ;; This instruction shifts the target reg/mem as usual, but instead of
11081 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11082 ;; is a left shift double, bits are taken from the high order bits of
11083 ;; reg, else if the insn is a shift right double, bits are taken from the
11084 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11085 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11087 ;; Since sh[lr]d does not change the `reg' operand, that is done
11088 ;; separately, making all shifts emit pairs of shift double and normal
11089 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11090 ;; support a 63 bit shift, each shift where the count is in a reg expands
11091 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11093 ;; If the shift count is a constant, we need never emit more than one
11094 ;; shift pair, instead using moves and sign extension for counts greater
11097 (define_expand "ashlti3"
11098 [(set (match_operand:TI 0 "register_operand" "")
11099 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11100 (match_operand:QI 2 "nonmemory_operand" "")))]
11102 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11104 ;; This pattern must be defined before *ashlti3_1 to prevent
11105 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11107 (define_insn "*avx_ashlti3"
11108 [(set (match_operand:TI 0 "register_operand" "=x")
11109 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11110 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11113 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11114 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11116 [(set_attr "type" "sseishft")
11117 (set_attr "prefix" "vex")
11118 (set_attr "mode" "TI")])
11120 (define_insn "sse2_ashlti3"
11121 [(set (match_operand:TI 0 "register_operand" "=x")
11122 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11123 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11126 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11127 return "pslldq\t{%2, %0|%0, %2}";
11129 [(set_attr "type" "sseishft")
11130 (set_attr "prefix_data16" "1")
11131 (set_attr "mode" "TI")])
11133 (define_insn "*ashlti3_1"
11134 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11135 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11136 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11137 (clobber (reg:CC FLAGS_REG))]
11140 [(set_attr "type" "multi")])
11143 [(match_scratch:DI 3 "r")
11144 (parallel [(set (match_operand:TI 0 "register_operand" "")
11145 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11146 (match_operand:QI 2 "nonmemory_operand" "")))
11147 (clobber (reg:CC FLAGS_REG))])
11151 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11154 [(set (match_operand:TI 0 "register_operand" "")
11155 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11156 (match_operand:QI 2 "nonmemory_operand" "")))
11157 (clobber (reg:CC FLAGS_REG))]
11158 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11159 ? epilogue_completed : reload_completed)"
11161 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11163 (define_insn "x86_64_shld"
11164 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11165 (ior:DI (ashift:DI (match_dup 0)
11166 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11168 (minus:QI (const_int 64) (match_dup 2)))))
11169 (clobber (reg:CC FLAGS_REG))]
11171 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11172 [(set_attr "type" "ishift")
11173 (set_attr "prefix_0f" "1")
11174 (set_attr "mode" "DI")
11175 (set_attr "athlon_decode" "vector")
11176 (set_attr "amdfam10_decode" "vector")])
11178 (define_expand "x86_64_shift_adj_1"
11179 [(set (reg:CCZ FLAGS_REG)
11180 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11183 (set (match_operand:DI 0 "register_operand" "")
11184 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11185 (match_operand:DI 1 "register_operand" "")
11188 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11189 (match_operand:DI 3 "register_operand" "r")
11194 (define_expand "x86_64_shift_adj_2"
11195 [(use (match_operand:DI 0 "register_operand" ""))
11196 (use (match_operand:DI 1 "register_operand" ""))
11197 (use (match_operand:QI 2 "register_operand" ""))]
11200 rtx label = gen_label_rtx ();
11203 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11205 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208 gen_rtx_LABEL_REF (VOIDmode, label),
11210 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211 JUMP_LABEL (tmp) = label;
11213 emit_move_insn (operands[0], operands[1]);
11214 ix86_expand_clear (operands[1]);
11216 emit_label (label);
11217 LABEL_NUSES (label) = 1;
11222 (define_expand "ashldi3"
11223 [(set (match_operand:DI 0 "shiftdi_operand" "")
11224 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11225 (match_operand:QI 2 "nonmemory_operand" "")))]
11227 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11229 (define_insn "*ashldi3_1_rex64"
11230 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11231 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11232 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11233 (clobber (reg:CC FLAGS_REG))]
11234 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11236 switch (get_attr_type (insn))
11239 gcc_assert (operands[2] == const1_rtx);
11240 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11241 return "add{q}\t%0, %0";
11244 gcc_assert (CONST_INT_P (operands[2]));
11245 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11246 operands[1] = gen_rtx_MULT (DImode, operands[1],
11247 GEN_INT (1 << INTVAL (operands[2])));
11248 return "lea{q}\t{%a1, %0|%0, %a1}";
11251 if (REG_P (operands[2]))
11252 return "sal{q}\t{%b2, %0|%0, %b2}";
11253 else if (operands[2] == const1_rtx
11254 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11255 return "sal{q}\t%0";
11257 return "sal{q}\t{%2, %0|%0, %2}";
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11265 (match_operand 0 "register_operand" ""))
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11269 (const_string "ishift")))
11270 (set_attr "mode" "DI")])
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11274 [(set (match_operand:DI 0 "register_operand" "")
11275 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11276 (match_operand:QI 2 "immediate_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)
11281 (mult:DI (match_dup 1)
11283 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11285 ;; This pattern can't accept a variable shift count, since shifts by
11286 ;; zero don't affect the flags. We assume that shifts by constant
11287 ;; zero are optimized away.
11288 (define_insn "*ashldi3_cmp_rex64"
11289 [(set (reg FLAGS_REG)
11291 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11292 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11294 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11295 (ashift:DI (match_dup 1) (match_dup 2)))]
11297 && (optimize_function_for_size_p (cfun)
11298 || !TARGET_PARTIAL_FLAG_REG_STALL
11299 || (operands[2] == const1_rtx
11301 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11302 && ix86_match_ccmode (insn, CCGOCmode)
11303 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11305 switch (get_attr_type (insn))
11308 gcc_assert (operands[2] == const1_rtx);
11309 return "add{q}\t%0, %0";
11312 if (REG_P (operands[2]))
11313 return "sal{q}\t{%b2, %0|%0, %b2}";
11314 else if (operands[2] == const1_rtx
11315 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11316 return "sal{q}\t%0";
11318 return "sal{q}\t{%2, %0|%0, %2}";
11321 [(set (attr "type")
11322 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11324 (match_operand 0 "register_operand" ""))
11325 (match_operand 2 "const1_operand" ""))
11326 (const_string "alu")
11328 (const_string "ishift")))
11329 (set_attr "mode" "DI")])
11331 (define_insn "*ashldi3_cconly_rex64"
11332 [(set (reg FLAGS_REG)
11334 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11335 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11337 (clobber (match_scratch:DI 0 "=r"))]
11339 && (optimize_function_for_size_p (cfun)
11340 || !TARGET_PARTIAL_FLAG_REG_STALL
11341 || (operands[2] == const1_rtx
11343 || TARGET_DOUBLE_WITH_ADD)))
11344 && ix86_match_ccmode (insn, CCGOCmode)
11345 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11347 switch (get_attr_type (insn))
11350 gcc_assert (operands[2] == const1_rtx);
11351 return "add{q}\t%0, %0";
11354 if (REG_P (operands[2]))
11355 return "sal{q}\t{%b2, %0|%0, %b2}";
11356 else if (operands[2] == const1_rtx
11357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11358 return "sal{q}\t%0";
11360 return "sal{q}\t{%2, %0|%0, %2}";
11363 [(set (attr "type")
11364 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11366 (match_operand 0 "register_operand" ""))
11367 (match_operand 2 "const1_operand" ""))
11368 (const_string "alu")
11370 (const_string "ishift")))
11371 (set_attr "mode" "DI")])
11373 (define_insn "*ashldi3_1"
11374 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11375 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11376 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11377 (clobber (reg:CC FLAGS_REG))]
11380 [(set_attr "type" "multi")])
11382 ;; By default we don't ask for a scratch register, because when DImode
11383 ;; values are manipulated, registers are already at a premium. But if
11384 ;; we have one handy, we won't turn it away.
11386 [(match_scratch:SI 3 "r")
11387 (parallel [(set (match_operand:DI 0 "register_operand" "")
11388 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11389 (match_operand:QI 2 "nonmemory_operand" "")))
11390 (clobber (reg:CC FLAGS_REG))])
11392 "!TARGET_64BIT && TARGET_CMOVE"
11394 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11397 [(set (match_operand:DI 0 "register_operand" "")
11398 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11399 (match_operand:QI 2 "nonmemory_operand" "")))
11400 (clobber (reg:CC FLAGS_REG))]
11401 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11402 ? epilogue_completed : reload_completed)"
11404 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11406 (define_insn "x86_shld"
11407 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11408 (ior:SI (ashift:SI (match_dup 0)
11409 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11410 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11411 (minus:QI (const_int 32) (match_dup 2)))))
11412 (clobber (reg:CC FLAGS_REG))]
11414 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11415 [(set_attr "type" "ishift")
11416 (set_attr "prefix_0f" "1")
11417 (set_attr "mode" "SI")
11418 (set_attr "pent_pair" "np")
11419 (set_attr "athlon_decode" "vector")
11420 (set_attr "amdfam10_decode" "vector")])
11422 (define_expand "x86_shift_adj_1"
11423 [(set (reg:CCZ FLAGS_REG)
11424 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11427 (set (match_operand:SI 0 "register_operand" "")
11428 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11429 (match_operand:SI 1 "register_operand" "")
11432 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11433 (match_operand:SI 3 "register_operand" "r")
11438 (define_expand "x86_shift_adj_2"
11439 [(use (match_operand:SI 0 "register_operand" ""))
11440 (use (match_operand:SI 1 "register_operand" ""))
11441 (use (match_operand:QI 2 "register_operand" ""))]
11444 rtx label = gen_label_rtx ();
11447 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11449 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11450 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11451 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11452 gen_rtx_LABEL_REF (VOIDmode, label),
11454 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11455 JUMP_LABEL (tmp) = label;
11457 emit_move_insn (operands[0], operands[1]);
11458 ix86_expand_clear (operands[1]);
11460 emit_label (label);
11461 LABEL_NUSES (label) = 1;
11466 (define_expand "ashlsi3"
11467 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11468 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11469 (match_operand:QI 2 "nonmemory_operand" "")))]
11471 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11473 (define_insn "*ashlsi3_1"
11474 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11475 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11476 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11477 (clobber (reg:CC FLAGS_REG))]
11478 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11480 switch (get_attr_type (insn))
11483 gcc_assert (operands[2] == const1_rtx);
11484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11485 return "add{l}\t%0, %0";
11491 if (REG_P (operands[2]))
11492 return "sal{l}\t{%b2, %0|%0, %b2}";
11493 else if (operands[2] == const1_rtx
11494 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11495 return "sal{l}\t%0";
11497 return "sal{l}\t{%2, %0|%0, %2}";
11500 [(set (attr "type")
11501 (cond [(eq_attr "alternative" "1")
11502 (const_string "lea")
11503 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11505 (match_operand 0 "register_operand" ""))
11506 (match_operand 2 "const1_operand" ""))
11507 (const_string "alu")
11509 (const_string "ishift")))
11510 (set_attr "mode" "SI")])
11512 ;; Convert lea to the lea pattern to avoid flags dependency.
11514 [(set (match_operand 0 "register_operand" "")
11515 (ashift (match_operand 1 "index_register_operand" "")
11516 (match_operand:QI 2 "const_int_operand" "")))
11517 (clobber (reg:CC FLAGS_REG))]
11519 && true_regnum (operands[0]) != true_regnum (operands[1])
11520 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11524 enum machine_mode mode = GET_MODE (operands[0]);
11526 if (GET_MODE_SIZE (mode) < 4)
11527 operands[0] = gen_lowpart (SImode, operands[0]);
11529 operands[1] = gen_lowpart (Pmode, operands[1]);
11530 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11532 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11533 if (Pmode != SImode)
11534 pat = gen_rtx_SUBREG (SImode, pat, 0);
11535 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11539 ;; Rare case of shifting RSP is handled by generating move and shift
11541 [(set (match_operand 0 "register_operand" "")
11542 (ashift (match_operand 1 "register_operand" "")
11543 (match_operand:QI 2 "const_int_operand" "")))
11544 (clobber (reg:CC FLAGS_REG))]
11546 && true_regnum (operands[0]) != true_regnum (operands[1])"
11550 emit_move_insn (operands[0], operands[1]);
11551 pat = gen_rtx_SET (VOIDmode, operands[0],
11552 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11553 operands[0], operands[2]));
11554 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11555 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11559 (define_insn "*ashlsi3_1_zext"
11560 [(set (match_operand:DI 0 "register_operand" "=r,r")
11561 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11562 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11563 (clobber (reg:CC FLAGS_REG))]
11564 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11566 switch (get_attr_type (insn))
11569 gcc_assert (operands[2] == const1_rtx);
11570 return "add{l}\t%k0, %k0";
11576 if (REG_P (operands[2]))
11577 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11578 else if (operands[2] == const1_rtx
11579 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11580 return "sal{l}\t%k0";
11582 return "sal{l}\t{%2, %k0|%k0, %2}";
11585 [(set (attr "type")
11586 (cond [(eq_attr "alternative" "1")
11587 (const_string "lea")
11588 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11590 (match_operand 2 "const1_operand" ""))
11591 (const_string "alu")
11593 (const_string "ishift")))
11594 (set_attr "mode" "SI")])
11596 ;; Convert lea to the lea pattern to avoid flags dependency.
11598 [(set (match_operand:DI 0 "register_operand" "")
11599 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11600 (match_operand:QI 2 "const_int_operand" ""))))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "TARGET_64BIT && reload_completed
11603 && true_regnum (operands[0]) != true_regnum (operands[1])"
11604 [(set (match_dup 0) (zero_extend:DI
11605 (subreg:SI (mult:DI (match_dup 1)
11606 (match_dup 2)) 0)))]
11608 operands[1] = gen_lowpart (Pmode, operands[1]);
11609 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11612 ;; This pattern can't accept a variable shift count, since shifts by
11613 ;; zero don't affect the flags. We assume that shifts by constant
11614 ;; zero are optimized away.
11615 (define_insn "*ashlsi3_cmp"
11616 [(set (reg FLAGS_REG)
11618 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11621 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11622 (ashift:SI (match_dup 1) (match_dup 2)))]
11623 "(optimize_function_for_size_p (cfun)
11624 || !TARGET_PARTIAL_FLAG_REG_STALL
11625 || (operands[2] == const1_rtx
11627 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11628 && ix86_match_ccmode (insn, CCGOCmode)
11629 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11631 switch (get_attr_type (insn))
11634 gcc_assert (operands[2] == const1_rtx);
11635 return "add{l}\t%0, %0";
11638 if (REG_P (operands[2]))
11639 return "sal{l}\t{%b2, %0|%0, %b2}";
11640 else if (operands[2] == const1_rtx
11641 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11642 return "sal{l}\t%0";
11644 return "sal{l}\t{%2, %0|%0, %2}";
11647 [(set (attr "type")
11648 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11650 (match_operand 0 "register_operand" ""))
11651 (match_operand 2 "const1_operand" ""))
11652 (const_string "alu")
11654 (const_string "ishift")))
11655 (set_attr "mode" "SI")])
11657 (define_insn "*ashlsi3_cconly"
11658 [(set (reg FLAGS_REG)
11660 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11661 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11663 (clobber (match_scratch:SI 0 "=r"))]
11664 "(optimize_function_for_size_p (cfun)
11665 || !TARGET_PARTIAL_FLAG_REG_STALL
11666 || (operands[2] == const1_rtx
11668 || TARGET_DOUBLE_WITH_ADD)))
11669 && ix86_match_ccmode (insn, CCGOCmode)
11670 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11672 switch (get_attr_type (insn))
11675 gcc_assert (operands[2] == const1_rtx);
11676 return "add{l}\t%0, %0";
11679 if (REG_P (operands[2]))
11680 return "sal{l}\t{%b2, %0|%0, %b2}";
11681 else if (operands[2] == const1_rtx
11682 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11683 return "sal{l}\t%0";
11685 return "sal{l}\t{%2, %0|%0, %2}";
11688 [(set (attr "type")
11689 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11691 (match_operand 0 "register_operand" ""))
11692 (match_operand 2 "const1_operand" ""))
11693 (const_string "alu")
11695 (const_string "ishift")))
11696 (set_attr "mode" "SI")])
11698 (define_insn "*ashlsi3_cmp_zext"
11699 [(set (reg FLAGS_REG)
11701 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11702 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11704 (set (match_operand:DI 0 "register_operand" "=r")
11705 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11707 && (optimize_function_for_size_p (cfun)
11708 || !TARGET_PARTIAL_FLAG_REG_STALL
11709 || (operands[2] == const1_rtx
11711 || TARGET_DOUBLE_WITH_ADD)))
11712 && ix86_match_ccmode (insn, CCGOCmode)
11713 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11715 switch (get_attr_type (insn))
11718 gcc_assert (operands[2] == const1_rtx);
11719 return "add{l}\t%k0, %k0";
11722 if (REG_P (operands[2]))
11723 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11724 else if (operands[2] == const1_rtx
11725 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11726 return "sal{l}\t%k0";
11728 return "sal{l}\t{%2, %k0|%k0, %2}";
11731 [(set (attr "type")
11732 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11734 (match_operand 2 "const1_operand" ""))
11735 (const_string "alu")
11737 (const_string "ishift")))
11738 (set_attr "mode" "SI")])
11740 (define_expand "ashlhi3"
11741 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11742 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))]
11744 "TARGET_HIMODE_MATH"
11745 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11747 (define_insn "*ashlhi3_1_lea"
11748 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11749 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11750 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11751 (clobber (reg:CC FLAGS_REG))]
11752 "!TARGET_PARTIAL_REG_STALL
11753 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11755 switch (get_attr_type (insn))
11760 gcc_assert (operands[2] == const1_rtx);
11761 return "add{w}\t%0, %0";
11764 if (REG_P (operands[2]))
11765 return "sal{w}\t{%b2, %0|%0, %b2}";
11766 else if (operands[2] == const1_rtx
11767 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11768 return "sal{w}\t%0";
11770 return "sal{w}\t{%2, %0|%0, %2}";
11773 [(set (attr "type")
11774 (cond [(eq_attr "alternative" "1")
11775 (const_string "lea")
11776 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (match_operand 0 "register_operand" ""))
11779 (match_operand 2 "const1_operand" ""))
11780 (const_string "alu")
11782 (const_string "ishift")))
11783 (set_attr "mode" "HI,SI")])
11785 (define_insn "*ashlhi3_1"
11786 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11787 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11788 (match_operand:QI 2 "nonmemory_operand" "cI")))
11789 (clobber (reg:CC FLAGS_REG))]
11790 "TARGET_PARTIAL_REG_STALL
11791 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11793 switch (get_attr_type (insn))
11796 gcc_assert (operands[2] == const1_rtx);
11797 return "add{w}\t%0, %0";
11800 if (REG_P (operands[2]))
11801 return "sal{w}\t{%b2, %0|%0, %b2}";
11802 else if (operands[2] == const1_rtx
11803 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11804 return "sal{w}\t%0";
11806 return "sal{w}\t{%2, %0|%0, %2}";
11809 [(set (attr "type")
11810 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11812 (match_operand 0 "register_operand" ""))
11813 (match_operand 2 "const1_operand" ""))
11814 (const_string "alu")
11816 (const_string "ishift")))
11817 (set_attr "mode" "HI")])
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags. We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashlhi3_cmp"
11823 [(set (reg FLAGS_REG)
11825 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11826 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11828 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11829 (ashift:HI (match_dup 1) (match_dup 2)))]
11830 "(optimize_function_for_size_p (cfun)
11831 || !TARGET_PARTIAL_FLAG_REG_STALL
11832 || (operands[2] == const1_rtx
11834 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11835 && ix86_match_ccmode (insn, CCGOCmode)
11836 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11838 switch (get_attr_type (insn))
11841 gcc_assert (operands[2] == const1_rtx);
11842 return "add{w}\t%0, %0";
11845 if (REG_P (operands[2]))
11846 return "sal{w}\t{%b2, %0|%0, %b2}";
11847 else if (operands[2] == const1_rtx
11848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11849 return "sal{w}\t%0";
11851 return "sal{w}\t{%2, %0|%0, %2}";
11854 [(set (attr "type")
11855 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11857 (match_operand 0 "register_operand" ""))
11858 (match_operand 2 "const1_operand" ""))
11859 (const_string "alu")
11861 (const_string "ishift")))
11862 (set_attr "mode" "HI")])
11864 (define_insn "*ashlhi3_cconly"
11865 [(set (reg FLAGS_REG)
11867 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11868 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11870 (clobber (match_scratch:HI 0 "=r"))]
11871 "(optimize_function_for_size_p (cfun)
11872 || !TARGET_PARTIAL_FLAG_REG_STALL
11873 || (operands[2] == const1_rtx
11875 || TARGET_DOUBLE_WITH_ADD)))
11876 && ix86_match_ccmode (insn, CCGOCmode)
11877 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11879 switch (get_attr_type (insn))
11882 gcc_assert (operands[2] == const1_rtx);
11883 return "add{w}\t%0, %0";
11886 if (REG_P (operands[2]))
11887 return "sal{w}\t{%b2, %0|%0, %b2}";
11888 else if (operands[2] == const1_rtx
11889 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11890 return "sal{w}\t%0";
11892 return "sal{w}\t{%2, %0|%0, %2}";
11895 [(set (attr "type")
11896 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11898 (match_operand 0 "register_operand" ""))
11899 (match_operand 2 "const1_operand" ""))
11900 (const_string "alu")
11902 (const_string "ishift")))
11903 (set_attr "mode" "HI")])
11905 (define_expand "ashlqi3"
11906 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11907 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11908 (match_operand:QI 2 "nonmemory_operand" "")))]
11909 "TARGET_QIMODE_MATH"
11910 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11912 ;; %%% Potential partial reg stall on alternative 2. What to do?
11914 (define_insn "*ashlqi3_1_lea"
11915 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11916 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11917 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11918 (clobber (reg:CC FLAGS_REG))]
11919 "!TARGET_PARTIAL_REG_STALL
11920 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11922 switch (get_attr_type (insn))
11927 gcc_assert (operands[2] == const1_rtx);
11928 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11929 return "add{l}\t%k0, %k0";
11931 return "add{b}\t%0, %0";
11934 if (REG_P (operands[2]))
11936 if (get_attr_mode (insn) == MODE_SI)
11937 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11939 return "sal{b}\t{%b2, %0|%0, %b2}";
11941 else if (operands[2] == const1_rtx
11942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11944 if (get_attr_mode (insn) == MODE_SI)
11945 return "sal{l}\t%0";
11947 return "sal{b}\t%0";
11951 if (get_attr_mode (insn) == MODE_SI)
11952 return "sal{l}\t{%2, %k0|%k0, %2}";
11954 return "sal{b}\t{%2, %0|%0, %2}";
11958 [(set (attr "type")
11959 (cond [(eq_attr "alternative" "2")
11960 (const_string "lea")
11961 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11963 (match_operand 0 "register_operand" ""))
11964 (match_operand 2 "const1_operand" ""))
11965 (const_string "alu")
11967 (const_string "ishift")))
11968 (set_attr "mode" "QI,SI,SI")])
11970 (define_insn "*ashlqi3_1"
11971 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11972 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11973 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "TARGET_PARTIAL_REG_STALL
11976 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11978 switch (get_attr_type (insn))
11981 gcc_assert (operands[2] == const1_rtx);
11982 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11983 return "add{l}\t%k0, %k0";
11985 return "add{b}\t%0, %0";
11988 if (REG_P (operands[2]))
11990 if (get_attr_mode (insn) == MODE_SI)
11991 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11993 return "sal{b}\t{%b2, %0|%0, %b2}";
11995 else if (operands[2] == const1_rtx
11996 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11998 if (get_attr_mode (insn) == MODE_SI)
11999 return "sal{l}\t%0";
12001 return "sal{b}\t%0";
12005 if (get_attr_mode (insn) == MODE_SI)
12006 return "sal{l}\t{%2, %k0|%k0, %2}";
12008 return "sal{b}\t{%2, %0|%0, %2}";
12012 [(set (attr "type")
12013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12015 (match_operand 0 "register_operand" ""))
12016 (match_operand 2 "const1_operand" ""))
12017 (const_string "alu")
12019 (const_string "ishift")))
12020 (set_attr "mode" "QI,SI")])
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags. We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashlqi3_cmp"
12026 [(set (reg FLAGS_REG)
12028 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12031 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12032 (ashift:QI (match_dup 1) (match_dup 2)))]
12033 "(optimize_function_for_size_p (cfun)
12034 || !TARGET_PARTIAL_FLAG_REG_STALL
12035 || (operands[2] == const1_rtx
12037 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12038 && ix86_match_ccmode (insn, CCGOCmode)
12039 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12041 switch (get_attr_type (insn))
12044 gcc_assert (operands[2] == const1_rtx);
12045 return "add{b}\t%0, %0";
12048 if (REG_P (operands[2]))
12049 return "sal{b}\t{%b2, %0|%0, %b2}";
12050 else if (operands[2] == const1_rtx
12051 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12052 return "sal{b}\t%0";
12054 return "sal{b}\t{%2, %0|%0, %2}";
12057 [(set (attr "type")
12058 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12060 (match_operand 0 "register_operand" ""))
12061 (match_operand 2 "const1_operand" ""))
12062 (const_string "alu")
12064 (const_string "ishift")))
12065 (set_attr "mode" "QI")])
12067 (define_insn "*ashlqi3_cconly"
12068 [(set (reg FLAGS_REG)
12070 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12071 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12073 (clobber (match_scratch:QI 0 "=q"))]
12074 "(optimize_function_for_size_p (cfun)
12075 || !TARGET_PARTIAL_FLAG_REG_STALL
12076 || (operands[2] == const1_rtx
12078 || TARGET_DOUBLE_WITH_ADD)))
12079 && ix86_match_ccmode (insn, CCGOCmode)
12080 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12082 switch (get_attr_type (insn))
12085 gcc_assert (operands[2] == const1_rtx);
12086 return "add{b}\t%0, %0";
12089 if (REG_P (operands[2]))
12090 return "sal{b}\t{%b2, %0|%0, %b2}";
12091 else if (operands[2] == const1_rtx
12092 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12093 return "sal{b}\t%0";
12095 return "sal{b}\t{%2, %0|%0, %2}";
12098 [(set (attr "type")
12099 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12101 (match_operand 0 "register_operand" ""))
12102 (match_operand 2 "const1_operand" ""))
12103 (const_string "alu")
12105 (const_string "ishift")))
12106 (set_attr "mode" "QI")])
12108 ;; See comment above `ashldi3' about how this works.
12110 (define_expand "ashrti3"
12111 [(set (match_operand:TI 0 "register_operand" "")
12112 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12113 (match_operand:QI 2 "nonmemory_operand" "")))]
12115 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12117 (define_insn "*ashrti3_1"
12118 [(set (match_operand:TI 0 "register_operand" "=r")
12119 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12120 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12121 (clobber (reg:CC FLAGS_REG))]
12124 [(set_attr "type" "multi")])
12127 [(match_scratch:DI 3 "r")
12128 (parallel [(set (match_operand:TI 0 "register_operand" "")
12129 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12130 (match_operand:QI 2 "nonmemory_operand" "")))
12131 (clobber (reg:CC FLAGS_REG))])
12135 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12138 [(set (match_operand:TI 0 "register_operand" "")
12139 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12140 (match_operand:QI 2 "nonmemory_operand" "")))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12143 ? epilogue_completed : reload_completed)"
12145 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12147 (define_insn "x86_64_shrd"
12148 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12149 (ior:DI (ashiftrt:DI (match_dup 0)
12150 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12151 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12152 (minus:QI (const_int 64) (match_dup 2)))))
12153 (clobber (reg:CC FLAGS_REG))]
12155 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12156 [(set_attr "type" "ishift")
12157 (set_attr "prefix_0f" "1")
12158 (set_attr "mode" "DI")
12159 (set_attr "athlon_decode" "vector")
12160 (set_attr "amdfam10_decode" "vector")])
12162 (define_expand "ashrdi3"
12163 [(set (match_operand:DI 0 "shiftdi_operand" "")
12164 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12165 (match_operand:QI 2 "nonmemory_operand" "")))]
12167 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12169 (define_expand "x86_64_shift_adj_3"
12170 [(use (match_operand:DI 0 "register_operand" ""))
12171 (use (match_operand:DI 1 "register_operand" ""))
12172 (use (match_operand:QI 2 "register_operand" ""))]
12175 rtx label = gen_label_rtx ();
12178 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12180 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12181 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12182 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12183 gen_rtx_LABEL_REF (VOIDmode, label),
12185 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12186 JUMP_LABEL (tmp) = label;
12188 emit_move_insn (operands[0], operands[1]);
12189 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12191 emit_label (label);
12192 LABEL_NUSES (label) = 1;
12197 (define_insn "ashrdi3_63_rex64"
12198 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12199 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12200 (match_operand:DI 2 "const_int_operand" "i,i")))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_64BIT && INTVAL (operands[2]) == 63
12203 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12204 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12207 sar{q}\t{%2, %0|%0, %2}"
12208 [(set_attr "type" "imovx,ishift")
12209 (set_attr "prefix_0f" "0,*")
12210 (set_attr "length_immediate" "0,*")
12211 (set_attr "modrm" "0,1")
12212 (set_attr "mode" "DI")])
12214 (define_insn "*ashrdi3_1_one_bit_rex64"
12215 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12216 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" "")))
12218 (clobber (reg:CC FLAGS_REG))]
12220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:DI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrdi3_1_rex64"
12230 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12231 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12232 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12233 (clobber (reg:CC FLAGS_REG))]
12234 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12236 sar{q}\t{%2, %0|%0, %2}
12237 sar{q}\t{%b2, %0|%0, %b2}"
12238 [(set_attr "type" "ishift")
12239 (set_attr "mode" "DI")])
12241 ;; This pattern can't accept a variable shift count, since shifts by
12242 ;; zero don't affect the flags. We assume that shifts by constant
12243 ;; zero are optimized away.
12244 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12245 [(set (reg FLAGS_REG)
12247 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12248 (match_operand:QI 2 "const1_operand" ""))
12250 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12251 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12254 && ix86_match_ccmode (insn, CCGOCmode)
12255 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12257 [(set_attr "type" "ishift")
12258 (set (attr "length")
12259 (if_then_else (match_operand:DI 0 "register_operand" "")
12261 (const_string "*")))])
12263 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const1_operand" ""))
12269 (clobber (match_scratch:DI 0 "=r"))]
12271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12272 && ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275 [(set_attr "type" "ishift")
12276 (set_attr "length" "2")])
12278 ;; This pattern can't accept a variable shift count, since shifts by
12279 ;; zero don't affect the flags. We assume that shifts by constant
12280 ;; zero are optimized away.
12281 (define_insn "*ashrdi3_cmp_rex64"
12282 [(set (reg FLAGS_REG)
12284 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12285 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12287 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12288 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12290 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12291 && ix86_match_ccmode (insn, CCGOCmode)
12292 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12293 "sar{q}\t{%2, %0|%0, %2}"
12294 [(set_attr "type" "ishift")
12295 (set_attr "mode" "DI")])
12297 (define_insn "*ashrdi3_cconly_rex64"
12298 [(set (reg FLAGS_REG)
12300 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12301 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12303 (clobber (match_scratch:DI 0 "=r"))]
12305 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12306 && ix86_match_ccmode (insn, CCGOCmode)
12307 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12308 "sar{q}\t{%2, %0|%0, %2}"
12309 [(set_attr "type" "ishift")
12310 (set_attr "mode" "DI")])
12312 (define_insn "*ashrdi3_1"
12313 [(set (match_operand:DI 0 "register_operand" "=r")
12314 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12315 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12316 (clobber (reg:CC FLAGS_REG))]
12319 [(set_attr "type" "multi")])
12321 ;; By default we don't ask for a scratch register, because when DImode
12322 ;; values are manipulated, registers are already at a premium. But if
12323 ;; we have one handy, we won't turn it away.
12325 [(match_scratch:SI 3 "r")
12326 (parallel [(set (match_operand:DI 0 "register_operand" "")
12327 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12328 (match_operand:QI 2 "nonmemory_operand" "")))
12329 (clobber (reg:CC FLAGS_REG))])
12331 "!TARGET_64BIT && TARGET_CMOVE"
12333 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12336 [(set (match_operand:DI 0 "register_operand" "")
12337 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12338 (match_operand:QI 2 "nonmemory_operand" "")))
12339 (clobber (reg:CC FLAGS_REG))]
12340 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12341 ? epilogue_completed : reload_completed)"
12343 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12345 (define_insn "x86_shrd"
12346 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12347 (ior:SI (ashiftrt:SI (match_dup 0)
12348 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12349 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12350 (minus:QI (const_int 32) (match_dup 2)))))
12351 (clobber (reg:CC FLAGS_REG))]
12353 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12354 [(set_attr "type" "ishift")
12355 (set_attr "prefix_0f" "1")
12356 (set_attr "pent_pair" "np")
12357 (set_attr "mode" "SI")])
12359 (define_expand "x86_shift_adj_3"
12360 [(use (match_operand:SI 0 "register_operand" ""))
12361 (use (match_operand:SI 1 "register_operand" ""))
12362 (use (match_operand:QI 2 "register_operand" ""))]
12365 rtx label = gen_label_rtx ();
12368 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12370 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12371 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12372 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12373 gen_rtx_LABEL_REF (VOIDmode, label),
12375 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12376 JUMP_LABEL (tmp) = label;
12378 emit_move_insn (operands[0], operands[1]);
12379 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12381 emit_label (label);
12382 LABEL_NUSES (label) = 1;
12387 (define_expand "ashrsi3_31"
12388 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12389 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12390 (match_operand:SI 2 "const_int_operand" "i,i")))
12391 (clobber (reg:CC FLAGS_REG))])]
12394 (define_insn "*ashrsi3_31"
12395 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12396 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12397 (match_operand:SI 2 "const_int_operand" "i,i")))
12398 (clobber (reg:CC FLAGS_REG))]
12399 "INTVAL (operands[2]) == 31
12400 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12401 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12404 sar{l}\t{%2, %0|%0, %2}"
12405 [(set_attr "type" "imovx,ishift")
12406 (set_attr "prefix_0f" "0,*")
12407 (set_attr "length_immediate" "0,*")
12408 (set_attr "modrm" "0,1")
12409 (set_attr "mode" "SI")])
12411 (define_insn "*ashrsi3_31_zext"
12412 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12413 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12414 (match_operand:SI 2 "const_int_operand" "i,i"))))
12415 (clobber (reg:CC FLAGS_REG))]
12416 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12417 && INTVAL (operands[2]) == 31
12418 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12421 sar{l}\t{%2, %k0|%k0, %2}"
12422 [(set_attr "type" "imovx,ishift")
12423 (set_attr "prefix_0f" "0,*")
12424 (set_attr "length_immediate" "0,*")
12425 (set_attr "modrm" "0,1")
12426 (set_attr "mode" "SI")])
12428 (define_expand "ashrsi3"
12429 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12430 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12431 (match_operand:QI 2 "nonmemory_operand" "")))]
12433 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12435 (define_insn "*ashrsi3_1_one_bit"
12436 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12437 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12438 (match_operand:QI 2 "const1_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12441 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12443 [(set_attr "type" "ishift")
12444 (set (attr "length")
12445 (if_then_else (match_operand:SI 0 "register_operand" "")
12447 (const_string "*")))])
12449 (define_insn "*ashrsi3_1_one_bit_zext"
12450 [(set (match_operand:DI 0 "register_operand" "=r")
12451 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12452 (match_operand:QI 2 "const1_operand" ""))))
12453 (clobber (reg:CC FLAGS_REG))]
12455 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12456 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12458 [(set_attr "type" "ishift")
12459 (set_attr "length" "2")])
12461 (define_insn "*ashrsi3_1"
12462 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12463 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12464 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12468 sar{l}\t{%2, %0|%0, %2}
12469 sar{l}\t{%b2, %0|%0, %b2}"
12470 [(set_attr "type" "ishift")
12471 (set_attr "mode" "SI")])
12473 (define_insn "*ashrsi3_1_zext"
12474 [(set (match_operand:DI 0 "register_operand" "=r,r")
12475 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12476 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12477 (clobber (reg:CC FLAGS_REG))]
12478 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12480 sar{l}\t{%2, %k0|%k0, %2}
12481 sar{l}\t{%b2, %k0|%k0, %b2}"
12482 [(set_attr "type" "ishift")
12483 (set_attr "mode" "SI")])
12485 ;; This pattern can't accept a variable shift count, since shifts by
12486 ;; zero don't affect the flags. We assume that shifts by constant
12487 ;; zero are optimized away.
12488 (define_insn "*ashrsi3_one_bit_cmp"
12489 [(set (reg FLAGS_REG)
12491 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12492 (match_operand:QI 2 "const1_operand" ""))
12494 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12495 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12496 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497 && ix86_match_ccmode (insn, CCGOCmode)
12498 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12500 [(set_attr "type" "ishift")
12501 (set (attr "length")
12502 (if_then_else (match_operand:SI 0 "register_operand" "")
12504 (const_string "*")))])
12506 (define_insn "*ashrsi3_one_bit_cconly"
12507 [(set (reg FLAGS_REG)
12509 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12512 (clobber (match_scratch:SI 0 "=r"))]
12513 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12514 && ix86_match_ccmode (insn, CCGOCmode)
12515 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517 [(set_attr "type" "ishift")
12518 (set_attr "length" "2")])
12520 (define_insn "*ashrsi3_one_bit_cmp_zext"
12521 [(set (reg FLAGS_REG)
12523 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12524 (match_operand:QI 2 "const1_operand" ""))
12526 (set (match_operand:DI 0 "register_operand" "=r")
12527 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12529 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12530 && ix86_match_ccmode (insn, CCmode)
12531 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12533 [(set_attr "type" "ishift")
12534 (set_attr "length" "2")])
12536 ;; This pattern can't accept a variable shift count, since shifts by
12537 ;; zero don't affect the flags. We assume that shifts by constant
12538 ;; zero are optimized away.
12539 (define_insn "*ashrsi3_cmp"
12540 [(set (reg FLAGS_REG)
12542 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12543 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12545 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12546 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12547 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12548 && ix86_match_ccmode (insn, CCGOCmode)
12549 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12550 "sar{l}\t{%2, %0|%0, %2}"
12551 [(set_attr "type" "ishift")
12552 (set_attr "mode" "SI")])
12554 (define_insn "*ashrsi3_cconly"
12555 [(set (reg FLAGS_REG)
12557 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12560 (clobber (match_scratch:SI 0 "=r"))]
12561 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12562 && ix86_match_ccmode (insn, CCGOCmode)
12563 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12564 "sar{l}\t{%2, %0|%0, %2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "SI")])
12568 (define_insn "*ashrsi3_cmp_zext"
12569 [(set (reg FLAGS_REG)
12571 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12572 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12574 (set (match_operand:DI 0 "register_operand" "=r")
12575 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12577 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12578 && ix86_match_ccmode (insn, CCGOCmode)
12579 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12580 "sar{l}\t{%2, %k0|%k0, %2}"
12581 [(set_attr "type" "ishift")
12582 (set_attr "mode" "SI")])
12584 (define_expand "ashrhi3"
12585 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12586 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12587 (match_operand:QI 2 "nonmemory_operand" "")))]
12588 "TARGET_HIMODE_MATH"
12589 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12591 (define_insn "*ashrhi3_1_one_bit"
12592 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12594 (match_operand:QI 2 "const1_operand" "")))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12597 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12599 [(set_attr "type" "ishift")
12600 (set (attr "length")
12601 (if_then_else (match_operand 0 "register_operand" "")
12603 (const_string "*")))])
12605 (define_insn "*ashrhi3_1"
12606 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12607 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12608 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12609 (clobber (reg:CC FLAGS_REG))]
12610 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12612 sar{w}\t{%2, %0|%0, %2}
12613 sar{w}\t{%b2, %0|%0, %b2}"
12614 [(set_attr "type" "ishift")
12615 (set_attr "mode" "HI")])
12617 ;; This pattern can't accept a variable shift count, since shifts by
12618 ;; zero don't affect the flags. We assume that shifts by constant
12619 ;; zero are optimized away.
12620 (define_insn "*ashrhi3_one_bit_cmp"
12621 [(set (reg FLAGS_REG)
12623 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624 (match_operand:QI 2 "const1_operand" ""))
12626 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12627 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12628 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12629 && ix86_match_ccmode (insn, CCGOCmode)
12630 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12632 [(set_attr "type" "ishift")
12633 (set (attr "length")
12634 (if_then_else (match_operand 0 "register_operand" "")
12636 (const_string "*")))])
12638 (define_insn "*ashrhi3_one_bit_cconly"
12639 [(set (reg FLAGS_REG)
12641 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12642 (match_operand:QI 2 "const1_operand" ""))
12644 (clobber (match_scratch:HI 0 "=r"))]
12645 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12646 && ix86_match_ccmode (insn, CCGOCmode)
12647 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12649 [(set_attr "type" "ishift")
12650 (set_attr "length" "2")])
12652 ;; This pattern can't accept a variable shift count, since shifts by
12653 ;; zero don't affect the flags. We assume that shifts by constant
12654 ;; zero are optimized away.
12655 (define_insn "*ashrhi3_cmp"
12656 [(set (reg FLAGS_REG)
12658 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12659 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12661 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12662 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12663 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12664 && ix86_match_ccmode (insn, CCGOCmode)
12665 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12666 "sar{w}\t{%2, %0|%0, %2}"
12667 [(set_attr "type" "ishift")
12668 (set_attr "mode" "HI")])
12670 (define_insn "*ashrhi3_cconly"
12671 [(set (reg FLAGS_REG)
12673 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12674 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12676 (clobber (match_scratch:HI 0 "=r"))]
12677 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12678 && ix86_match_ccmode (insn, CCGOCmode)
12679 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12680 "sar{w}\t{%2, %0|%0, %2}"
12681 [(set_attr "type" "ishift")
12682 (set_attr "mode" "HI")])
12684 (define_expand "ashrqi3"
12685 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12686 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12687 (match_operand:QI 2 "nonmemory_operand" "")))]
12688 "TARGET_QIMODE_MATH"
12689 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12691 (define_insn "*ashrqi3_1_one_bit"
12692 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12693 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12694 (match_operand:QI 2 "const1_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12696 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12697 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12699 [(set_attr "type" "ishift")
12700 (set (attr "length")
12701 (if_then_else (match_operand 0 "register_operand" "")
12703 (const_string "*")))])
12705 (define_insn "*ashrqi3_1_one_bit_slp"
12706 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12707 (ashiftrt:QI (match_dup 0)
12708 (match_operand:QI 1 "const1_operand" "")))
12709 (clobber (reg:CC FLAGS_REG))]
12710 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12711 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12712 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12714 [(set_attr "type" "ishift1")
12715 (set (attr "length")
12716 (if_then_else (match_operand 0 "register_operand" "")
12718 (const_string "*")))])
12720 (define_insn "*ashrqi3_1"
12721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12722 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12723 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12724 (clobber (reg:CC FLAGS_REG))]
12725 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12727 sar{b}\t{%2, %0|%0, %2}
12728 sar{b}\t{%b2, %0|%0, %b2}"
12729 [(set_attr "type" "ishift")
12730 (set_attr "mode" "QI")])
12732 (define_insn "*ashrqi3_1_slp"
12733 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12734 (ashiftrt:QI (match_dup 0)
12735 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12736 (clobber (reg:CC FLAGS_REG))]
12737 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12738 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12740 sar{b}\t{%1, %0|%0, %1}
12741 sar{b}\t{%b1, %0|%0, %b1}"
12742 [(set_attr "type" "ishift1")
12743 (set_attr "mode" "QI")])
12745 ;; This pattern can't accept a variable shift count, since shifts by
12746 ;; zero don't affect the flags. We assume that shifts by constant
12747 ;; zero are optimized away.
12748 (define_insn "*ashrqi3_one_bit_cmp"
12749 [(set (reg FLAGS_REG)
12751 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752 (match_operand:QI 2 "const1_operand" "I"))
12754 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12755 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12756 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12757 && ix86_match_ccmode (insn, CCGOCmode)
12758 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12760 [(set_attr "type" "ishift")
12761 (set (attr "length")
12762 (if_then_else (match_operand 0 "register_operand" "")
12764 (const_string "*")))])
12766 (define_insn "*ashrqi3_one_bit_cconly"
12767 [(set (reg FLAGS_REG)
12769 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12770 (match_operand:QI 2 "const1_operand" ""))
12772 (clobber (match_scratch:QI 0 "=q"))]
12773 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12774 && ix86_match_ccmode (insn, CCGOCmode)
12775 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12777 [(set_attr "type" "ishift")
12778 (set_attr "length" "2")])
12780 ;; This pattern can't accept a variable shift count, since shifts by
12781 ;; zero don't affect the flags. We assume that shifts by constant
12782 ;; zero are optimized away.
12783 (define_insn "*ashrqi3_cmp"
12784 [(set (reg FLAGS_REG)
12786 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12787 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12789 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12791 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12792 && ix86_match_ccmode (insn, CCGOCmode)
12793 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12794 "sar{b}\t{%2, %0|%0, %2}"
12795 [(set_attr "type" "ishift")
12796 (set_attr "mode" "QI")])
12798 (define_insn "*ashrqi3_cconly"
12799 [(set (reg FLAGS_REG)
12801 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12802 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12804 (clobber (match_scratch:QI 0 "=q"))]
12805 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12806 && ix86_match_ccmode (insn, CCGOCmode)
12807 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12808 "sar{b}\t{%2, %0|%0, %2}"
12809 [(set_attr "type" "ishift")
12810 (set_attr "mode" "QI")])
12813 ;; Logical shift instructions
12815 ;; See comment above `ashldi3' about how this works.
12817 (define_expand "lshrti3"
12818 [(set (match_operand:TI 0 "register_operand" "")
12819 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12820 (match_operand:QI 2 "nonmemory_operand" "")))]
12822 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12824 ;; This pattern must be defined before *lshrti3_1 to prevent
12825 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12827 (define_insn "*avx_lshrti3"
12828 [(set (match_operand:TI 0 "register_operand" "=x")
12829 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12830 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12833 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12834 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12836 [(set_attr "type" "sseishft")
12837 (set_attr "prefix" "vex")
12838 (set_attr "mode" "TI")])
12840 (define_insn "sse2_lshrti3"
12841 [(set (match_operand:TI 0 "register_operand" "=x")
12842 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12843 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12846 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12847 return "psrldq\t{%2, %0|%0, %2}";
12849 [(set_attr "type" "sseishft")
12850 (set_attr "prefix_data16" "1")
12851 (set_attr "mode" "TI")])
12853 (define_insn "*lshrti3_1"
12854 [(set (match_operand:TI 0 "register_operand" "=r")
12855 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12856 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12857 (clobber (reg:CC FLAGS_REG))]
12860 [(set_attr "type" "multi")])
12863 [(match_scratch:DI 3 "r")
12864 (parallel [(set (match_operand:TI 0 "register_operand" "")
12865 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12866 (match_operand:QI 2 "nonmemory_operand" "")))
12867 (clobber (reg:CC FLAGS_REG))])
12871 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12874 [(set (match_operand:TI 0 "register_operand" "")
12875 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12876 (match_operand:QI 2 "nonmemory_operand" "")))
12877 (clobber (reg:CC FLAGS_REG))]
12878 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12879 ? epilogue_completed : reload_completed)"
12881 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12883 (define_expand "lshrdi3"
12884 [(set (match_operand:DI 0 "shiftdi_operand" "")
12885 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12886 (match_operand:QI 2 "nonmemory_operand" "")))]
12888 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12890 (define_insn "*lshrdi3_1_one_bit_rex64"
12891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12892 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12893 (match_operand:QI 2 "const1_operand" "")))
12894 (clobber (reg:CC FLAGS_REG))]
12896 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899 [(set_attr "type" "ishift")
12900 (set (attr "length")
12901 (if_then_else (match_operand:DI 0 "register_operand" "")
12903 (const_string "*")))])
12905 (define_insn "*lshrdi3_1_rex64"
12906 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12907 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12908 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12909 (clobber (reg:CC FLAGS_REG))]
12910 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12912 shr{q}\t{%2, %0|%0, %2}
12913 shr{q}\t{%b2, %0|%0, %b2}"
12914 [(set_attr "type" "ishift")
12915 (set_attr "mode" "DI")])
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags. We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12921 [(set (reg FLAGS_REG)
12923 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12924 (match_operand:QI 2 "const1_operand" ""))
12926 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12927 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12930 && ix86_match_ccmode (insn, CCGOCmode)
12931 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12933 [(set_attr "type" "ishift")
12934 (set (attr "length")
12935 (if_then_else (match_operand:DI 0 "register_operand" "")
12937 (const_string "*")))])
12939 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12940 [(set (reg FLAGS_REG)
12942 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943 (match_operand:QI 2 "const1_operand" ""))
12945 (clobber (match_scratch:DI 0 "=r"))]
12947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12948 && ix86_match_ccmode (insn, CCGOCmode)
12949 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951 [(set_attr "type" "ishift")
12952 (set_attr "length" "2")])
12954 ;; This pattern can't accept a variable shift count, since shifts by
12955 ;; zero don't affect the flags. We assume that shifts by constant
12956 ;; zero are optimized away.
12957 (define_insn "*lshrdi3_cmp_rex64"
12958 [(set (reg FLAGS_REG)
12960 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12961 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12963 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12964 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12966 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12967 && ix86_match_ccmode (insn, CCGOCmode)
12968 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12969 "shr{q}\t{%2, %0|%0, %2}"
12970 [(set_attr "type" "ishift")
12971 (set_attr "mode" "DI")])
12973 (define_insn "*lshrdi3_cconly_rex64"
12974 [(set (reg FLAGS_REG)
12976 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12977 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12979 (clobber (match_scratch:DI 0 "=r"))]
12981 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12982 && ix86_match_ccmode (insn, CCGOCmode)
12983 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12984 "shr{q}\t{%2, %0|%0, %2}"
12985 [(set_attr "type" "ishift")
12986 (set_attr "mode" "DI")])
12988 (define_insn "*lshrdi3_1"
12989 [(set (match_operand:DI 0 "register_operand" "=r")
12990 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12991 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12992 (clobber (reg:CC FLAGS_REG))]
12995 [(set_attr "type" "multi")])
12997 ;; By default we don't ask for a scratch register, because when DImode
12998 ;; values are manipulated, registers are already at a premium. But if
12999 ;; we have one handy, we won't turn it away.
13001 [(match_scratch:SI 3 "r")
13002 (parallel [(set (match_operand:DI 0 "register_operand" "")
13003 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))])
13007 "!TARGET_64BIT && TARGET_CMOVE"
13009 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13012 [(set (match_operand:DI 0 "register_operand" "")
13013 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13014 (match_operand:QI 2 "nonmemory_operand" "")))
13015 (clobber (reg:CC FLAGS_REG))]
13016 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13017 ? epilogue_completed : reload_completed)"
13019 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13021 (define_expand "lshrsi3"
13022 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13023 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13024 (match_operand:QI 2 "nonmemory_operand" "")))]
13026 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13028 (define_insn "*lshrsi3_1_one_bit"
13029 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13030 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13031 (match_operand:QI 2 "const1_operand" "")))
13032 (clobber (reg:CC FLAGS_REG))]
13033 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13034 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13036 [(set_attr "type" "ishift")
13037 (set (attr "length")
13038 (if_then_else (match_operand:SI 0 "register_operand" "")
13040 (const_string "*")))])
13042 (define_insn "*lshrsi3_1_one_bit_zext"
13043 [(set (match_operand:DI 0 "register_operand" "=r")
13044 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13045 (match_operand:QI 2 "const1_operand" "")))
13046 (clobber (reg:CC FLAGS_REG))]
13048 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13049 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13051 [(set_attr "type" "ishift")
13052 (set_attr "length" "2")])
13054 (define_insn "*lshrsi3_1"
13055 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13056 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13057 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13061 shr{l}\t{%2, %0|%0, %2}
13062 shr{l}\t{%b2, %0|%0, %b2}"
13063 [(set_attr "type" "ishift")
13064 (set_attr "mode" "SI")])
13066 (define_insn "*lshrsi3_1_zext"
13067 [(set (match_operand:DI 0 "register_operand" "=r,r")
13069 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13070 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13071 (clobber (reg:CC FLAGS_REG))]
13072 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13074 shr{l}\t{%2, %k0|%k0, %2}
13075 shr{l}\t{%b2, %k0|%k0, %b2}"
13076 [(set_attr "type" "ishift")
13077 (set_attr "mode" "SI")])
13079 ;; This pattern can't accept a variable shift count, since shifts by
13080 ;; zero don't affect the flags. We assume that shifts by constant
13081 ;; zero are optimized away.
13082 (define_insn "*lshrsi3_one_bit_cmp"
13083 [(set (reg FLAGS_REG)
13085 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086 (match_operand:QI 2 "const1_operand" ""))
13088 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13089 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13090 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091 && ix86_match_ccmode (insn, CCGOCmode)
13092 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13094 [(set_attr "type" "ishift")
13095 (set (attr "length")
13096 (if_then_else (match_operand:SI 0 "register_operand" "")
13098 (const_string "*")))])
13100 (define_insn "*lshrsi3_one_bit_cconly"
13101 [(set (reg FLAGS_REG)
13103 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104 (match_operand:QI 2 "const1_operand" ""))
13106 (clobber (match_scratch:SI 0 "=r"))]
13107 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13108 && ix86_match_ccmode (insn, CCGOCmode)
13109 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111 [(set_attr "type" "ishift")
13112 (set_attr "length" "2")])
13114 (define_insn "*lshrsi3_cmp_one_bit_zext"
13115 [(set (reg FLAGS_REG)
13117 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13118 (match_operand:QI 2 "const1_operand" ""))
13120 (set (match_operand:DI 0 "register_operand" "=r")
13121 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13123 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13124 && ix86_match_ccmode (insn, CCGOCmode)
13125 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13127 [(set_attr "type" "ishift")
13128 (set_attr "length" "2")])
13130 ;; This pattern can't accept a variable shift count, since shifts by
13131 ;; zero don't affect the flags. We assume that shifts by constant
13132 ;; zero are optimized away.
13133 (define_insn "*lshrsi3_cmp"
13134 [(set (reg FLAGS_REG)
13136 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13137 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13139 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13140 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13141 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13142 && ix86_match_ccmode (insn, CCGOCmode)
13143 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13144 "shr{l}\t{%2, %0|%0, %2}"
13145 [(set_attr "type" "ishift")
13146 (set_attr "mode" "SI")])
13148 (define_insn "*lshrsi3_cconly"
13149 [(set (reg FLAGS_REG)
13151 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13152 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13154 (clobber (match_scratch:SI 0 "=r"))]
13155 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13156 && ix86_match_ccmode (insn, CCGOCmode)
13157 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13158 "shr{l}\t{%2, %0|%0, %2}"
13159 [(set_attr "type" "ishift")
13160 (set_attr "mode" "SI")])
13162 (define_insn "*lshrsi3_cmp_zext"
13163 [(set (reg FLAGS_REG)
13165 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13166 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13168 (set (match_operand:DI 0 "register_operand" "=r")
13169 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13171 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13172 && ix86_match_ccmode (insn, CCGOCmode)
13173 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13174 "shr{l}\t{%2, %k0|%k0, %2}"
13175 [(set_attr "type" "ishift")
13176 (set_attr "mode" "SI")])
13178 (define_expand "lshrhi3"
13179 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13180 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13181 (match_operand:QI 2 "nonmemory_operand" "")))]
13182 "TARGET_HIMODE_MATH"
13183 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13185 (define_insn "*lshrhi3_1_one_bit"
13186 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13188 (match_operand:QI 2 "const1_operand" "")))
13189 (clobber (reg:CC FLAGS_REG))]
13190 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13191 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13193 [(set_attr "type" "ishift")
13194 (set (attr "length")
13195 (if_then_else (match_operand 0 "register_operand" "")
13197 (const_string "*")))])
13199 (define_insn "*lshrhi3_1"
13200 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13201 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13206 shr{w}\t{%2, %0|%0, %2}
13207 shr{w}\t{%b2, %0|%0, %b2}"
13208 [(set_attr "type" "ishift")
13209 (set_attr "mode" "HI")])
13211 ;; This pattern can't accept a variable shift count, since shifts by
13212 ;; zero don't affect the flags. We assume that shifts by constant
13213 ;; zero are optimized away.
13214 (define_insn "*lshrhi3_one_bit_cmp"
13215 [(set (reg FLAGS_REG)
13217 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13218 (match_operand:QI 2 "const1_operand" ""))
13220 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13222 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13223 && ix86_match_ccmode (insn, CCGOCmode)
13224 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13226 [(set_attr "type" "ishift")
13227 (set (attr "length")
13228 (if_then_else (match_operand:SI 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*lshrhi3_one_bit_cconly"
13233 [(set (reg FLAGS_REG)
13235 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13236 (match_operand:QI 2 "const1_operand" ""))
13238 (clobber (match_scratch:HI 0 "=r"))]
13239 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13240 && ix86_match_ccmode (insn, CCGOCmode)
13241 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13243 [(set_attr "type" "ishift")
13244 (set_attr "length" "2")])
13246 ;; This pattern can't accept a variable shift count, since shifts by
13247 ;; zero don't affect the flags. We assume that shifts by constant
13248 ;; zero are optimized away.
13249 (define_insn "*lshrhi3_cmp"
13250 [(set (reg FLAGS_REG)
13252 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13253 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13255 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13256 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13257 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13258 && ix86_match_ccmode (insn, CCGOCmode)
13259 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13260 "shr{w}\t{%2, %0|%0, %2}"
13261 [(set_attr "type" "ishift")
13262 (set_attr "mode" "HI")])
13264 (define_insn "*lshrhi3_cconly"
13265 [(set (reg FLAGS_REG)
13267 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13270 (clobber (match_scratch:HI 0 "=r"))]
13271 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13272 && ix86_match_ccmode (insn, CCGOCmode)
13273 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13274 "shr{w}\t{%2, %0|%0, %2}"
13275 [(set_attr "type" "ishift")
13276 (set_attr "mode" "HI")])
13278 (define_expand "lshrqi3"
13279 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13280 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13281 (match_operand:QI 2 "nonmemory_operand" "")))]
13282 "TARGET_QIMODE_MATH"
13283 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13285 (define_insn "*lshrqi3_1_one_bit"
13286 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13287 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13288 (match_operand:QI 2 "const1_operand" "")))
13289 (clobber (reg:CC FLAGS_REG))]
13290 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13291 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13293 [(set_attr "type" "ishift")
13294 (set (attr "length")
13295 (if_then_else (match_operand 0 "register_operand" "")
13297 (const_string "*")))])
13299 (define_insn "*lshrqi3_1_one_bit_slp"
13300 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13301 (lshiftrt:QI (match_dup 0)
13302 (match_operand:QI 1 "const1_operand" "")))
13303 (clobber (reg:CC FLAGS_REG))]
13304 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13307 [(set_attr "type" "ishift1")
13308 (set (attr "length")
13309 (if_then_else (match_operand 0 "register_operand" "")
13311 (const_string "*")))])
13313 (define_insn "*lshrqi3_1"
13314 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13315 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13316 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13317 (clobber (reg:CC FLAGS_REG))]
13318 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13320 shr{b}\t{%2, %0|%0, %2}
13321 shr{b}\t{%b2, %0|%0, %b2}"
13322 [(set_attr "type" "ishift")
13323 (set_attr "mode" "QI")])
13325 (define_insn "*lshrqi3_1_slp"
13326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13327 (lshiftrt:QI (match_dup 0)
13328 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13329 (clobber (reg:CC FLAGS_REG))]
13330 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13331 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13333 shr{b}\t{%1, %0|%0, %1}
13334 shr{b}\t{%b1, %0|%0, %b1}"
13335 [(set_attr "type" "ishift1")
13336 (set_attr "mode" "QI")])
13338 ;; This pattern can't accept a variable shift count, since shifts by
13339 ;; zero don't affect the flags. We assume that shifts by constant
13340 ;; zero are optimized away.
13341 (define_insn "*lshrqi2_one_bit_cmp"
13342 [(set (reg FLAGS_REG)
13344 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13345 (match_operand:QI 2 "const1_operand" ""))
13347 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13348 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13349 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13350 && ix86_match_ccmode (insn, CCGOCmode)
13351 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13353 [(set_attr "type" "ishift")
13354 (set (attr "length")
13355 (if_then_else (match_operand:SI 0 "register_operand" "")
13357 (const_string "*")))])
13359 (define_insn "*lshrqi2_one_bit_cconly"
13360 [(set (reg FLAGS_REG)
13362 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13363 (match_operand:QI 2 "const1_operand" ""))
13365 (clobber (match_scratch:QI 0 "=q"))]
13366 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13367 && ix86_match_ccmode (insn, CCGOCmode)
13368 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13370 [(set_attr "type" "ishift")
13371 (set_attr "length" "2")])
13373 ;; This pattern can't accept a variable shift count, since shifts by
13374 ;; zero don't affect the flags. We assume that shifts by constant
13375 ;; zero are optimized away.
13376 (define_insn "*lshrqi2_cmp"
13377 [(set (reg FLAGS_REG)
13379 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13380 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13382 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13383 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13384 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13385 && ix86_match_ccmode (insn, CCGOCmode)
13386 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13387 "shr{b}\t{%2, %0|%0, %2}"
13388 [(set_attr "type" "ishift")
13389 (set_attr "mode" "QI")])
13391 (define_insn "*lshrqi2_cconly"
13392 [(set (reg FLAGS_REG)
13394 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13395 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13397 (clobber (match_scratch:QI 0 "=q"))]
13398 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13399 && ix86_match_ccmode (insn, CCGOCmode)
13400 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13401 "shr{b}\t{%2, %0|%0, %2}"
13402 [(set_attr "type" "ishift")
13403 (set_attr "mode" "QI")])
13405 ;; Rotate instructions
13407 (define_expand "rotldi3"
13408 [(set (match_operand:DI 0 "shiftdi_operand" "")
13409 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13410 (match_operand:QI 2 "nonmemory_operand" "")))]
13415 ix86_expand_binary_operator (ROTATE, DImode, operands);
13418 if (!const_1_to_31_operand (operands[2], VOIDmode))
13420 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13424 ;; Implement rotation using two double-precision shift instructions
13425 ;; and a scratch register.
13426 (define_insn_and_split "ix86_rotldi3"
13427 [(set (match_operand:DI 0 "register_operand" "=r")
13428 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13429 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13430 (clobber (reg:CC FLAGS_REG))
13431 (clobber (match_scratch:SI 3 "=&r"))]
13434 "&& reload_completed"
13435 [(set (match_dup 3) (match_dup 4))
13437 [(set (match_dup 4)
13438 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13439 (lshiftrt:SI (match_dup 5)
13440 (minus:QI (const_int 32) (match_dup 2)))))
13441 (clobber (reg:CC FLAGS_REG))])
13443 [(set (match_dup 5)
13444 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13445 (lshiftrt:SI (match_dup 3)
13446 (minus:QI (const_int 32) (match_dup 2)))))
13447 (clobber (reg:CC FLAGS_REG))])]
13448 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13450 (define_insn "*rotlsi3_1_one_bit_rex64"
13451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13452 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13453 (match_operand:QI 2 "const1_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13456 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13459 [(set_attr "type" "rotate")
13460 (set (attr "length")
13461 (if_then_else (match_operand:DI 0 "register_operand" "")
13463 (const_string "*")))])
13465 (define_insn "*rotldi3_1_rex64"
13466 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13467 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13468 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13469 (clobber (reg:CC FLAGS_REG))]
13470 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13472 rol{q}\t{%2, %0|%0, %2}
13473 rol{q}\t{%b2, %0|%0, %b2}"
13474 [(set_attr "type" "rotate")
13475 (set_attr "mode" "DI")])
13477 (define_expand "rotlsi3"
13478 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13479 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13480 (match_operand:QI 2 "nonmemory_operand" "")))]
13482 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13484 (define_insn "*rotlsi3_1_one_bit"
13485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13486 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13487 (match_operand:QI 2 "const1_operand" "")))
13488 (clobber (reg:CC FLAGS_REG))]
13489 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13490 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13492 [(set_attr "type" "rotate")
13493 (set (attr "length")
13494 (if_then_else (match_operand:SI 0 "register_operand" "")
13496 (const_string "*")))])
13498 (define_insn "*rotlsi3_1_one_bit_zext"
13499 [(set (match_operand:DI 0 "register_operand" "=r")
13501 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13502 (match_operand:QI 2 "const1_operand" ""))))
13503 (clobber (reg:CC FLAGS_REG))]
13505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13506 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13508 [(set_attr "type" "rotate")
13509 (set_attr "length" "2")])
13511 (define_insn "*rotlsi3_1"
13512 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13513 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13514 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13515 (clobber (reg:CC FLAGS_REG))]
13516 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13518 rol{l}\t{%2, %0|%0, %2}
13519 rol{l}\t{%b2, %0|%0, %b2}"
13520 [(set_attr "type" "rotate")
13521 (set_attr "mode" "SI")])
13523 (define_insn "*rotlsi3_1_zext"
13524 [(set (match_operand:DI 0 "register_operand" "=r,r")
13526 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13527 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13528 (clobber (reg:CC FLAGS_REG))]
13529 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13531 rol{l}\t{%2, %k0|%k0, %2}
13532 rol{l}\t{%b2, %k0|%k0, %b2}"
13533 [(set_attr "type" "rotate")
13534 (set_attr "mode" "SI")])
13536 (define_expand "rotlhi3"
13537 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13538 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13539 (match_operand:QI 2 "nonmemory_operand" "")))]
13540 "TARGET_HIMODE_MATH"
13541 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13543 (define_insn "*rotlhi3_1_one_bit"
13544 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13545 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13546 (match_operand:QI 2 "const1_operand" "")))
13547 (clobber (reg:CC FLAGS_REG))]
13548 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13549 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13551 [(set_attr "type" "rotate")
13552 (set (attr "length")
13553 (if_then_else (match_operand 0 "register_operand" "")
13555 (const_string "*")))])
13557 (define_insn "*rotlhi3_1"
13558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13559 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13561 (clobber (reg:CC FLAGS_REG))]
13562 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13564 rol{w}\t{%2, %0|%0, %2}
13565 rol{w}\t{%b2, %0|%0, %b2}"
13566 [(set_attr "type" "rotate")
13567 (set_attr "mode" "HI")])
13570 [(set (match_operand:HI 0 "register_operand" "")
13571 (rotate:HI (match_dup 0) (const_int 8)))
13572 (clobber (reg:CC FLAGS_REG))]
13574 [(parallel [(set (strict_low_part (match_dup 0))
13575 (bswap:HI (match_dup 0)))
13576 (clobber (reg:CC FLAGS_REG))])]
13579 (define_expand "rotlqi3"
13580 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13581 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13582 (match_operand:QI 2 "nonmemory_operand" "")))]
13583 "TARGET_QIMODE_MATH"
13584 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13586 (define_insn "*rotlqi3_1_one_bit_slp"
13587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13588 (rotate:QI (match_dup 0)
13589 (match_operand:QI 1 "const1_operand" "")))
13590 (clobber (reg:CC FLAGS_REG))]
13591 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13592 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13594 [(set_attr "type" "rotate1")
13595 (set (attr "length")
13596 (if_then_else (match_operand 0 "register_operand" "")
13598 (const_string "*")))])
13600 (define_insn "*rotlqi3_1_one_bit"
13601 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13602 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13603 (match_operand:QI 2 "const1_operand" "")))
13604 (clobber (reg:CC FLAGS_REG))]
13605 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13606 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13608 [(set_attr "type" "rotate")
13609 (set (attr "length")
13610 (if_then_else (match_operand 0 "register_operand" "")
13612 (const_string "*")))])
13614 (define_insn "*rotlqi3_1_slp"
13615 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13616 (rotate:QI (match_dup 0)
13617 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13618 (clobber (reg:CC FLAGS_REG))]
13619 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13622 rol{b}\t{%1, %0|%0, %1}
13623 rol{b}\t{%b1, %0|%0, %b1}"
13624 [(set_attr "type" "rotate1")
13625 (set_attr "mode" "QI")])
13627 (define_insn "*rotlqi3_1"
13628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13629 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13630 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13631 (clobber (reg:CC FLAGS_REG))]
13632 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13634 rol{b}\t{%2, %0|%0, %2}
13635 rol{b}\t{%b2, %0|%0, %b2}"
13636 [(set_attr "type" "rotate")
13637 (set_attr "mode" "QI")])
13639 (define_expand "rotrdi3"
13640 [(set (match_operand:DI 0 "shiftdi_operand" "")
13641 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13642 (match_operand:QI 2 "nonmemory_operand" "")))]
13647 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13650 if (!const_1_to_31_operand (operands[2], VOIDmode))
13652 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13656 ;; Implement rotation using two double-precision shift instructions
13657 ;; and a scratch register.
13658 (define_insn_and_split "ix86_rotrdi3"
13659 [(set (match_operand:DI 0 "register_operand" "=r")
13660 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13661 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13662 (clobber (reg:CC FLAGS_REG))
13663 (clobber (match_scratch:SI 3 "=&r"))]
13666 "&& reload_completed"
13667 [(set (match_dup 3) (match_dup 4))
13669 [(set (match_dup 4)
13670 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13671 (ashift:SI (match_dup 5)
13672 (minus:QI (const_int 32) (match_dup 2)))))
13673 (clobber (reg:CC FLAGS_REG))])
13675 [(set (match_dup 5)
13676 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13677 (ashift:SI (match_dup 3)
13678 (minus:QI (const_int 32) (match_dup 2)))))
13679 (clobber (reg:CC FLAGS_REG))])]
13680 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13682 (define_insn "*rotrdi3_1_one_bit_rex64"
13683 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13684 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13685 (match_operand:QI 2 "const1_operand" "")))
13686 (clobber (reg:CC FLAGS_REG))]
13688 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13691 [(set_attr "type" "rotate")
13692 (set (attr "length")
13693 (if_then_else (match_operand:DI 0 "register_operand" "")
13695 (const_string "*")))])
13697 (define_insn "*rotrdi3_1_rex64"
13698 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13699 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13700 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13701 (clobber (reg:CC FLAGS_REG))]
13702 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13704 ror{q}\t{%2, %0|%0, %2}
13705 ror{q}\t{%b2, %0|%0, %b2}"
13706 [(set_attr "type" "rotate")
13707 (set_attr "mode" "DI")])
13709 (define_expand "rotrsi3"
13710 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13711 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13712 (match_operand:QI 2 "nonmemory_operand" "")))]
13714 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13716 (define_insn "*rotrsi3_1_one_bit"
13717 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13718 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13719 (match_operand:QI 2 "const1_operand" "")))
13720 (clobber (reg:CC FLAGS_REG))]
13721 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13722 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13724 [(set_attr "type" "rotate")
13725 (set (attr "length")
13726 (if_then_else (match_operand:SI 0 "register_operand" "")
13728 (const_string "*")))])
13730 (define_insn "*rotrsi3_1_one_bit_zext"
13731 [(set (match_operand:DI 0 "register_operand" "=r")
13733 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13734 (match_operand:QI 2 "const1_operand" ""))))
13735 (clobber (reg:CC FLAGS_REG))]
13737 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13738 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13740 [(set_attr "type" "rotate")
13741 (set (attr "length")
13742 (if_then_else (match_operand:SI 0 "register_operand" "")
13744 (const_string "*")))])
13746 (define_insn "*rotrsi3_1"
13747 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13748 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13750 (clobber (reg:CC FLAGS_REG))]
13751 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13753 ror{l}\t{%2, %0|%0, %2}
13754 ror{l}\t{%b2, %0|%0, %b2}"
13755 [(set_attr "type" "rotate")
13756 (set_attr "mode" "SI")])
13758 (define_insn "*rotrsi3_1_zext"
13759 [(set (match_operand:DI 0 "register_operand" "=r,r")
13761 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13762 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13766 ror{l}\t{%2, %k0|%k0, %2}
13767 ror{l}\t{%b2, %k0|%k0, %b2}"
13768 [(set_attr "type" "rotate")
13769 (set_attr "mode" "SI")])
13771 (define_expand "rotrhi3"
13772 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13773 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13774 (match_operand:QI 2 "nonmemory_operand" "")))]
13775 "TARGET_HIMODE_MATH"
13776 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13778 (define_insn "*rotrhi3_one_bit"
13779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13780 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13781 (match_operand:QI 2 "const1_operand" "")))
13782 (clobber (reg:CC FLAGS_REG))]
13783 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13784 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13786 [(set_attr "type" "rotate")
13787 (set (attr "length")
13788 (if_then_else (match_operand 0 "register_operand" "")
13790 (const_string "*")))])
13792 (define_insn "*rotrhi3_1"
13793 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13794 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13795 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13796 (clobber (reg:CC FLAGS_REG))]
13797 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13799 ror{w}\t{%2, %0|%0, %2}
13800 ror{w}\t{%b2, %0|%0, %b2}"
13801 [(set_attr "type" "rotate")
13802 (set_attr "mode" "HI")])
13805 [(set (match_operand:HI 0 "register_operand" "")
13806 (rotatert:HI (match_dup 0) (const_int 8)))
13807 (clobber (reg:CC FLAGS_REG))]
13809 [(parallel [(set (strict_low_part (match_dup 0))
13810 (bswap:HI (match_dup 0)))
13811 (clobber (reg:CC FLAGS_REG))])]
13814 (define_expand "rotrqi3"
13815 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13816 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13817 (match_operand:QI 2 "nonmemory_operand" "")))]
13818 "TARGET_QIMODE_MATH"
13819 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13821 (define_insn "*rotrqi3_1_one_bit"
13822 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13823 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13824 (match_operand:QI 2 "const1_operand" "")))
13825 (clobber (reg:CC FLAGS_REG))]
13826 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13827 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13829 [(set_attr "type" "rotate")
13830 (set (attr "length")
13831 (if_then_else (match_operand 0 "register_operand" "")
13833 (const_string "*")))])
13835 (define_insn "*rotrqi3_1_one_bit_slp"
13836 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13837 (rotatert:QI (match_dup 0)
13838 (match_operand:QI 1 "const1_operand" "")))
13839 (clobber (reg:CC FLAGS_REG))]
13840 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13843 [(set_attr "type" "rotate1")
13844 (set (attr "length")
13845 (if_then_else (match_operand 0 "register_operand" "")
13847 (const_string "*")))])
13849 (define_insn "*rotrqi3_1"
13850 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13851 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13852 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13853 (clobber (reg:CC FLAGS_REG))]
13854 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13856 ror{b}\t{%2, %0|%0, %2}
13857 ror{b}\t{%b2, %0|%0, %b2}"
13858 [(set_attr "type" "rotate")
13859 (set_attr "mode" "QI")])
13861 (define_insn "*rotrqi3_1_slp"
13862 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13863 (rotatert:QI (match_dup 0)
13864 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13865 (clobber (reg:CC FLAGS_REG))]
13866 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13867 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13869 ror{b}\t{%1, %0|%0, %1}
13870 ror{b}\t{%b1, %0|%0, %b1}"
13871 [(set_attr "type" "rotate1")
13872 (set_attr "mode" "QI")])
13874 ;; Bit set / bit test instructions
13876 (define_expand "extv"
13877 [(set (match_operand:SI 0 "register_operand" "")
13878 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13879 (match_operand:SI 2 "const8_operand" "")
13880 (match_operand:SI 3 "const8_operand" "")))]
13883 /* Handle extractions from %ah et al. */
13884 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13887 /* From mips.md: extract_bit_field doesn't verify that our source
13888 matches the predicate, so check it again here. */
13889 if (! ext_register_operand (operands[1], VOIDmode))
13893 (define_expand "extzv"
13894 [(set (match_operand:SI 0 "register_operand" "")
13895 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13896 (match_operand:SI 2 "const8_operand" "")
13897 (match_operand:SI 3 "const8_operand" "")))]
13900 /* Handle extractions from %ah et al. */
13901 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13904 /* From mips.md: extract_bit_field doesn't verify that our source
13905 matches the predicate, so check it again here. */
13906 if (! ext_register_operand (operands[1], VOIDmode))
13910 (define_expand "insv"
13911 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13912 (match_operand 1 "const8_operand" "")
13913 (match_operand 2 "const8_operand" ""))
13914 (match_operand 3 "register_operand" ""))]
13917 /* Handle insertions to %ah et al. */
13918 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13921 /* From mips.md: insert_bit_field doesn't verify that our source
13922 matches the predicate, so check it again here. */
13923 if (! ext_register_operand (operands[0], VOIDmode))
13927 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13929 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13934 ;; %%% bts, btr, btc, bt.
13935 ;; In general these instructions are *slow* when applied to memory,
13936 ;; since they enforce atomic operation. When applied to registers,
13937 ;; it depends on the cpu implementation. They're never faster than
13938 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13939 ;; no point. But in 64-bit, we can't hold the relevant immediates
13940 ;; within the instruction itself, so operating on bits in the high
13941 ;; 32-bits of a register becomes easier.
13943 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13944 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13945 ;; negdf respectively, so they can never be disabled entirely.
13947 (define_insn "*btsq"
13948 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13950 (match_operand:DI 1 "const_0_to_63_operand" ""))
13952 (clobber (reg:CC FLAGS_REG))]
13953 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13954 "bts{q}\t{%1, %0|%0, %1}"
13955 [(set_attr "type" "alu1")])
13957 (define_insn "*btrq"
13958 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13960 (match_operand:DI 1 "const_0_to_63_operand" ""))
13962 (clobber (reg:CC FLAGS_REG))]
13963 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13964 "btr{q}\t{%1, %0|%0, %1}"
13965 [(set_attr "type" "alu1")])
13967 (define_insn "*btcq"
13968 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13970 (match_operand:DI 1 "const_0_to_63_operand" ""))
13971 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13972 (clobber (reg:CC FLAGS_REG))]
13973 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13974 "btc{q}\t{%1, %0|%0, %1}"
13975 [(set_attr "type" "alu1")])
13977 ;; Allow Nocona to avoid these instructions if a register is available.
13980 [(match_scratch:DI 2 "r")
13981 (parallel [(set (zero_extract:DI
13982 (match_operand:DI 0 "register_operand" "")
13984 (match_operand:DI 1 "const_0_to_63_operand" ""))
13986 (clobber (reg:CC FLAGS_REG))])]
13987 "TARGET_64BIT && !TARGET_USE_BT"
13990 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13993 if (HOST_BITS_PER_WIDE_INT >= 64)
13994 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13995 else if (i < HOST_BITS_PER_WIDE_INT)
13996 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13998 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14000 op1 = immed_double_const (lo, hi, DImode);
14003 emit_move_insn (operands[2], op1);
14007 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14012 [(match_scratch:DI 2 "r")
14013 (parallel [(set (zero_extract:DI
14014 (match_operand:DI 0 "register_operand" "")
14016 (match_operand:DI 1 "const_0_to_63_operand" ""))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 "TARGET_64BIT && !TARGET_USE_BT"
14022 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14025 if (HOST_BITS_PER_WIDE_INT >= 64)
14026 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027 else if (i < HOST_BITS_PER_WIDE_INT)
14028 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14030 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14032 op1 = immed_double_const (~lo, ~hi, DImode);
14035 emit_move_insn (operands[2], op1);
14039 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14044 [(match_scratch:DI 2 "r")
14045 (parallel [(set (zero_extract:DI
14046 (match_operand:DI 0 "register_operand" "")
14048 (match_operand:DI 1 "const_0_to_63_operand" ""))
14049 (not:DI (zero_extract:DI
14050 (match_dup 0) (const_int 1) (match_dup 1))))
14051 (clobber (reg:CC FLAGS_REG))])]
14052 "TARGET_64BIT && !TARGET_USE_BT"
14055 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14058 if (HOST_BITS_PER_WIDE_INT >= 64)
14059 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14060 else if (i < HOST_BITS_PER_WIDE_INT)
14061 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14063 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14065 op1 = immed_double_const (lo, hi, DImode);
14068 emit_move_insn (operands[2], op1);
14072 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14076 (define_insn "*btdi_rex64"
14077 [(set (reg:CCC FLAGS_REG)
14080 (match_operand:DI 0 "register_operand" "r")
14082 (match_operand:DI 1 "nonmemory_operand" "rN"))
14084 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14085 "bt{q}\t{%1, %0|%0, %1}"
14086 [(set_attr "type" "alu1")])
14088 (define_insn "*btsi"
14089 [(set (reg:CCC FLAGS_REG)
14092 (match_operand:SI 0 "register_operand" "r")
14094 (match_operand:SI 1 "nonmemory_operand" "rN"))
14096 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14097 "bt{l}\t{%1, %0|%0, %1}"
14098 [(set_attr "type" "alu1")])
14100 ;; Store-flag instructions.
14102 ;; For all sCOND expanders, also expand the compare or test insn that
14103 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14105 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14106 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14107 ;; way, which can later delete the movzx if only QImode is needed.
14109 (define_expand "s<code>"
14110 [(set (match_operand:QI 0 "register_operand" "")
14111 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14113 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14115 (define_expand "s<code>"
14116 [(set (match_operand:QI 0 "register_operand" "")
14117 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14118 "TARGET_80387 || TARGET_SSE"
14119 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14121 (define_insn "*setcc_1"
14122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14123 (match_operator:QI 1 "ix86_comparison_operator"
14124 [(reg FLAGS_REG) (const_int 0)]))]
14127 [(set_attr "type" "setcc")
14128 (set_attr "mode" "QI")])
14130 (define_insn "*setcc_2"
14131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14132 (match_operator:QI 1 "ix86_comparison_operator"
14133 [(reg FLAGS_REG) (const_int 0)]))]
14136 [(set_attr "type" "setcc")
14137 (set_attr "mode" "QI")])
14139 ;; In general it is not safe to assume too much about CCmode registers,
14140 ;; so simplify-rtx stops when it sees a second one. Under certain
14141 ;; conditions this is safe on x86, so help combine not create
14148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14149 (ne:QI (match_operator 1 "ix86_comparison_operator"
14150 [(reg FLAGS_REG) (const_int 0)])
14153 [(set (match_dup 0) (match_dup 1))]
14155 PUT_MODE (operands[1], QImode);
14159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14160 (ne:QI (match_operator 1 "ix86_comparison_operator"
14161 [(reg FLAGS_REG) (const_int 0)])
14164 [(set (match_dup 0) (match_dup 1))]
14166 PUT_MODE (operands[1], QImode);
14170 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14171 (eq:QI (match_operator 1 "ix86_comparison_operator"
14172 [(reg FLAGS_REG) (const_int 0)])
14175 [(set (match_dup 0) (match_dup 1))]
14177 rtx new_op1 = copy_rtx (operands[1]);
14178 operands[1] = new_op1;
14179 PUT_MODE (new_op1, QImode);
14180 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14181 GET_MODE (XEXP (new_op1, 0))));
14183 /* Make sure that (a) the CCmode we have for the flags is strong
14184 enough for the reversed compare or (b) we have a valid FP compare. */
14185 if (! ix86_comparison_operator (new_op1, VOIDmode))
14190 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14191 (eq:QI (match_operator 1 "ix86_comparison_operator"
14192 [(reg FLAGS_REG) (const_int 0)])
14195 [(set (match_dup 0) (match_dup 1))]
14197 rtx new_op1 = copy_rtx (operands[1]);
14198 operands[1] = new_op1;
14199 PUT_MODE (new_op1, QImode);
14200 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14201 GET_MODE (XEXP (new_op1, 0))));
14203 /* Make sure that (a) the CCmode we have for the flags is strong
14204 enough for the reversed compare or (b) we have a valid FP compare. */
14205 if (! ix86_comparison_operator (new_op1, VOIDmode))
14209 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14210 ;; subsequent logical operations are used to imitate conditional moves.
14211 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14214 (define_insn "*avx_setcc<mode>"
14215 [(set (match_operand:MODEF 0 "register_operand" "=x")
14216 (match_operator:MODEF 1 "avx_comparison_float_operator"
14217 [(match_operand:MODEF 2 "register_operand" "x")
14218 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14220 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14221 [(set_attr "type" "ssecmp")
14222 (set_attr "prefix" "vex")
14223 (set_attr "mode" "<MODE>")])
14225 (define_insn "*sse_setcc<mode>"
14226 [(set (match_operand:MODEF 0 "register_operand" "=x")
14227 (match_operator:MODEF 1 "sse_comparison_operator"
14228 [(match_operand:MODEF 2 "register_operand" "0")
14229 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14230 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14231 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14232 [(set_attr "type" "ssecmp")
14233 (set_attr "mode" "<MODE>")])
14235 (define_insn "*sse5_setcc<mode>"
14236 [(set (match_operand:MODEF 0 "register_operand" "=x")
14237 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14238 [(match_operand:MODEF 2 "register_operand" "x")
14239 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14241 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14242 [(set_attr "type" "sse4arg")
14243 (set_attr "mode" "<MODE>")])
14246 ;; Basic conditional jump instructions.
14247 ;; We ignore the overflow flag for signed branch instructions.
14249 ;; For all bCOND expanders, also expand the compare or test insn that
14250 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14252 (define_expand "b<code>"
14254 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14256 (label_ref (match_operand 0 ""))
14259 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14261 (define_expand "b<code>"
14263 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14265 (label_ref (match_operand 0 ""))
14267 "TARGET_80387 || TARGET_SSE_MATH"
14268 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14270 (define_insn "*jcc_1"
14272 (if_then_else (match_operator 1 "ix86_comparison_operator"
14273 [(reg FLAGS_REG) (const_int 0)])
14274 (label_ref (match_operand 0 "" ""))
14278 [(set_attr "type" "ibr")
14279 (set_attr "modrm" "0")
14280 (set (attr "length")
14281 (if_then_else (and (ge (minus (match_dup 0) (pc))
14283 (lt (minus (match_dup 0) (pc))
14288 (define_insn "*jcc_2"
14290 (if_then_else (match_operator 1 "ix86_comparison_operator"
14291 [(reg FLAGS_REG) (const_int 0)])
14293 (label_ref (match_operand 0 "" ""))))]
14296 [(set_attr "type" "ibr")
14297 (set_attr "modrm" "0")
14298 (set (attr "length")
14299 (if_then_else (and (ge (minus (match_dup 0) (pc))
14301 (lt (minus (match_dup 0) (pc))
14306 ;; In general it is not safe to assume too much about CCmode registers,
14307 ;; so simplify-rtx stops when it sees a second one. Under certain
14308 ;; conditions this is safe on x86, so help combine not create
14316 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14317 [(reg FLAGS_REG) (const_int 0)])
14319 (label_ref (match_operand 1 "" ""))
14323 (if_then_else (match_dup 0)
14324 (label_ref (match_dup 1))
14327 PUT_MODE (operands[0], VOIDmode);
14332 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14333 [(reg FLAGS_REG) (const_int 0)])
14335 (label_ref (match_operand 1 "" ""))
14339 (if_then_else (match_dup 0)
14340 (label_ref (match_dup 1))
14343 rtx new_op0 = copy_rtx (operands[0]);
14344 operands[0] = new_op0;
14345 PUT_MODE (new_op0, VOIDmode);
14346 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14347 GET_MODE (XEXP (new_op0, 0))));
14349 /* Make sure that (a) the CCmode we have for the flags is strong
14350 enough for the reversed compare or (b) we have a valid FP compare. */
14351 if (! ix86_comparison_operator (new_op0, VOIDmode))
14355 ;; zero_extend in SImode is correct, since this is what combine pass
14356 ;; generates from shift insn with QImode operand. Actually, the mode of
14357 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14358 ;; appropriate modulo of the bit offset value.
14360 (define_insn_and_split "*jcc_btdi_rex64"
14362 (if_then_else (match_operator 0 "bt_comparison_operator"
14364 (match_operand:DI 1 "register_operand" "r")
14367 (match_operand:QI 2 "register_operand" "r")))
14369 (label_ref (match_operand 3 "" ""))
14371 (clobber (reg:CC FLAGS_REG))]
14372 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14375 [(set (reg:CCC FLAGS_REG)
14383 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384 (label_ref (match_dup 3))
14387 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14389 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14392 ;; avoid useless masking of bit offset operand
14393 (define_insn_and_split "*jcc_btdi_mask_rex64"
14395 (if_then_else (match_operator 0 "bt_comparison_operator"
14397 (match_operand:DI 1 "register_operand" "r")
14400 (match_operand:SI 2 "register_operand" "r")
14401 (match_operand:SI 3 "const_int_operand" "n")))])
14402 (label_ref (match_operand 4 "" ""))
14404 (clobber (reg:CC FLAGS_REG))]
14405 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14406 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14409 [(set (reg:CCC FLAGS_REG)
14417 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14418 (label_ref (match_dup 4))
14421 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14423 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14426 (define_insn_and_split "*jcc_btsi"
14428 (if_then_else (match_operator 0 "bt_comparison_operator"
14430 (match_operand:SI 1 "register_operand" "r")
14433 (match_operand:QI 2 "register_operand" "r")))
14435 (label_ref (match_operand 3 "" ""))
14437 (clobber (reg:CC FLAGS_REG))]
14438 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14441 [(set (reg:CCC FLAGS_REG)
14449 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450 (label_ref (match_dup 3))
14453 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14455 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14458 ;; avoid useless masking of bit offset operand
14459 (define_insn_and_split "*jcc_btsi_mask"
14461 (if_then_else (match_operator 0 "bt_comparison_operator"
14463 (match_operand:SI 1 "register_operand" "r")
14466 (match_operand:SI 2 "register_operand" "r")
14467 (match_operand:SI 3 "const_int_operand" "n")))])
14468 (label_ref (match_operand 4 "" ""))
14470 (clobber (reg:CC FLAGS_REG))]
14471 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14472 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14475 [(set (reg:CCC FLAGS_REG)
14483 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14484 (label_ref (match_dup 4))
14486 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14488 (define_insn_and_split "*jcc_btsi_1"
14490 (if_then_else (match_operator 0 "bt_comparison_operator"
14493 (match_operand:SI 1 "register_operand" "r")
14494 (match_operand:QI 2 "register_operand" "r"))
14497 (label_ref (match_operand 3 "" ""))
14499 (clobber (reg:CC FLAGS_REG))]
14500 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14503 [(set (reg:CCC FLAGS_REG)
14511 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14512 (label_ref (match_dup 3))
14515 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14517 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14520 ;; avoid useless masking of bit offset operand
14521 (define_insn_and_split "*jcc_btsi_mask_1"
14524 (match_operator 0 "bt_comparison_operator"
14527 (match_operand:SI 1 "register_operand" "r")
14530 (match_operand:SI 2 "register_operand" "r")
14531 (match_operand:SI 3 "const_int_operand" "n")) 0))
14534 (label_ref (match_operand 4 "" ""))
14536 (clobber (reg:CC FLAGS_REG))]
14537 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14538 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14541 [(set (reg:CCC FLAGS_REG)
14549 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14550 (label_ref (match_dup 4))
14552 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14554 ;; Define combination compare-and-branch fp compare instructions to use
14555 ;; during early optimization. Splitting the operation apart early makes
14556 ;; for bad code when we want to reverse the operation.
14558 (define_insn "*fp_jcc_1_mixed"
14560 (if_then_else (match_operator 0 "comparison_operator"
14561 [(match_operand 1 "register_operand" "f,x")
14562 (match_operand 2 "nonimmediate_operand" "f,xm")])
14563 (label_ref (match_operand 3 "" ""))
14565 (clobber (reg:CCFP FPSR_REG))
14566 (clobber (reg:CCFP FLAGS_REG))]
14567 "TARGET_MIX_SSE_I387
14568 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14569 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14570 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14573 (define_insn "*fp_jcc_1_sse"
14575 (if_then_else (match_operator 0 "comparison_operator"
14576 [(match_operand 1 "register_operand" "x")
14577 (match_operand 2 "nonimmediate_operand" "xm")])
14578 (label_ref (match_operand 3 "" ""))
14580 (clobber (reg:CCFP FPSR_REG))
14581 (clobber (reg:CCFP FLAGS_REG))]
14583 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14584 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14585 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14588 (define_insn "*fp_jcc_1_387"
14590 (if_then_else (match_operator 0 "comparison_operator"
14591 [(match_operand 1 "register_operand" "f")
14592 (match_operand 2 "register_operand" "f")])
14593 (label_ref (match_operand 3 "" ""))
14595 (clobber (reg:CCFP FPSR_REG))
14596 (clobber (reg:CCFP FLAGS_REG))]
14597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14599 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14600 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14603 (define_insn "*fp_jcc_2_mixed"
14605 (if_then_else (match_operator 0 "comparison_operator"
14606 [(match_operand 1 "register_operand" "f,x")
14607 (match_operand 2 "nonimmediate_operand" "f,xm")])
14609 (label_ref (match_operand 3 "" ""))))
14610 (clobber (reg:CCFP FPSR_REG))
14611 (clobber (reg:CCFP FLAGS_REG))]
14612 "TARGET_MIX_SSE_I387
14613 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14614 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14615 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14618 (define_insn "*fp_jcc_2_sse"
14620 (if_then_else (match_operator 0 "comparison_operator"
14621 [(match_operand 1 "register_operand" "x")
14622 (match_operand 2 "nonimmediate_operand" "xm")])
14624 (label_ref (match_operand 3 "" ""))))
14625 (clobber (reg:CCFP FPSR_REG))
14626 (clobber (reg:CCFP FLAGS_REG))]
14628 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14629 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14633 (define_insn "*fp_jcc_2_387"
14635 (if_then_else (match_operator 0 "comparison_operator"
14636 [(match_operand 1 "register_operand" "f")
14637 (match_operand 2 "register_operand" "f")])
14639 (label_ref (match_operand 3 "" ""))))
14640 (clobber (reg:CCFP FPSR_REG))
14641 (clobber (reg:CCFP FLAGS_REG))]
14642 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14644 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14645 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14648 (define_insn "*fp_jcc_3_387"
14650 (if_then_else (match_operator 0 "comparison_operator"
14651 [(match_operand 1 "register_operand" "f")
14652 (match_operand 2 "nonimmediate_operand" "fm")])
14653 (label_ref (match_operand 3 "" ""))
14655 (clobber (reg:CCFP FPSR_REG))
14656 (clobber (reg:CCFP FLAGS_REG))
14657 (clobber (match_scratch:HI 4 "=a"))]
14659 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14660 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14661 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14662 && SELECT_CC_MODE (GET_CODE (operands[0]),
14663 operands[1], operands[2]) == CCFPmode
14664 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14667 (define_insn "*fp_jcc_4_387"
14669 (if_then_else (match_operator 0 "comparison_operator"
14670 [(match_operand 1 "register_operand" "f")
14671 (match_operand 2 "nonimmediate_operand" "fm")])
14673 (label_ref (match_operand 3 "" ""))))
14674 (clobber (reg:CCFP FPSR_REG))
14675 (clobber (reg:CCFP FLAGS_REG))
14676 (clobber (match_scratch:HI 4 "=a"))]
14678 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14679 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14681 && SELECT_CC_MODE (GET_CODE (operands[0]),
14682 operands[1], operands[2]) == CCFPmode
14683 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14686 (define_insn "*fp_jcc_5_387"
14688 (if_then_else (match_operator 0 "comparison_operator"
14689 [(match_operand 1 "register_operand" "f")
14690 (match_operand 2 "register_operand" "f")])
14691 (label_ref (match_operand 3 "" ""))
14693 (clobber (reg:CCFP FPSR_REG))
14694 (clobber (reg:CCFP FLAGS_REG))
14695 (clobber (match_scratch:HI 4 "=a"))]
14696 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14697 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14698 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14701 (define_insn "*fp_jcc_6_387"
14703 (if_then_else (match_operator 0 "comparison_operator"
14704 [(match_operand 1 "register_operand" "f")
14705 (match_operand 2 "register_operand" "f")])
14707 (label_ref (match_operand 3 "" ""))))
14708 (clobber (reg:CCFP FPSR_REG))
14709 (clobber (reg:CCFP FLAGS_REG))
14710 (clobber (match_scratch:HI 4 "=a"))]
14711 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14712 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14713 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14716 (define_insn "*fp_jcc_7_387"
14718 (if_then_else (match_operator 0 "comparison_operator"
14719 [(match_operand 1 "register_operand" "f")
14720 (match_operand 2 "const0_operand" "")])
14721 (label_ref (match_operand 3 "" ""))
14723 (clobber (reg:CCFP FPSR_REG))
14724 (clobber (reg:CCFP FLAGS_REG))
14725 (clobber (match_scratch:HI 4 "=a"))]
14726 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14727 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14728 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14729 && SELECT_CC_MODE (GET_CODE (operands[0]),
14730 operands[1], operands[2]) == CCFPmode
14731 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14734 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14735 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14736 ;; with a precedence over other operators and is always put in the first
14737 ;; place. Swap condition and operands to match ficom instruction.
14739 (define_insn "*fp_jcc_8<mode>_387"
14741 (if_then_else (match_operator 0 "comparison_operator"
14742 [(match_operator 1 "float_operator"
14743 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14744 (match_operand 3 "register_operand" "f,f")])
14745 (label_ref (match_operand 4 "" ""))
14747 (clobber (reg:CCFP FPSR_REG))
14748 (clobber (reg:CCFP FLAGS_REG))
14749 (clobber (match_scratch:HI 5 "=a,a"))]
14750 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14751 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14752 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14753 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14754 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14755 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14760 (if_then_else (match_operator 0 "comparison_operator"
14761 [(match_operand 1 "register_operand" "")
14762 (match_operand 2 "nonimmediate_operand" "")])
14763 (match_operand 3 "" "")
14764 (match_operand 4 "" "")))
14765 (clobber (reg:CCFP FPSR_REG))
14766 (clobber (reg:CCFP FLAGS_REG))]
14770 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14771 operands[3], operands[4], NULL_RTX, NULL_RTX);
14777 (if_then_else (match_operator 0 "comparison_operator"
14778 [(match_operand 1 "register_operand" "")
14779 (match_operand 2 "general_operand" "")])
14780 (match_operand 3 "" "")
14781 (match_operand 4 "" "")))
14782 (clobber (reg:CCFP FPSR_REG))
14783 (clobber (reg:CCFP FLAGS_REG))
14784 (clobber (match_scratch:HI 5 "=a"))]
14788 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14789 operands[3], operands[4], operands[5], NULL_RTX);
14795 (if_then_else (match_operator 0 "comparison_operator"
14796 [(match_operator 1 "float_operator"
14797 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14798 (match_operand 3 "register_operand" "")])
14799 (match_operand 4 "" "")
14800 (match_operand 5 "" "")))
14801 (clobber (reg:CCFP FPSR_REG))
14802 (clobber (reg:CCFP FLAGS_REG))
14803 (clobber (match_scratch:HI 6 "=a"))]
14807 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14808 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14809 operands[3], operands[7],
14810 operands[4], operands[5], operands[6], NULL_RTX);
14814 ;; %%% Kill this when reload knows how to do it.
14817 (if_then_else (match_operator 0 "comparison_operator"
14818 [(match_operator 1 "float_operator"
14819 [(match_operand:X87MODEI12 2 "register_operand" "")])
14820 (match_operand 3 "register_operand" "")])
14821 (match_operand 4 "" "")
14822 (match_operand 5 "" "")))
14823 (clobber (reg:CCFP FPSR_REG))
14824 (clobber (reg:CCFP FLAGS_REG))
14825 (clobber (match_scratch:HI 6 "=a"))]
14829 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14831 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14832 operands[3], operands[7],
14833 operands[4], operands[5], operands[6], operands[2]);
14837 ;; Unconditional and other jump instructions
14839 (define_insn "jump"
14841 (label_ref (match_operand 0 "" "")))]
14844 [(set_attr "type" "ibr")
14845 (set (attr "length")
14846 (if_then_else (and (ge (minus (match_dup 0) (pc))
14848 (lt (minus (match_dup 0) (pc))
14852 (set_attr "modrm" "0")])
14854 (define_expand "indirect_jump"
14855 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14859 (define_insn "*indirect_jump"
14860 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14863 [(set_attr "type" "ibr")
14864 (set_attr "length_immediate" "0")])
14866 (define_expand "tablejump"
14867 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14868 (use (label_ref (match_operand 1 "" "")))])]
14871 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14872 relative. Convert the relative address to an absolute address. */
14876 enum rtx_code code;
14878 /* We can't use @GOTOFF for text labels on VxWorks;
14879 see gotoff_operand. */
14880 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14884 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14886 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14890 op1 = pic_offset_table_rtx;
14895 op0 = pic_offset_table_rtx;
14899 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14904 (define_insn "*tablejump_1"
14905 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14906 (use (label_ref (match_operand 1 "" "")))]
14909 [(set_attr "type" "ibr")
14910 (set_attr "length_immediate" "0")])
14912 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14915 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14916 (set (match_operand:QI 1 "register_operand" "")
14917 (match_operator:QI 2 "ix86_comparison_operator"
14918 [(reg FLAGS_REG) (const_int 0)]))
14919 (set (match_operand 3 "q_regs_operand" "")
14920 (zero_extend (match_dup 1)))]
14921 "(peep2_reg_dead_p (3, operands[1])
14922 || operands_match_p (operands[1], operands[3]))
14923 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14924 [(set (match_dup 4) (match_dup 0))
14925 (set (strict_low_part (match_dup 5))
14928 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14929 operands[5] = gen_lowpart (QImode, operands[3]);
14930 ix86_expand_clear (operands[3]);
14933 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14936 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14937 (set (match_operand:QI 1 "register_operand" "")
14938 (match_operator:QI 2 "ix86_comparison_operator"
14939 [(reg FLAGS_REG) (const_int 0)]))
14940 (parallel [(set (match_operand 3 "q_regs_operand" "")
14941 (zero_extend (match_dup 1)))
14942 (clobber (reg:CC FLAGS_REG))])]
14943 "(peep2_reg_dead_p (3, operands[1])
14944 || operands_match_p (operands[1], operands[3]))
14945 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14946 [(set (match_dup 4) (match_dup 0))
14947 (set (strict_low_part (match_dup 5))
14950 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14951 operands[5] = gen_lowpart (QImode, operands[3]);
14952 ix86_expand_clear (operands[3]);
14955 ;; Call instructions.
14957 ;; The predicates normally associated with named expanders are not properly
14958 ;; checked for calls. This is a bug in the generic code, but it isn't that
14959 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14961 ;; P6 processors will jump to the address after the decrement when %esp
14962 ;; is used as a call operand, so they will execute return address as a code.
14963 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14965 ;; Call subroutine returning no value.
14967 (define_expand "call_pop"
14968 [(parallel [(call (match_operand:QI 0 "" "")
14969 (match_operand:SI 1 "" ""))
14970 (set (reg:SI SP_REG)
14971 (plus:SI (reg:SI SP_REG)
14972 (match_operand:SI 3 "" "")))])]
14975 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14979 (define_insn "*call_pop_0"
14980 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14981 (match_operand:SI 1 "" ""))
14982 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14983 (match_operand:SI 2 "immediate_operand" "")))]
14986 if (SIBLING_CALL_P (insn))
14989 return "call\t%P0";
14991 [(set_attr "type" "call")])
14993 (define_insn "*call_pop_1"
14994 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14995 (match_operand:SI 1 "" ""))
14996 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14997 (match_operand:SI 2 "immediate_operand" "i")))]
14998 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
15000 if (constant_call_address_operand (operands[0], Pmode))
15001 return "call\t%P0";
15002 return "call\t%A0";
15004 [(set_attr "type" "call")])
15006 (define_insn "*sibcall_pop_1"
15007 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15008 (match_operand:SI 1 "" ""))
15009 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15010 (match_operand:SI 2 "immediate_operand" "i,i")))]
15011 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
15015 [(set_attr "type" "call")])
15017 (define_expand "call"
15018 [(call (match_operand:QI 0 "" "")
15019 (match_operand 1 "" ""))
15020 (use (match_operand 2 "" ""))]
15023 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15027 (define_expand "sibcall"
15028 [(call (match_operand:QI 0 "" "")
15029 (match_operand 1 "" ""))
15030 (use (match_operand 2 "" ""))]
15033 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15037 (define_insn "*call_0"
15038 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15039 (match_operand 1 "" ""))]
15042 if (SIBLING_CALL_P (insn))
15045 return "call\t%P0";
15047 [(set_attr "type" "call")])
15049 (define_insn "*call_1"
15050 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
15051 (match_operand 1 "" ""))]
15052 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
15054 if (constant_call_address_operand (operands[0], Pmode))
15055 return "call\t%P0";
15056 return "call\t%A0";
15058 [(set_attr "type" "call")])
15060 (define_insn "*sibcall_1"
15061 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15062 (match_operand 1 "" ""))]
15063 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
15067 [(set_attr "type" "call")])
15069 (define_insn "*call_1_rex64"
15070 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15071 (match_operand 1 "" ""))]
15072 "TARGET_64BIT && !SIBLING_CALL_P (insn)
15073 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15075 if (constant_call_address_operand (operands[0], Pmode))
15076 return "call\t%P0";
15077 return "call\t%A0";
15079 [(set_attr "type" "call")])
15081 (define_insn "*call_1_rex64_ms_sysv"
15082 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15083 (match_operand 1 "" ""))
15084 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15085 (clobber (reg:TI XMM6_REG))
15086 (clobber (reg:TI XMM7_REG))
15087 (clobber (reg:TI XMM8_REG))
15088 (clobber (reg:TI XMM9_REG))
15089 (clobber (reg:TI XMM10_REG))
15090 (clobber (reg:TI XMM11_REG))
15091 (clobber (reg:TI XMM12_REG))
15092 (clobber (reg:TI XMM13_REG))
15093 (clobber (reg:TI XMM14_REG))
15094 (clobber (reg:TI XMM15_REG))
15095 (clobber (reg:DI SI_REG))
15096 (clobber (reg:DI DI_REG))]
15097 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
15099 if (constant_call_address_operand (operands[0], Pmode))
15100 return "call\t%P0";
15101 return "call\t%A0";
15103 [(set_attr "type" "call")])
15105 (define_insn "*call_1_rex64_large"
15106 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15107 (match_operand 1 "" ""))]
15108 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
15110 [(set_attr "type" "call")])
15112 (define_insn "*sibcall_1_rex64"
15113 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15114 (match_operand 1 "" ""))]
15115 "TARGET_64BIT && SIBLING_CALL_P (insn)"
15119 [(set_attr "type" "call")])
15121 ;; Call subroutine, returning value in operand 0
15122 (define_expand "call_value_pop"
15123 [(parallel [(set (match_operand 0 "" "")
15124 (call (match_operand:QI 1 "" "")
15125 (match_operand:SI 2 "" "")))
15126 (set (reg:SI SP_REG)
15127 (plus:SI (reg:SI SP_REG)
15128 (match_operand:SI 4 "" "")))])]
15131 ix86_expand_call (operands[0], operands[1], operands[2],
15132 operands[3], operands[4], 0);
15136 (define_expand "call_value"
15137 [(set (match_operand 0 "" "")
15138 (call (match_operand:QI 1 "" "")
15139 (match_operand:SI 2 "" "")))
15140 (use (match_operand:SI 3 "" ""))]
15141 ;; Operand 2 not used on the i386.
15144 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15148 (define_expand "sibcall_value"
15149 [(set (match_operand 0 "" "")
15150 (call (match_operand:QI 1 "" "")
15151 (match_operand:SI 2 "" "")))
15152 (use (match_operand:SI 3 "" ""))]
15153 ;; Operand 2 not used on the i386.
15156 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15160 ;; Call subroutine returning any type.
15162 (define_expand "untyped_call"
15163 [(parallel [(call (match_operand 0 "" "")
15165 (match_operand 1 "" "")
15166 (match_operand 2 "" "")])]
15171 /* In order to give reg-stack an easier job in validating two
15172 coprocessor registers as containing a possible return value,
15173 simply pretend the untyped call returns a complex long double
15176 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15177 and should have the default ABI. */
15179 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15180 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15181 operands[0], const0_rtx,
15182 GEN_INT ((TARGET_64BIT
15183 ? (DEFAULT_ABI == SYSV_ABI
15184 ? X86_64_SSE_REGPARM_MAX
15185 : X64_SSE_REGPARM_MAX)
15186 : X86_32_SSE_REGPARM_MAX)
15190 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15192 rtx set = XVECEXP (operands[2], 0, i);
15193 emit_move_insn (SET_DEST (set), SET_SRC (set));
15196 /* The optimizer does not know that the call sets the function value
15197 registers we stored in the result block. We avoid problems by
15198 claiming that all hard registers are used and clobbered at this
15200 emit_insn (gen_blockage ());
15205 ;; Prologue and epilogue instructions
15207 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15208 ;; all of memory. This blocks insns from being moved across this point.
15210 (define_insn "blockage"
15211 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15214 [(set_attr "length" "0")])
15216 ;; Do not schedule instructions accessing memory across this point.
15218 (define_expand "memory_blockage"
15219 [(set (match_dup 0)
15220 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15223 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15224 MEM_VOLATILE_P (operands[0]) = 1;
15227 (define_insn "*memory_blockage"
15228 [(set (match_operand:BLK 0 "" "")
15229 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15232 [(set_attr "length" "0")])
15234 ;; As USE insns aren't meaningful after reload, this is used instead
15235 ;; to prevent deleting instructions setting registers for PIC code
15236 (define_insn "prologue_use"
15237 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15240 [(set_attr "length" "0")])
15242 ;; Insn emitted into the body of a function to return from a function.
15243 ;; This is only done if the function's epilogue is known to be simple.
15244 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15246 (define_expand "return"
15248 "ix86_can_use_return_insn_p ()"
15250 if (crtl->args.pops_args)
15252 rtx popc = GEN_INT (crtl->args.pops_args);
15253 emit_jump_insn (gen_return_pop_internal (popc));
15258 (define_insn "return_internal"
15262 [(set_attr "length" "1")
15263 (set_attr "length_immediate" "0")
15264 (set_attr "modrm" "0")])
15266 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15267 ;; instruction Athlon and K8 have.
15269 (define_insn "return_internal_long"
15271 (unspec [(const_int 0)] UNSPEC_REP)]
15274 [(set_attr "length" "1")
15275 (set_attr "length_immediate" "0")
15276 (set_attr "prefix_rep" "1")
15277 (set_attr "modrm" "0")])
15279 (define_insn "return_pop_internal"
15281 (use (match_operand:SI 0 "const_int_operand" ""))]
15284 [(set_attr "length" "3")
15285 (set_attr "length_immediate" "2")
15286 (set_attr "modrm" "0")])
15288 (define_insn "return_indirect_internal"
15290 (use (match_operand:SI 0 "register_operand" "r"))]
15293 [(set_attr "type" "ibr")
15294 (set_attr "length_immediate" "0")])
15300 [(set_attr "length" "1")
15301 (set_attr "length_immediate" "0")
15302 (set_attr "modrm" "0")])
15304 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15305 ;; branch prediction penalty for the third jump in a 16-byte
15308 (define_insn "align"
15309 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15312 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15313 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15315 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15316 The align insn is used to avoid 3 jump instructions in the row to improve
15317 branch prediction and the benefits hardly outweigh the cost of extra 8
15318 nops on the average inserted by full alignment pseudo operation. */
15322 [(set_attr "length" "16")])
15324 (define_expand "prologue"
15327 "ix86_expand_prologue (); DONE;")
15329 (define_insn "set_got"
15330 [(set (match_operand:SI 0 "register_operand" "=r")
15331 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15332 (clobber (reg:CC FLAGS_REG))]
15334 { return output_set_got (operands[0], NULL_RTX); }
15335 [(set_attr "type" "multi")
15336 (set_attr "length" "12")])
15338 (define_insn "set_got_labelled"
15339 [(set (match_operand:SI 0 "register_operand" "=r")
15340 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15342 (clobber (reg:CC FLAGS_REG))]
15344 { return output_set_got (operands[0], operands[1]); }
15345 [(set_attr "type" "multi")
15346 (set_attr "length" "12")])
15348 (define_insn "set_got_rex64"
15349 [(set (match_operand:DI 0 "register_operand" "=r")
15350 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15352 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15353 [(set_attr "type" "lea")
15354 (set_attr "length" "6")])
15356 (define_insn "set_rip_rex64"
15357 [(set (match_operand:DI 0 "register_operand" "=r")
15358 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15360 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15361 [(set_attr "type" "lea")
15362 (set_attr "length" "6")])
15364 (define_insn "set_got_offset_rex64"
15365 [(set (match_operand:DI 0 "register_operand" "=r")
15367 [(label_ref (match_operand 1 "" ""))]
15368 UNSPEC_SET_GOT_OFFSET))]
15370 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15371 [(set_attr "type" "imov")
15372 (set_attr "length" "11")])
15374 (define_expand "epilogue"
15377 "ix86_expand_epilogue (1); DONE;")
15379 (define_expand "sibcall_epilogue"
15382 "ix86_expand_epilogue (0); DONE;")
15384 (define_expand "eh_return"
15385 [(use (match_operand 0 "register_operand" ""))]
15388 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15390 /* Tricky bit: we write the address of the handler to which we will
15391 be returning into someone else's stack frame, one word below the
15392 stack address we wish to restore. */
15393 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15394 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15395 tmp = gen_rtx_MEM (Pmode, tmp);
15396 emit_move_insn (tmp, ra);
15398 if (Pmode == SImode)
15399 emit_jump_insn (gen_eh_return_si (sa));
15401 emit_jump_insn (gen_eh_return_di (sa));
15406 (define_insn_and_split "eh_return_<mode>"
15408 (unspec [(match_operand:P 0 "register_operand" "c")]
15409 UNSPEC_EH_RETURN))]
15414 "ix86_expand_epilogue (2); DONE;")
15416 (define_insn "leave"
15417 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15418 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15419 (clobber (mem:BLK (scratch)))]
15422 [(set_attr "type" "leave")])
15424 (define_insn "leave_rex64"
15425 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15426 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15427 (clobber (mem:BLK (scratch)))]
15430 [(set_attr "type" "leave")])
15432 (define_expand "ffssi2"
15434 [(set (match_operand:SI 0 "register_operand" "")
15435 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15436 (clobber (match_scratch:SI 2 ""))
15437 (clobber (reg:CC FLAGS_REG))])]
15442 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15447 (define_expand "ffs_cmove"
15448 [(set (match_dup 2) (const_int -1))
15449 (parallel [(set (reg:CCZ FLAGS_REG)
15450 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15452 (set (match_operand:SI 0 "register_operand" "")
15453 (ctz:SI (match_dup 1)))])
15454 (set (match_dup 0) (if_then_else:SI
15455 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15458 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15459 (clobber (reg:CC FLAGS_REG))])]
15461 "operands[2] = gen_reg_rtx (SImode);")
15463 (define_insn_and_split "*ffs_no_cmove"
15464 [(set (match_operand:SI 0 "register_operand" "=r")
15465 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15466 (clobber (match_scratch:SI 2 "=&q"))
15467 (clobber (reg:CC FLAGS_REG))]
15470 "&& reload_completed"
15471 [(parallel [(set (reg:CCZ FLAGS_REG)
15472 (compare:CCZ (match_dup 1) (const_int 0)))
15473 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15474 (set (strict_low_part (match_dup 3))
15475 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15476 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15477 (clobber (reg:CC FLAGS_REG))])
15478 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15479 (clobber (reg:CC FLAGS_REG))])
15480 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15481 (clobber (reg:CC FLAGS_REG))])]
15483 operands[3] = gen_lowpart (QImode, operands[2]);
15484 ix86_expand_clear (operands[2]);
15487 (define_insn "*ffssi_1"
15488 [(set (reg:CCZ FLAGS_REG)
15489 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15491 (set (match_operand:SI 0 "register_operand" "=r")
15492 (ctz:SI (match_dup 1)))]
15494 "bsf{l}\t{%1, %0|%0, %1}"
15495 [(set_attr "prefix_0f" "1")])
15497 (define_expand "ffsdi2"
15498 [(set (match_dup 2) (const_int -1))
15499 (parallel [(set (reg:CCZ FLAGS_REG)
15500 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15502 (set (match_operand:DI 0 "register_operand" "")
15503 (ctz:DI (match_dup 1)))])
15504 (set (match_dup 0) (if_then_else:DI
15505 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15508 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15509 (clobber (reg:CC FLAGS_REG))])]
15511 "operands[2] = gen_reg_rtx (DImode);")
15513 (define_insn "*ffsdi_1"
15514 [(set (reg:CCZ FLAGS_REG)
15515 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15517 (set (match_operand:DI 0 "register_operand" "=r")
15518 (ctz:DI (match_dup 1)))]
15520 "bsf{q}\t{%1, %0|%0, %1}"
15521 [(set_attr "prefix_0f" "1")])
15523 (define_insn "ctzsi2"
15524 [(set (match_operand:SI 0 "register_operand" "=r")
15525 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15526 (clobber (reg:CC FLAGS_REG))]
15528 "bsf{l}\t{%1, %0|%0, %1}"
15529 [(set_attr "prefix_0f" "1")])
15531 (define_insn "ctzdi2"
15532 [(set (match_operand:DI 0 "register_operand" "=r")
15533 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15534 (clobber (reg:CC FLAGS_REG))]
15536 "bsf{q}\t{%1, %0|%0, %1}"
15537 [(set_attr "prefix_0f" "1")])
15539 (define_expand "clzsi2"
15541 [(set (match_operand:SI 0 "register_operand" "")
15542 (minus:SI (const_int 31)
15543 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15544 (clobber (reg:CC FLAGS_REG))])
15546 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15547 (clobber (reg:CC FLAGS_REG))])]
15552 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15557 (define_insn "clzsi2_abm"
15558 [(set (match_operand:SI 0 "register_operand" "=r")
15559 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15560 (clobber (reg:CC FLAGS_REG))]
15562 "lzcnt{l}\t{%1, %0|%0, %1}"
15563 [(set_attr "prefix_rep" "1")
15564 (set_attr "type" "bitmanip")
15565 (set_attr "mode" "SI")])
15567 (define_insn "*bsr"
15568 [(set (match_operand:SI 0 "register_operand" "=r")
15569 (minus:SI (const_int 31)
15570 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15571 (clobber (reg:CC FLAGS_REG))]
15573 "bsr{l}\t{%1, %0|%0, %1}"
15574 [(set_attr "prefix_0f" "1")
15575 (set_attr "mode" "SI")])
15577 (define_insn "popcount<mode>2"
15578 [(set (match_operand:SWI248 0 "register_operand" "=r")
15580 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15581 (clobber (reg:CC FLAGS_REG))]
15585 return "popcnt\t{%1, %0|%0, %1}";
15587 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15590 [(set_attr "prefix_rep" "1")
15591 (set_attr "type" "bitmanip")
15592 (set_attr "mode" "<MODE>")])
15594 (define_insn "*popcount<mode>2_cmp"
15595 [(set (reg FLAGS_REG)
15598 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15600 (set (match_operand:SWI248 0 "register_operand" "=r")
15601 (popcount:SWI248 (match_dup 1)))]
15602 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15605 return "popcnt\t{%1, %0|%0, %1}";
15607 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15610 [(set_attr "prefix_rep" "1")
15611 (set_attr "type" "bitmanip")
15612 (set_attr "mode" "<MODE>")])
15614 (define_insn "*popcountsi2_cmp_zext"
15615 [(set (reg FLAGS_REG)
15617 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15619 (set (match_operand:DI 0 "register_operand" "=r")
15620 (zero_extend:DI(popcount:SI (match_dup 1))))]
15621 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15624 return "popcnt\t{%1, %0|%0, %1}";
15626 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15629 [(set_attr "prefix_rep" "1")
15630 (set_attr "type" "bitmanip")
15631 (set_attr "mode" "SI")])
15633 (define_expand "bswapsi2"
15634 [(set (match_operand:SI 0 "register_operand" "")
15635 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15640 rtx x = operands[0];
15642 emit_move_insn (x, operands[1]);
15643 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15644 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15645 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15650 (define_insn "*bswapsi_1"
15651 [(set (match_operand:SI 0 "register_operand" "=r")
15652 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15655 [(set_attr "prefix_0f" "1")
15656 (set_attr "length" "2")])
15658 (define_insn "*bswaphi_lowpart_1"
15659 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15660 (bswap:HI (match_dup 0)))
15661 (clobber (reg:CC FLAGS_REG))]
15662 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15664 xchg{b}\t{%h0, %b0|%b0, %h0}
15665 rol{w}\t{$8, %0|%0, 8}"
15666 [(set_attr "length" "2,4")
15667 (set_attr "mode" "QI,HI")])
15669 (define_insn "bswaphi_lowpart"
15670 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15671 (bswap:HI (match_dup 0)))
15672 (clobber (reg:CC FLAGS_REG))]
15674 "rol{w}\t{$8, %0|%0, 8}"
15675 [(set_attr "length" "4")
15676 (set_attr "mode" "HI")])
15678 (define_insn "bswapdi2"
15679 [(set (match_operand:DI 0 "register_operand" "=r")
15680 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15683 [(set_attr "prefix_0f" "1")
15684 (set_attr "length" "3")])
15686 (define_expand "clzdi2"
15688 [(set (match_operand:DI 0 "register_operand" "")
15689 (minus:DI (const_int 63)
15690 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15691 (clobber (reg:CC FLAGS_REG))])
15693 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15694 (clobber (reg:CC FLAGS_REG))])]
15699 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15704 (define_insn "clzdi2_abm"
15705 [(set (match_operand:DI 0 "register_operand" "=r")
15706 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15707 (clobber (reg:CC FLAGS_REG))]
15708 "TARGET_64BIT && TARGET_ABM"
15709 "lzcnt{q}\t{%1, %0|%0, %1}"
15710 [(set_attr "prefix_rep" "1")
15711 (set_attr "type" "bitmanip")
15712 (set_attr "mode" "DI")])
15714 (define_insn "*bsr_rex64"
15715 [(set (match_operand:DI 0 "register_operand" "=r")
15716 (minus:DI (const_int 63)
15717 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15718 (clobber (reg:CC FLAGS_REG))]
15720 "bsr{q}\t{%1, %0|%0, %1}"
15721 [(set_attr "prefix_0f" "1")
15722 (set_attr "mode" "DI")])
15724 (define_expand "clzhi2"
15726 [(set (match_operand:HI 0 "register_operand" "")
15727 (minus:HI (const_int 15)
15728 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15729 (clobber (reg:CC FLAGS_REG))])
15731 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15732 (clobber (reg:CC FLAGS_REG))])]
15737 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15742 (define_insn "clzhi2_abm"
15743 [(set (match_operand:HI 0 "register_operand" "=r")
15744 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15745 (clobber (reg:CC FLAGS_REG))]
15747 "lzcnt{w}\t{%1, %0|%0, %1}"
15748 [(set_attr "prefix_rep" "1")
15749 (set_attr "type" "bitmanip")
15750 (set_attr "mode" "HI")])
15752 (define_insn "*bsrhi"
15753 [(set (match_operand:HI 0 "register_operand" "=r")
15754 (minus:HI (const_int 15)
15755 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15756 (clobber (reg:CC FLAGS_REG))]
15758 "bsr{w}\t{%1, %0|%0, %1}"
15759 [(set_attr "prefix_0f" "1")
15760 (set_attr "mode" "HI")])
15762 (define_expand "paritydi2"
15763 [(set (match_operand:DI 0 "register_operand" "")
15764 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15767 rtx scratch = gen_reg_rtx (QImode);
15770 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15771 NULL_RTX, operands[1]));
15773 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15774 gen_rtx_REG (CCmode, FLAGS_REG),
15776 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15779 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15782 rtx tmp = gen_reg_rtx (SImode);
15784 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15785 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15790 (define_insn_and_split "paritydi2_cmp"
15791 [(set (reg:CC FLAGS_REG)
15792 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
15794 (clobber (match_scratch:DI 0 "=r"))
15795 (clobber (match_scratch:SI 1 "=&r"))
15796 (clobber (match_scratch:HI 2 "=Q"))]
15799 "&& reload_completed"
15801 [(set (match_dup 1)
15802 (xor:SI (match_dup 1) (match_dup 4)))
15803 (clobber (reg:CC FLAGS_REG))])
15805 [(set (reg:CC FLAGS_REG)
15806 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15807 (clobber (match_dup 1))
15808 (clobber (match_dup 2))])]
15810 operands[4] = gen_lowpart (SImode, operands[3]);
15814 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15815 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15818 operands[1] = gen_highpart (SImode, operands[3]);
15821 (define_expand "paritysi2"
15822 [(set (match_operand:SI 0 "register_operand" "")
15823 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15826 rtx scratch = gen_reg_rtx (QImode);
15829 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15831 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15832 gen_rtx_REG (CCmode, FLAGS_REG),
15834 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15836 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15840 (define_insn_and_split "paritysi2_cmp"
15841 [(set (reg:CC FLAGS_REG)
15842 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
15844 (clobber (match_scratch:SI 0 "=r"))
15845 (clobber (match_scratch:HI 1 "=&Q"))]
15848 "&& reload_completed"
15850 [(set (match_dup 1)
15851 (xor:HI (match_dup 1) (match_dup 3)))
15852 (clobber (reg:CC FLAGS_REG))])
15854 [(set (reg:CC FLAGS_REG)
15855 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15856 (clobber (match_dup 1))])]
15858 operands[3] = gen_lowpart (HImode, operands[2]);
15860 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15861 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15864 (define_insn "*parityhi2_cmp"
15865 [(set (reg:CC FLAGS_REG)
15866 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
15868 (clobber (match_scratch:HI 0 "=Q"))]
15870 "xor{b}\t{%h0, %b0|%b0, %h0}"
15871 [(set_attr "length" "2")
15872 (set_attr "mode" "HI")])
15874 ;; Thread-local storage patterns for ELF.
15876 ;; Note that these code sequences must appear exactly as shown
15877 ;; in order to allow linker relaxation.
15879 (define_insn "*tls_global_dynamic_32_gnu"
15880 [(set (match_operand:SI 0 "register_operand" "=a")
15881 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15882 (match_operand:SI 2 "tls_symbolic_operand" "")
15883 (match_operand:SI 3 "call_insn_operand" "")]
15885 (clobber (match_scratch:SI 4 "=d"))
15886 (clobber (match_scratch:SI 5 "=c"))
15887 (clobber (reg:CC FLAGS_REG))]
15888 "!TARGET_64BIT && TARGET_GNU_TLS"
15889 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15890 [(set_attr "type" "multi")
15891 (set_attr "length" "12")])
15893 (define_expand "tls_global_dynamic_32"
15894 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15897 (match_operand:SI 1 "tls_symbolic_operand" "")
15900 (clobber (match_scratch:SI 4 ""))
15901 (clobber (match_scratch:SI 5 ""))
15902 (clobber (reg:CC FLAGS_REG))])]
15906 operands[2] = pic_offset_table_rtx;
15909 operands[2] = gen_reg_rtx (Pmode);
15910 emit_insn (gen_set_got (operands[2]));
15912 if (TARGET_GNU2_TLS)
15914 emit_insn (gen_tls_dynamic_gnu2_32
15915 (operands[0], operands[1], operands[2]));
15918 operands[3] = ix86_tls_get_addr ();
15921 (define_insn "*tls_global_dynamic_64"
15922 [(set (match_operand:DI 0 "register_operand" "=a")
15923 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15924 (match_operand:DI 3 "" "")))
15925 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15928 { return ".byte\t0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15929 [(set_attr "type" "multi")
15930 (set_attr "length" "16")])
15932 (define_expand "tls_global_dynamic_64"
15933 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15934 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15935 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15939 if (TARGET_GNU2_TLS)
15941 emit_insn (gen_tls_dynamic_gnu2_64
15942 (operands[0], operands[1]));
15945 operands[2] = ix86_tls_get_addr ();
15948 (define_insn "*tls_local_dynamic_base_32_gnu"
15949 [(set (match_operand:SI 0 "register_operand" "=a")
15950 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15951 (match_operand:SI 2 "call_insn_operand" "")]
15952 UNSPEC_TLS_LD_BASE))
15953 (clobber (match_scratch:SI 3 "=d"))
15954 (clobber (match_scratch:SI 4 "=c"))
15955 (clobber (reg:CC FLAGS_REG))]
15956 "!TARGET_64BIT && TARGET_GNU_TLS"
15957 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15958 [(set_attr "type" "multi")
15959 (set_attr "length" "11")])
15961 (define_expand "tls_local_dynamic_base_32"
15962 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15963 (unspec:SI [(match_dup 1) (match_dup 2)]
15964 UNSPEC_TLS_LD_BASE))
15965 (clobber (match_scratch:SI 3 ""))
15966 (clobber (match_scratch:SI 4 ""))
15967 (clobber (reg:CC FLAGS_REG))])]
15971 operands[1] = pic_offset_table_rtx;
15974 operands[1] = gen_reg_rtx (Pmode);
15975 emit_insn (gen_set_got (operands[1]));
15977 if (TARGET_GNU2_TLS)
15979 emit_insn (gen_tls_dynamic_gnu2_32
15980 (operands[0], ix86_tls_module_base (), operands[1]));
15983 operands[2] = ix86_tls_get_addr ();
15986 (define_insn "*tls_local_dynamic_base_64"
15987 [(set (match_operand:DI 0 "register_operand" "=a")
15988 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15989 (match_operand:DI 2 "" "")))
15990 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15992 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15993 [(set_attr "type" "multi")
15994 (set_attr "length" "12")])
15996 (define_expand "tls_local_dynamic_base_64"
15997 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15998 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15999 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16002 if (TARGET_GNU2_TLS)
16004 emit_insn (gen_tls_dynamic_gnu2_64
16005 (operands[0], ix86_tls_module_base ()));
16008 operands[1] = ix86_tls_get_addr ();
16011 ;; Local dynamic of a single variable is a lose. Show combine how
16012 ;; to convert that back to global dynamic.
16014 (define_insn_and_split "*tls_local_dynamic_32_once"
16015 [(set (match_operand:SI 0 "register_operand" "=a")
16016 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16017 (match_operand:SI 2 "call_insn_operand" "")]
16018 UNSPEC_TLS_LD_BASE)
16019 (const:SI (unspec:SI
16020 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16022 (clobber (match_scratch:SI 4 "=d"))
16023 (clobber (match_scratch:SI 5 "=c"))
16024 (clobber (reg:CC FLAGS_REG))]
16028 [(parallel [(set (match_dup 0)
16029 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16031 (clobber (match_dup 4))
16032 (clobber (match_dup 5))
16033 (clobber (reg:CC FLAGS_REG))])]
16036 ;; Load and add the thread base pointer from %gs:0.
16038 (define_insn "*load_tp_si"
16039 [(set (match_operand:SI 0 "register_operand" "=r")
16040 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16042 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16043 [(set_attr "type" "imov")
16044 (set_attr "modrm" "0")
16045 (set_attr "length" "7")
16046 (set_attr "memory" "load")
16047 (set_attr "imm_disp" "false")])
16049 (define_insn "*add_tp_si"
16050 [(set (match_operand:SI 0 "register_operand" "=r")
16051 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16052 (match_operand:SI 1 "register_operand" "0")))
16053 (clobber (reg:CC FLAGS_REG))]
16055 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16056 [(set_attr "type" "alu")
16057 (set_attr "modrm" "0")
16058 (set_attr "length" "7")
16059 (set_attr "memory" "load")
16060 (set_attr "imm_disp" "false")])
16062 (define_insn "*load_tp_di"
16063 [(set (match_operand:DI 0 "register_operand" "=r")
16064 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16066 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16067 [(set_attr "type" "imov")
16068 (set_attr "modrm" "0")
16069 (set_attr "length" "7")
16070 (set_attr "memory" "load")
16071 (set_attr "imm_disp" "false")])
16073 (define_insn "*add_tp_di"
16074 [(set (match_operand:DI 0 "register_operand" "=r")
16075 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16076 (match_operand:DI 1 "register_operand" "0")))
16077 (clobber (reg:CC FLAGS_REG))]
16079 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16080 [(set_attr "type" "alu")
16081 (set_attr "modrm" "0")
16082 (set_attr "length" "7")
16083 (set_attr "memory" "load")
16084 (set_attr "imm_disp" "false")])
16086 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
16087 ;; %rax as destination of the initial executable code sequence.
16088 (define_insn "tls_initial_exec_64_sun"
16089 [(set (match_operand:DI 0 "register_operand" "=a")
16091 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16092 UNSPEC_TLS_IE_SUN))
16093 (clobber (reg:CC FLAGS_REG))]
16094 "TARGET_64BIT && TARGET_SUN_TLS"
16095 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
16096 [(set_attr "type" "multi")])
16098 ;; GNU2 TLS patterns can be split.
16100 (define_expand "tls_dynamic_gnu2_32"
16101 [(set (match_dup 3)
16102 (plus:SI (match_operand:SI 2 "register_operand" "")
16104 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16107 [(set (match_operand:SI 0 "register_operand" "")
16108 (unspec:SI [(match_dup 1) (match_dup 3)
16109 (match_dup 2) (reg:SI SP_REG)]
16111 (clobber (reg:CC FLAGS_REG))])]
16112 "!TARGET_64BIT && TARGET_GNU2_TLS"
16114 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16115 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16118 (define_insn "*tls_dynamic_lea_32"
16119 [(set (match_operand:SI 0 "register_operand" "=r")
16120 (plus:SI (match_operand:SI 1 "register_operand" "b")
16122 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16123 UNSPEC_TLSDESC))))]
16124 "!TARGET_64BIT && TARGET_GNU2_TLS"
16125 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16126 [(set_attr "type" "lea")
16127 (set_attr "mode" "SI")
16128 (set_attr "length" "6")
16129 (set_attr "length_address" "4")])
16131 (define_insn "*tls_dynamic_call_32"
16132 [(set (match_operand:SI 0 "register_operand" "=a")
16133 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16134 (match_operand:SI 2 "register_operand" "0")
16135 ;; we have to make sure %ebx still points to the GOT
16136 (match_operand:SI 3 "register_operand" "b")
16139 (clobber (reg:CC FLAGS_REG))]
16140 "!TARGET_64BIT && TARGET_GNU2_TLS"
16141 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16142 [(set_attr "type" "call")
16143 (set_attr "length" "2")
16144 (set_attr "length_address" "0")])
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16147 [(set (match_operand:SI 0 "register_operand" "=&a")
16149 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16150 (match_operand:SI 4 "" "")
16151 (match_operand:SI 2 "register_operand" "b")
16154 (const:SI (unspec:SI
16155 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16157 (clobber (reg:CC FLAGS_REG))]
16158 "!TARGET_64BIT && TARGET_GNU2_TLS"
16161 [(set (match_dup 0) (match_dup 5))]
16163 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16167 (define_expand "tls_dynamic_gnu2_64"
16168 [(set (match_dup 2)
16169 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16172 [(set (match_operand:DI 0 "register_operand" "")
16173 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16175 (clobber (reg:CC FLAGS_REG))])]
16176 "TARGET_64BIT && TARGET_GNU2_TLS"
16178 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16179 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16182 (define_insn "*tls_dynamic_lea_64"
16183 [(set (match_operand:DI 0 "register_operand" "=r")
16184 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16186 "TARGET_64BIT && TARGET_GNU2_TLS"
16187 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16188 [(set_attr "type" "lea")
16189 (set_attr "mode" "DI")
16190 (set_attr "length" "7")
16191 (set_attr "length_address" "4")])
16193 (define_insn "*tls_dynamic_call_64"
16194 [(set (match_operand:DI 0 "register_operand" "=a")
16195 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16196 (match_operand:DI 2 "register_operand" "0")
16199 (clobber (reg:CC FLAGS_REG))]
16200 "TARGET_64BIT && TARGET_GNU2_TLS"
16201 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16202 [(set_attr "type" "call")
16203 (set_attr "length" "2")
16204 (set_attr "length_address" "0")])
16206 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16207 [(set (match_operand:DI 0 "register_operand" "=&a")
16209 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16210 (match_operand:DI 3 "" "")
16213 (const:DI (unspec:DI
16214 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16216 (clobber (reg:CC FLAGS_REG))]
16217 "TARGET_64BIT && TARGET_GNU2_TLS"
16220 [(set (match_dup 0) (match_dup 4))]
16222 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16223 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16228 ;; These patterns match the binary 387 instructions for addM3, subM3,
16229 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16230 ;; SFmode. The first is the normal insn, the second the same insn but
16231 ;; with one operand a conversion, and the third the same insn but with
16232 ;; the other operand a conversion. The conversion may be SFmode or
16233 ;; SImode if the target mode DFmode, but only SImode if the target mode
16236 ;; Gcc is slightly more smart about handling normal two address instructions
16237 ;; so use special patterns for add and mull.
16239 (define_insn "*fop_<mode>_comm_mixed_avx"
16240 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16241 (match_operator:MODEF 3 "binary_fp_operator"
16242 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16243 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16244 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16245 && COMMUTATIVE_ARITH_P (operands[3])
16246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16247 "* return output_387_binary_op (insn, operands);"
16248 [(set (attr "type")
16249 (if_then_else (eq_attr "alternative" "1")
16250 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251 (const_string "ssemul")
16252 (const_string "sseadd"))
16253 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16254 (const_string "fmul")
16255 (const_string "fop"))))
16256 (set_attr "prefix" "orig,maybe_vex")
16257 (set_attr "mode" "<MODE>")])
16259 (define_insn "*fop_<mode>_comm_mixed"
16260 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16261 (match_operator:MODEF 3 "binary_fp_operator"
16262 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16264 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16265 && COMMUTATIVE_ARITH_P (operands[3])
16266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16267 "* return output_387_binary_op (insn, operands);"
16268 [(set (attr "type")
16269 (if_then_else (eq_attr "alternative" "1")
16270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271 (const_string "ssemul")
16272 (const_string "sseadd"))
16273 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274 (const_string "fmul")
16275 (const_string "fop"))))
16276 (set_attr "mode" "<MODE>")])
16278 (define_insn "*fop_<mode>_comm_avx"
16279 [(set (match_operand:MODEF 0 "register_operand" "=x")
16280 (match_operator:MODEF 3 "binary_fp_operator"
16281 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16282 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16283 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16284 && COMMUTATIVE_ARITH_P (operands[3])
16285 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286 "* return output_387_binary_op (insn, operands);"
16287 [(set (attr "type")
16288 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16289 (const_string "ssemul")
16290 (const_string "sseadd")))
16291 (set_attr "prefix" "vex")
16292 (set_attr "mode" "<MODE>")])
16294 (define_insn "*fop_<mode>_comm_sse"
16295 [(set (match_operand:MODEF 0 "register_operand" "=x")
16296 (match_operator:MODEF 3 "binary_fp_operator"
16297 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16299 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16300 && COMMUTATIVE_ARITH_P (operands[3])
16301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302 "* return output_387_binary_op (insn, operands);"
16303 [(set (attr "type")
16304 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305 (const_string "ssemul")
16306 (const_string "sseadd")))
16307 (set_attr "mode" "<MODE>")])
16309 (define_insn "*fop_<mode>_comm_i387"
16310 [(set (match_operand:MODEF 0 "register_operand" "=f")
16311 (match_operator:MODEF 3 "binary_fp_operator"
16312 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16313 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16315 && COMMUTATIVE_ARITH_P (operands[3])
16316 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317 "* return output_387_binary_op (insn, operands);"
16318 [(set (attr "type")
16319 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16320 (const_string "fmul")
16321 (const_string "fop")))
16322 (set_attr "mode" "<MODE>")])
16324 (define_insn "*fop_<mode>_1_mixed_avx"
16325 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16326 (match_operator:MODEF 3 "binary_fp_operator"
16327 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16328 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16329 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16330 && !COMMUTATIVE_ARITH_P (operands[3])
16331 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16332 "* return output_387_binary_op (insn, operands);"
16333 [(set (attr "type")
16334 (cond [(and (eq_attr "alternative" "2")
16335 (match_operand:MODEF 3 "mult_operator" ""))
16336 (const_string "ssemul")
16337 (and (eq_attr "alternative" "2")
16338 (match_operand:MODEF 3 "div_operator" ""))
16339 (const_string "ssediv")
16340 (eq_attr "alternative" "2")
16341 (const_string "sseadd")
16342 (match_operand:MODEF 3 "mult_operator" "")
16343 (const_string "fmul")
16344 (match_operand:MODEF 3 "div_operator" "")
16345 (const_string "fdiv")
16347 (const_string "fop")))
16348 (set_attr "prefix" "orig,orig,maybe_vex")
16349 (set_attr "mode" "<MODE>")])
16351 (define_insn "*fop_<mode>_1_mixed"
16352 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16353 (match_operator:MODEF 3 "binary_fp_operator"
16354 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16355 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16356 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16357 && !COMMUTATIVE_ARITH_P (operands[3])
16358 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16359 "* return output_387_binary_op (insn, operands);"
16360 [(set (attr "type")
16361 (cond [(and (eq_attr "alternative" "2")
16362 (match_operand:MODEF 3 "mult_operator" ""))
16363 (const_string "ssemul")
16364 (and (eq_attr "alternative" "2")
16365 (match_operand:MODEF 3 "div_operator" ""))
16366 (const_string "ssediv")
16367 (eq_attr "alternative" "2")
16368 (const_string "sseadd")
16369 (match_operand:MODEF 3 "mult_operator" "")
16370 (const_string "fmul")
16371 (match_operand:MODEF 3 "div_operator" "")
16372 (const_string "fdiv")
16374 (const_string "fop")))
16375 (set_attr "mode" "<MODE>")])
16377 (define_insn "*rcpsf2_sse"
16378 [(set (match_operand:SF 0 "register_operand" "=x")
16379 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16382 "%vrcpss\t{%1, %d0|%d0, %1}"
16383 [(set_attr "type" "sse")
16384 (set_attr "prefix" "maybe_vex")
16385 (set_attr "mode" "SF")])
16387 (define_insn "*fop_<mode>_1_avx"
16388 [(set (match_operand:MODEF 0 "register_operand" "=x")
16389 (match_operator:MODEF 3 "binary_fp_operator"
16390 [(match_operand:MODEF 1 "register_operand" "x")
16391 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16392 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16393 && !COMMUTATIVE_ARITH_P (operands[3])"
16394 "* return output_387_binary_op (insn, operands);"
16395 [(set (attr "type")
16396 (cond [(match_operand:MODEF 3 "mult_operator" "")
16397 (const_string "ssemul")
16398 (match_operand:MODEF 3 "div_operator" "")
16399 (const_string "ssediv")
16401 (const_string "sseadd")))
16402 (set_attr "prefix" "vex")
16403 (set_attr "mode" "<MODE>")])
16405 (define_insn "*fop_<mode>_1_sse"
16406 [(set (match_operand:MODEF 0 "register_operand" "=x")
16407 (match_operator:MODEF 3 "binary_fp_operator"
16408 [(match_operand:MODEF 1 "register_operand" "0")
16409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16410 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16411 && !COMMUTATIVE_ARITH_P (operands[3])"
16412 "* return output_387_binary_op (insn, operands);"
16413 [(set (attr "type")
16414 (cond [(match_operand:MODEF 3 "mult_operator" "")
16415 (const_string "ssemul")
16416 (match_operand:MODEF 3 "div_operator" "")
16417 (const_string "ssediv")
16419 (const_string "sseadd")))
16420 (set_attr "mode" "<MODE>")])
16422 ;; This pattern is not fully shadowed by the pattern above.
16423 (define_insn "*fop_<mode>_1_i387"
16424 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16425 (match_operator:MODEF 3 "binary_fp_operator"
16426 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16427 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16428 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429 && !COMMUTATIVE_ARITH_P (operands[3])
16430 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16431 "* return output_387_binary_op (insn, operands);"
16432 [(set (attr "type")
16433 (cond [(match_operand:MODEF 3 "mult_operator" "")
16434 (const_string "fmul")
16435 (match_operand:MODEF 3 "div_operator" "")
16436 (const_string "fdiv")
16438 (const_string "fop")))
16439 (set_attr "mode" "<MODE>")])
16441 ;; ??? Add SSE splitters for these!
16442 (define_insn "*fop_<MODEF:mode>_2_i387"
16443 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16444 (match_operator:MODEF 3 "binary_fp_operator"
16446 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16447 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16448 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16449 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16450 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16451 [(set (attr "type")
16452 (cond [(match_operand:MODEF 3 "mult_operator" "")
16453 (const_string "fmul")
16454 (match_operand:MODEF 3 "div_operator" "")
16455 (const_string "fdiv")
16457 (const_string "fop")))
16458 (set_attr "fp_int_src" "true")
16459 (set_attr "mode" "<X87MODEI12:MODE>")])
16461 (define_insn "*fop_<MODEF:mode>_3_i387"
16462 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16463 (match_operator:MODEF 3 "binary_fp_operator"
16464 [(match_operand:MODEF 1 "register_operand" "0,0")
16466 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16467 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16468 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16469 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16470 [(set (attr "type")
16471 (cond [(match_operand:MODEF 3 "mult_operator" "")
16472 (const_string "fmul")
16473 (match_operand:MODEF 3 "div_operator" "")
16474 (const_string "fdiv")
16476 (const_string "fop")))
16477 (set_attr "fp_int_src" "true")
16478 (set_attr "mode" "<MODE>")])
16480 (define_insn "*fop_df_4_i387"
16481 [(set (match_operand:DF 0 "register_operand" "=f,f")
16482 (match_operator:DF 3 "binary_fp_operator"
16484 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16485 (match_operand:DF 2 "register_operand" "0,f")]))]
16486 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16487 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16488 "* return output_387_binary_op (insn, operands);"
16489 [(set (attr "type")
16490 (cond [(match_operand:DF 3 "mult_operator" "")
16491 (const_string "fmul")
16492 (match_operand:DF 3 "div_operator" "")
16493 (const_string "fdiv")
16495 (const_string "fop")))
16496 (set_attr "mode" "SF")])
16498 (define_insn "*fop_df_5_i387"
16499 [(set (match_operand:DF 0 "register_operand" "=f,f")
16500 (match_operator:DF 3 "binary_fp_operator"
16501 [(match_operand:DF 1 "register_operand" "0,f")
16503 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16504 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16505 "* return output_387_binary_op (insn, operands);"
16506 [(set (attr "type")
16507 (cond [(match_operand:DF 3 "mult_operator" "")
16508 (const_string "fmul")
16509 (match_operand:DF 3 "div_operator" "")
16510 (const_string "fdiv")
16512 (const_string "fop")))
16513 (set_attr "mode" "SF")])
16515 (define_insn "*fop_df_6_i387"
16516 [(set (match_operand:DF 0 "register_operand" "=f,f")
16517 (match_operator:DF 3 "binary_fp_operator"
16519 (match_operand:SF 1 "register_operand" "0,f"))
16521 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16522 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16523 "* return output_387_binary_op (insn, operands);"
16524 [(set (attr "type")
16525 (cond [(match_operand:DF 3 "mult_operator" "")
16526 (const_string "fmul")
16527 (match_operand:DF 3 "div_operator" "")
16528 (const_string "fdiv")
16530 (const_string "fop")))
16531 (set_attr "mode" "SF")])
16533 (define_insn "*fop_xf_comm_i387"
16534 [(set (match_operand:XF 0 "register_operand" "=f")
16535 (match_operator:XF 3 "binary_fp_operator"
16536 [(match_operand:XF 1 "register_operand" "%0")
16537 (match_operand:XF 2 "register_operand" "f")]))]
16539 && COMMUTATIVE_ARITH_P (operands[3])"
16540 "* return output_387_binary_op (insn, operands);"
16541 [(set (attr "type")
16542 (if_then_else (match_operand:XF 3 "mult_operator" "")
16543 (const_string "fmul")
16544 (const_string "fop")))
16545 (set_attr "mode" "XF")])
16547 (define_insn "*fop_xf_1_i387"
16548 [(set (match_operand:XF 0 "register_operand" "=f,f")
16549 (match_operator:XF 3 "binary_fp_operator"
16550 [(match_operand:XF 1 "register_operand" "0,f")
16551 (match_operand:XF 2 "register_operand" "f,0")]))]
16553 && !COMMUTATIVE_ARITH_P (operands[3])"
16554 "* return output_387_binary_op (insn, operands);"
16555 [(set (attr "type")
16556 (cond [(match_operand:XF 3 "mult_operator" "")
16557 (const_string "fmul")
16558 (match_operand:XF 3 "div_operator" "")
16559 (const_string "fdiv")
16561 (const_string "fop")))
16562 (set_attr "mode" "XF")])
16564 (define_insn "*fop_xf_2_i387"
16565 [(set (match_operand:XF 0 "register_operand" "=f,f")
16566 (match_operator:XF 3 "binary_fp_operator"
16568 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16569 (match_operand:XF 2 "register_operand" "0,0")]))]
16570 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16571 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16572 [(set (attr "type")
16573 (cond [(match_operand:XF 3 "mult_operator" "")
16574 (const_string "fmul")
16575 (match_operand:XF 3 "div_operator" "")
16576 (const_string "fdiv")
16578 (const_string "fop")))
16579 (set_attr "fp_int_src" "true")
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "*fop_xf_3_i387"
16583 [(set (match_operand:XF 0 "register_operand" "=f,f")
16584 (match_operator:XF 3 "binary_fp_operator"
16585 [(match_operand:XF 1 "register_operand" "0,0")
16587 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16588 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16589 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16590 [(set (attr "type")
16591 (cond [(match_operand:XF 3 "mult_operator" "")
16592 (const_string "fmul")
16593 (match_operand:XF 3 "div_operator" "")
16594 (const_string "fdiv")
16596 (const_string "fop")))
16597 (set_attr "fp_int_src" "true")
16598 (set_attr "mode" "<MODE>")])
16600 (define_insn "*fop_xf_4_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f,f")
16602 (match_operator:XF 3 "binary_fp_operator"
16604 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16605 (match_operand:XF 2 "register_operand" "0,f")]))]
16607 "* return output_387_binary_op (insn, operands);"
16608 [(set (attr "type")
16609 (cond [(match_operand:XF 3 "mult_operator" "")
16610 (const_string "fmul")
16611 (match_operand:XF 3 "div_operator" "")
16612 (const_string "fdiv")
16614 (const_string "fop")))
16615 (set_attr "mode" "<MODE>")])
16617 (define_insn "*fop_xf_5_i387"
16618 [(set (match_operand:XF 0 "register_operand" "=f,f")
16619 (match_operator:XF 3 "binary_fp_operator"
16620 [(match_operand:XF 1 "register_operand" "0,f")
16622 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16624 "* return output_387_binary_op (insn, operands);"
16625 [(set (attr "type")
16626 (cond [(match_operand:XF 3 "mult_operator" "")
16627 (const_string "fmul")
16628 (match_operand:XF 3 "div_operator" "")
16629 (const_string "fdiv")
16631 (const_string "fop")))
16632 (set_attr "mode" "<MODE>")])
16634 (define_insn "*fop_xf_6_i387"
16635 [(set (match_operand:XF 0 "register_operand" "=f,f")
16636 (match_operator:XF 3 "binary_fp_operator"
16638 (match_operand:MODEF 1 "register_operand" "0,f"))
16640 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16642 "* return output_387_binary_op (insn, operands);"
16643 [(set (attr "type")
16644 (cond [(match_operand:XF 3 "mult_operator" "")
16645 (const_string "fmul")
16646 (match_operand:XF 3 "div_operator" "")
16647 (const_string "fdiv")
16649 (const_string "fop")))
16650 (set_attr "mode" "<MODE>")])
16653 [(set (match_operand 0 "register_operand" "")
16654 (match_operator 3 "binary_fp_operator"
16655 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16656 (match_operand 2 "register_operand" "")]))]
16658 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16661 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16662 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16663 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16664 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16665 GET_MODE (operands[3]),
16668 ix86_free_from_memory (GET_MODE (operands[1]));
16673 [(set (match_operand 0 "register_operand" "")
16674 (match_operator 3 "binary_fp_operator"
16675 [(match_operand 1 "register_operand" "")
16676 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16678 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16681 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16682 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16683 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16684 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16685 GET_MODE (operands[3]),
16688 ix86_free_from_memory (GET_MODE (operands[2]));
16692 ;; FPU special functions.
16694 ;; This pattern implements a no-op XFmode truncation for
16695 ;; all fancy i386 XFmode math functions.
16697 (define_insn "truncxf<mode>2_i387_noop_unspec"
16698 [(set (match_operand:MODEF 0 "register_operand" "=f")
16699 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16700 UNSPEC_TRUNC_NOOP))]
16701 "TARGET_USE_FANCY_MATH_387"
16702 "* return output_387_reg_move (insn, operands);"
16703 [(set_attr "type" "fmov")
16704 (set_attr "mode" "<MODE>")])
16706 (define_insn "sqrtxf2"
16707 [(set (match_operand:XF 0 "register_operand" "=f")
16708 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16709 "TARGET_USE_FANCY_MATH_387"
16711 [(set_attr "type" "fpspc")
16712 (set_attr "mode" "XF")
16713 (set_attr "athlon_decode" "direct")
16714 (set_attr "amdfam10_decode" "direct")])
16716 (define_insn "sqrt_extend<mode>xf2_i387"
16717 [(set (match_operand:XF 0 "register_operand" "=f")
16720 (match_operand:MODEF 1 "register_operand" "0"))))]
16721 "TARGET_USE_FANCY_MATH_387"
16723 [(set_attr "type" "fpspc")
16724 (set_attr "mode" "XF")
16725 (set_attr "athlon_decode" "direct")
16726 (set_attr "amdfam10_decode" "direct")])
16728 (define_insn "*rsqrtsf2_sse"
16729 [(set (match_operand:SF 0 "register_operand" "=x")
16730 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16733 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16734 [(set_attr "type" "sse")
16735 (set_attr "prefix" "maybe_vex")
16736 (set_attr "mode" "SF")])
16738 (define_expand "rsqrtsf2"
16739 [(set (match_operand:SF 0 "register_operand" "")
16740 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16744 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16748 (define_insn "*sqrt<mode>2_sse"
16749 [(set (match_operand:MODEF 0 "register_operand" "=x")
16751 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16752 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16753 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16754 [(set_attr "type" "sse")
16755 (set_attr "prefix" "maybe_vex")
16756 (set_attr "mode" "<MODE>")
16757 (set_attr "athlon_decode" "*")
16758 (set_attr "amdfam10_decode" "*")])
16760 (define_expand "sqrt<mode>2"
16761 [(set (match_operand:MODEF 0 "register_operand" "")
16763 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16764 "TARGET_USE_FANCY_MATH_387
16765 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16767 if (<MODE>mode == SFmode
16768 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16769 && flag_finite_math_only && !flag_trapping_math
16770 && flag_unsafe_math_optimizations)
16772 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16776 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16778 rtx op0 = gen_reg_rtx (XFmode);
16779 rtx op1 = force_reg (<MODE>mode, operands[1]);
16781 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16782 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16787 (define_insn "fpremxf4_i387"
16788 [(set (match_operand:XF 0 "register_operand" "=f")
16789 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16790 (match_operand:XF 3 "register_operand" "1")]
16792 (set (match_operand:XF 1 "register_operand" "=u")
16793 (unspec:XF [(match_dup 2) (match_dup 3)]
16795 (set (reg:CCFP FPSR_REG)
16796 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16798 "TARGET_USE_FANCY_MATH_387"
16800 [(set_attr "type" "fpspc")
16801 (set_attr "mode" "XF")])
16803 (define_expand "fmodxf3"
16804 [(use (match_operand:XF 0 "register_operand" ""))
16805 (use (match_operand:XF 1 "general_operand" ""))
16806 (use (match_operand:XF 2 "general_operand" ""))]
16807 "TARGET_USE_FANCY_MATH_387"
16809 rtx label = gen_label_rtx ();
16811 rtx op1 = gen_reg_rtx (XFmode);
16812 rtx op2 = gen_reg_rtx (XFmode);
16814 emit_move_insn (op2, operands[2]);
16815 emit_move_insn (op1, operands[1]);
16817 emit_label (label);
16818 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16819 ix86_emit_fp_unordered_jump (label);
16820 LABEL_NUSES (label) = 1;
16822 emit_move_insn (operands[0], op1);
16826 (define_expand "fmod<mode>3"
16827 [(use (match_operand:MODEF 0 "register_operand" ""))
16828 (use (match_operand:MODEF 1 "general_operand" ""))
16829 (use (match_operand:MODEF 2 "general_operand" ""))]
16830 "TARGET_USE_FANCY_MATH_387"
16832 rtx label = gen_label_rtx ();
16834 rtx op1 = gen_reg_rtx (XFmode);
16835 rtx op2 = gen_reg_rtx (XFmode);
16837 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16840 emit_label (label);
16841 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16842 ix86_emit_fp_unordered_jump (label);
16843 LABEL_NUSES (label) = 1;
16845 /* Truncate the result properly for strict SSE math. */
16846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16847 && !TARGET_MIX_SSE_I387)
16848 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16850 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16855 (define_insn "fprem1xf4_i387"
16856 [(set (match_operand:XF 0 "register_operand" "=f")
16857 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16858 (match_operand:XF 3 "register_operand" "1")]
16860 (set (match_operand:XF 1 "register_operand" "=u")
16861 (unspec:XF [(match_dup 2) (match_dup 3)]
16863 (set (reg:CCFP FPSR_REG)
16864 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16866 "TARGET_USE_FANCY_MATH_387"
16868 [(set_attr "type" "fpspc")
16869 (set_attr "mode" "XF")])
16871 (define_expand "remainderxf3"
16872 [(use (match_operand:XF 0 "register_operand" ""))
16873 (use (match_operand:XF 1 "general_operand" ""))
16874 (use (match_operand:XF 2 "general_operand" ""))]
16875 "TARGET_USE_FANCY_MATH_387"
16877 rtx label = gen_label_rtx ();
16879 rtx op1 = gen_reg_rtx (XFmode);
16880 rtx op2 = gen_reg_rtx (XFmode);
16882 emit_move_insn (op2, operands[2]);
16883 emit_move_insn (op1, operands[1]);
16885 emit_label (label);
16886 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16887 ix86_emit_fp_unordered_jump (label);
16888 LABEL_NUSES (label) = 1;
16890 emit_move_insn (operands[0], op1);
16894 (define_expand "remainder<mode>3"
16895 [(use (match_operand:MODEF 0 "register_operand" ""))
16896 (use (match_operand:MODEF 1 "general_operand" ""))
16897 (use (match_operand:MODEF 2 "general_operand" ""))]
16898 "TARGET_USE_FANCY_MATH_387"
16900 rtx label = gen_label_rtx ();
16902 rtx op1 = gen_reg_rtx (XFmode);
16903 rtx op2 = gen_reg_rtx (XFmode);
16905 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16908 emit_label (label);
16910 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16911 ix86_emit_fp_unordered_jump (label);
16912 LABEL_NUSES (label) = 1;
16914 /* Truncate the result properly for strict SSE math. */
16915 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16916 && !TARGET_MIX_SSE_I387)
16917 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16919 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16924 (define_insn "*sinxf2_i387"
16925 [(set (match_operand:XF 0 "register_operand" "=f")
16926 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && flag_unsafe_math_optimizations"
16930 [(set_attr "type" "fpspc")
16931 (set_attr "mode" "XF")])
16933 (define_insn "*sin_extend<mode>xf2_i387"
16934 [(set (match_operand:XF 0 "register_operand" "=f")
16935 (unspec:XF [(float_extend:XF
16936 (match_operand:MODEF 1 "register_operand" "0"))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16940 || TARGET_MIX_SSE_I387)
16941 && flag_unsafe_math_optimizations"
16943 [(set_attr "type" "fpspc")
16944 (set_attr "mode" "XF")])
16946 (define_insn "*cosxf2_i387"
16947 [(set (match_operand:XF 0 "register_operand" "=f")
16948 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations"
16952 [(set_attr "type" "fpspc")
16953 (set_attr "mode" "XF")])
16955 (define_insn "*cos_extend<mode>xf2_i387"
16956 [(set (match_operand:XF 0 "register_operand" "=f")
16957 (unspec:XF [(float_extend:XF
16958 (match_operand:MODEF 1 "register_operand" "0"))]
16960 "TARGET_USE_FANCY_MATH_387
16961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16962 || TARGET_MIX_SSE_I387)
16963 && flag_unsafe_math_optimizations"
16965 [(set_attr "type" "fpspc")
16966 (set_attr "mode" "XF")])
16968 ;; When sincos pattern is defined, sin and cos builtin functions will be
16969 ;; expanded to sincos pattern with one of its outputs left unused.
16970 ;; CSE pass will figure out if two sincos patterns can be combined,
16971 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16972 ;; depending on the unused output.
16974 (define_insn "sincosxf3"
16975 [(set (match_operand:XF 0 "register_operand" "=f")
16976 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16977 UNSPEC_SINCOS_COS))
16978 (set (match_operand:XF 1 "register_operand" "=u")
16979 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && flag_unsafe_math_optimizations"
16983 [(set_attr "type" "fpspc")
16984 (set_attr "mode" "XF")])
16987 [(set (match_operand:XF 0 "register_operand" "")
16988 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16989 UNSPEC_SINCOS_COS))
16990 (set (match_operand:XF 1 "register_operand" "")
16991 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16992 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16993 && !(reload_completed || reload_in_progress)"
16994 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16998 [(set (match_operand:XF 0 "register_operand" "")
16999 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17000 UNSPEC_SINCOS_COS))
17001 (set (match_operand:XF 1 "register_operand" "")
17002 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17003 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17004 && !(reload_completed || reload_in_progress)"
17005 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17008 (define_insn "sincos_extend<mode>xf3_i387"
17009 [(set (match_operand:XF 0 "register_operand" "=f")
17010 (unspec:XF [(float_extend:XF
17011 (match_operand:MODEF 2 "register_operand" "0"))]
17012 UNSPEC_SINCOS_COS))
17013 (set (match_operand:XF 1 "register_operand" "=u")
17014 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015 "TARGET_USE_FANCY_MATH_387
17016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017 || TARGET_MIX_SSE_I387)
17018 && flag_unsafe_math_optimizations"
17020 [(set_attr "type" "fpspc")
17021 (set_attr "mode" "XF")])
17024 [(set (match_operand:XF 0 "register_operand" "")
17025 (unspec:XF [(float_extend:XF
17026 (match_operand:MODEF 2 "register_operand" ""))]
17027 UNSPEC_SINCOS_COS))
17028 (set (match_operand:XF 1 "register_operand" "")
17029 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17030 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17031 && !(reload_completed || reload_in_progress)"
17032 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17036 [(set (match_operand:XF 0 "register_operand" "")
17037 (unspec:XF [(float_extend:XF
17038 (match_operand:MODEF 2 "register_operand" ""))]
17039 UNSPEC_SINCOS_COS))
17040 (set (match_operand:XF 1 "register_operand" "")
17041 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17042 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17043 && !(reload_completed || reload_in_progress)"
17044 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17047 (define_expand "sincos<mode>3"
17048 [(use (match_operand:MODEF 0 "register_operand" ""))
17049 (use (match_operand:MODEF 1 "register_operand" ""))
17050 (use (match_operand:MODEF 2 "register_operand" ""))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053 || TARGET_MIX_SSE_I387)
17054 && flag_unsafe_math_optimizations"
17056 rtx op0 = gen_reg_rtx (XFmode);
17057 rtx op1 = gen_reg_rtx (XFmode);
17059 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17065 (define_insn "fptanxf4_i387"
17066 [(set (match_operand:XF 0 "register_operand" "=f")
17067 (match_operand:XF 3 "const_double_operand" "F"))
17068 (set (match_operand:XF 1 "register_operand" "=u")
17069 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations
17073 && standard_80387_constant_p (operands[3]) == 2"
17075 [(set_attr "type" "fpspc")
17076 (set_attr "mode" "XF")])
17078 (define_insn "fptan_extend<mode>xf4_i387"
17079 [(set (match_operand:MODEF 0 "register_operand" "=f")
17080 (match_operand:MODEF 3 "const_double_operand" "F"))
17081 (set (match_operand:XF 1 "register_operand" "=u")
17082 (unspec:XF [(float_extend:XF
17083 (match_operand:MODEF 2 "register_operand" "0"))]
17085 "TARGET_USE_FANCY_MATH_387
17086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17087 || TARGET_MIX_SSE_I387)
17088 && flag_unsafe_math_optimizations
17089 && standard_80387_constant_p (operands[3]) == 2"
17091 [(set_attr "type" "fpspc")
17092 (set_attr "mode" "XF")])
17094 (define_expand "tanxf2"
17095 [(use (match_operand:XF 0 "register_operand" ""))
17096 (use (match_operand:XF 1 "register_operand" ""))]
17097 "TARGET_USE_FANCY_MATH_387
17098 && flag_unsafe_math_optimizations"
17100 rtx one = gen_reg_rtx (XFmode);
17101 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17103 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17107 (define_expand "tan<mode>2"
17108 [(use (match_operand:MODEF 0 "register_operand" ""))
17109 (use (match_operand:MODEF 1 "register_operand" ""))]
17110 "TARGET_USE_FANCY_MATH_387
17111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17112 || TARGET_MIX_SSE_I387)
17113 && flag_unsafe_math_optimizations"
17115 rtx op0 = gen_reg_rtx (XFmode);
17117 rtx one = gen_reg_rtx (<MODE>mode);
17118 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17120 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17121 operands[1], op2));
17122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17126 (define_insn "*fpatanxf3_i387"
17127 [(set (match_operand:XF 0 "register_operand" "=f")
17128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17129 (match_operand:XF 2 "register_operand" "u")]
17131 (clobber (match_scratch:XF 3 "=2"))]
17132 "TARGET_USE_FANCY_MATH_387
17133 && flag_unsafe_math_optimizations"
17135 [(set_attr "type" "fpspc")
17136 (set_attr "mode" "XF")])
17138 (define_insn "fpatan_extend<mode>xf3_i387"
17139 [(set (match_operand:XF 0 "register_operand" "=f")
17140 (unspec:XF [(float_extend:XF
17141 (match_operand:MODEF 1 "register_operand" "0"))
17143 (match_operand:MODEF 2 "register_operand" "u"))]
17145 (clobber (match_scratch:XF 3 "=2"))]
17146 "TARGET_USE_FANCY_MATH_387
17147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148 || TARGET_MIX_SSE_I387)
17149 && flag_unsafe_math_optimizations"
17151 [(set_attr "type" "fpspc")
17152 (set_attr "mode" "XF")])
17154 (define_expand "atan2xf3"
17155 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17156 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17157 (match_operand:XF 1 "register_operand" "")]
17159 (clobber (match_scratch:XF 3 ""))])]
17160 "TARGET_USE_FANCY_MATH_387
17161 && flag_unsafe_math_optimizations"
17164 (define_expand "atan2<mode>3"
17165 [(use (match_operand:MODEF 0 "register_operand" ""))
17166 (use (match_operand:MODEF 1 "register_operand" ""))
17167 (use (match_operand:MODEF 2 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17170 || TARGET_MIX_SSE_I387)
17171 && flag_unsafe_math_optimizations"
17173 rtx op0 = gen_reg_rtx (XFmode);
17175 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17176 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17180 (define_expand "atanxf2"
17181 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17182 (unspec:XF [(match_dup 2)
17183 (match_operand:XF 1 "register_operand" "")]
17185 (clobber (match_scratch:XF 3 ""))])]
17186 "TARGET_USE_FANCY_MATH_387
17187 && flag_unsafe_math_optimizations"
17189 operands[2] = gen_reg_rtx (XFmode);
17190 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17193 (define_expand "atan<mode>2"
17194 [(use (match_operand:MODEF 0 "register_operand" ""))
17195 (use (match_operand:MODEF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198 || TARGET_MIX_SSE_I387)
17199 && flag_unsafe_math_optimizations"
17201 rtx op0 = gen_reg_rtx (XFmode);
17203 rtx op2 = gen_reg_rtx (<MODE>mode);
17204 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17206 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17211 (define_expand "asinxf2"
17212 [(set (match_dup 2)
17213 (mult:XF (match_operand:XF 1 "register_operand" "")
17215 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17216 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17217 (parallel [(set (match_operand:XF 0 "register_operand" "")
17218 (unspec:XF [(match_dup 5) (match_dup 1)]
17220 (clobber (match_scratch:XF 6 ""))])]
17221 "TARGET_USE_FANCY_MATH_387
17222 && flag_unsafe_math_optimizations"
17226 if (optimize_insn_for_size_p ())
17229 for (i = 2; i < 6; i++)
17230 operands[i] = gen_reg_rtx (XFmode);
17232 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17235 (define_expand "asin<mode>2"
17236 [(use (match_operand:MODEF 0 "register_operand" ""))
17237 (use (match_operand:MODEF 1 "general_operand" ""))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17240 || TARGET_MIX_SSE_I387)
17241 && flag_unsafe_math_optimizations"
17243 rtx op0 = gen_reg_rtx (XFmode);
17244 rtx op1 = gen_reg_rtx (XFmode);
17246 if (optimize_insn_for_size_p ())
17249 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17250 emit_insn (gen_asinxf2 (op0, op1));
17251 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17255 (define_expand "acosxf2"
17256 [(set (match_dup 2)
17257 (mult:XF (match_operand:XF 1 "register_operand" "")
17259 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17260 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17261 (parallel [(set (match_operand:XF 0 "register_operand" "")
17262 (unspec:XF [(match_dup 1) (match_dup 5)]
17264 (clobber (match_scratch:XF 6 ""))])]
17265 "TARGET_USE_FANCY_MATH_387
17266 && flag_unsafe_math_optimizations"
17270 if (optimize_insn_for_size_p ())
17273 for (i = 2; i < 6; i++)
17274 operands[i] = gen_reg_rtx (XFmode);
17276 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17279 (define_expand "acos<mode>2"
17280 [(use (match_operand:MODEF 0 "register_operand" ""))
17281 (use (match_operand:MODEF 1 "general_operand" ""))]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284 || TARGET_MIX_SSE_I387)
17285 && flag_unsafe_math_optimizations"
17287 rtx op0 = gen_reg_rtx (XFmode);
17288 rtx op1 = gen_reg_rtx (XFmode);
17290 if (optimize_insn_for_size_p ())
17293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294 emit_insn (gen_acosxf2 (op0, op1));
17295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17299 (define_insn "fyl2xxf3_i387"
17300 [(set (match_operand:XF 0 "register_operand" "=f")
17301 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17302 (match_operand:XF 2 "register_operand" "u")]
17304 (clobber (match_scratch:XF 3 "=2"))]
17305 "TARGET_USE_FANCY_MATH_387
17306 && flag_unsafe_math_optimizations"
17308 [(set_attr "type" "fpspc")
17309 (set_attr "mode" "XF")])
17311 (define_insn "fyl2x_extend<mode>xf3_i387"
17312 [(set (match_operand:XF 0 "register_operand" "=f")
17313 (unspec:XF [(float_extend:XF
17314 (match_operand:MODEF 1 "register_operand" "0"))
17315 (match_operand:XF 2 "register_operand" "u")]
17317 (clobber (match_scratch:XF 3 "=2"))]
17318 "TARGET_USE_FANCY_MATH_387
17319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17320 || TARGET_MIX_SSE_I387)
17321 && flag_unsafe_math_optimizations"
17323 [(set_attr "type" "fpspc")
17324 (set_attr "mode" "XF")])
17326 (define_expand "logxf2"
17327 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329 (match_dup 2)] UNSPEC_FYL2X))
17330 (clobber (match_scratch:XF 3 ""))])]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations"
17334 operands[2] = gen_reg_rtx (XFmode);
17335 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17338 (define_expand "log<mode>2"
17339 [(use (match_operand:MODEF 0 "register_operand" ""))
17340 (use (match_operand:MODEF 1 "register_operand" ""))]
17341 "TARGET_USE_FANCY_MATH_387
17342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343 || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations"
17346 rtx op0 = gen_reg_rtx (XFmode);
17348 rtx op2 = gen_reg_rtx (XFmode);
17349 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17351 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17356 (define_expand "log10xf2"
17357 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359 (match_dup 2)] UNSPEC_FYL2X))
17360 (clobber (match_scratch:XF 3 ""))])]
17361 "TARGET_USE_FANCY_MATH_387
17362 && flag_unsafe_math_optimizations"
17364 operands[2] = gen_reg_rtx (XFmode);
17365 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17368 (define_expand "log10<mode>2"
17369 [(use (match_operand:MODEF 0 "register_operand" ""))
17370 (use (match_operand:MODEF 1 "register_operand" ""))]
17371 "TARGET_USE_FANCY_MATH_387
17372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373 || TARGET_MIX_SSE_I387)
17374 && flag_unsafe_math_optimizations"
17376 rtx op0 = gen_reg_rtx (XFmode);
17378 rtx op2 = gen_reg_rtx (XFmode);
17379 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17381 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17386 (define_expand "log2xf2"
17387 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17388 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17389 (match_dup 2)] UNSPEC_FYL2X))
17390 (clobber (match_scratch:XF 3 ""))])]
17391 "TARGET_USE_FANCY_MATH_387
17392 && flag_unsafe_math_optimizations"
17394 operands[2] = gen_reg_rtx (XFmode);
17395 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17398 (define_expand "log2<mode>2"
17399 [(use (match_operand:MODEF 0 "register_operand" ""))
17400 (use (match_operand:MODEF 1 "register_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403 || TARGET_MIX_SSE_I387)
17404 && flag_unsafe_math_optimizations"
17406 rtx op0 = gen_reg_rtx (XFmode);
17408 rtx op2 = gen_reg_rtx (XFmode);
17409 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17411 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17416 (define_insn "fyl2xp1xf3_i387"
17417 [(set (match_operand:XF 0 "register_operand" "=f")
17418 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17419 (match_operand:XF 2 "register_operand" "u")]
17421 (clobber (match_scratch:XF 3 "=2"))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && flag_unsafe_math_optimizations"
17425 [(set_attr "type" "fpspc")
17426 (set_attr "mode" "XF")])
17428 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17429 [(set (match_operand:XF 0 "register_operand" "=f")
17430 (unspec:XF [(float_extend:XF
17431 (match_operand:MODEF 1 "register_operand" "0"))
17432 (match_operand:XF 2 "register_operand" "u")]
17434 (clobber (match_scratch:XF 3 "=2"))]
17435 "TARGET_USE_FANCY_MATH_387
17436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437 || TARGET_MIX_SSE_I387)
17438 && flag_unsafe_math_optimizations"
17440 [(set_attr "type" "fpspc")
17441 (set_attr "mode" "XF")])
17443 (define_expand "log1pxf2"
17444 [(use (match_operand:XF 0 "register_operand" ""))
17445 (use (match_operand:XF 1 "register_operand" ""))]
17446 "TARGET_USE_FANCY_MATH_387
17447 && flag_unsafe_math_optimizations"
17449 if (optimize_insn_for_size_p ())
17452 ix86_emit_i387_log1p (operands[0], operands[1]);
17456 (define_expand "log1p<mode>2"
17457 [(use (match_operand:MODEF 0 "register_operand" ""))
17458 (use (match_operand:MODEF 1 "register_operand" ""))]
17459 "TARGET_USE_FANCY_MATH_387
17460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17461 || TARGET_MIX_SSE_I387)
17462 && flag_unsafe_math_optimizations"
17466 if (optimize_insn_for_size_p ())
17469 op0 = gen_reg_rtx (XFmode);
17471 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17473 ix86_emit_i387_log1p (op0, operands[1]);
17474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17478 (define_insn "fxtractxf3_i387"
17479 [(set (match_operand:XF 0 "register_operand" "=f")
17480 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17481 UNSPEC_XTRACT_FRACT))
17482 (set (match_operand:XF 1 "register_operand" "=u")
17483 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17484 "TARGET_USE_FANCY_MATH_387
17485 && flag_unsafe_math_optimizations"
17487 [(set_attr "type" "fpspc")
17488 (set_attr "mode" "XF")])
17490 (define_insn "fxtract_extend<mode>xf3_i387"
17491 [(set (match_operand:XF 0 "register_operand" "=f")
17492 (unspec:XF [(float_extend:XF
17493 (match_operand:MODEF 2 "register_operand" "0"))]
17494 UNSPEC_XTRACT_FRACT))
17495 (set (match_operand:XF 1 "register_operand" "=u")
17496 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17497 "TARGET_USE_FANCY_MATH_387
17498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17499 || TARGET_MIX_SSE_I387)
17500 && flag_unsafe_math_optimizations"
17502 [(set_attr "type" "fpspc")
17503 (set_attr "mode" "XF")])
17505 (define_expand "logbxf2"
17506 [(parallel [(set (match_dup 2)
17507 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17508 UNSPEC_XTRACT_FRACT))
17509 (set (match_operand:XF 0 "register_operand" "")
17510 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17511 "TARGET_USE_FANCY_MATH_387
17512 && flag_unsafe_math_optimizations"
17514 operands[2] = gen_reg_rtx (XFmode);
17517 (define_expand "logb<mode>2"
17518 [(use (match_operand:MODEF 0 "register_operand" ""))
17519 (use (match_operand:MODEF 1 "register_operand" ""))]
17520 "TARGET_USE_FANCY_MATH_387
17521 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17522 || TARGET_MIX_SSE_I387)
17523 && flag_unsafe_math_optimizations"
17525 rtx op0 = gen_reg_rtx (XFmode);
17526 rtx op1 = gen_reg_rtx (XFmode);
17528 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17529 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17533 (define_expand "ilogbxf2"
17534 [(use (match_operand:SI 0 "register_operand" ""))
17535 (use (match_operand:XF 1 "register_operand" ""))]
17536 "TARGET_USE_FANCY_MATH_387
17537 && flag_unsafe_math_optimizations"
17541 if (optimize_insn_for_size_p ())
17544 op0 = gen_reg_rtx (XFmode);
17545 op1 = gen_reg_rtx (XFmode);
17547 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17548 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17552 (define_expand "ilogb<mode>2"
17553 [(use (match_operand:SI 0 "register_operand" ""))
17554 (use (match_operand:MODEF 1 "register_operand" ""))]
17555 "TARGET_USE_FANCY_MATH_387
17556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17557 || TARGET_MIX_SSE_I387)
17558 && flag_unsafe_math_optimizations"
17562 if (optimize_insn_for_size_p ())
17565 op0 = gen_reg_rtx (XFmode);
17566 op1 = gen_reg_rtx (XFmode);
17568 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17569 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17573 (define_insn "*f2xm1xf2_i387"
17574 [(set (match_operand:XF 0 "register_operand" "=f")
17575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17577 "TARGET_USE_FANCY_MATH_387
17578 && flag_unsafe_math_optimizations"
17580 [(set_attr "type" "fpspc")
17581 (set_attr "mode" "XF")])
17583 (define_insn "*fscalexf4_i387"
17584 [(set (match_operand:XF 0 "register_operand" "=f")
17585 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17586 (match_operand:XF 3 "register_operand" "1")]
17587 UNSPEC_FSCALE_FRACT))
17588 (set (match_operand:XF 1 "register_operand" "=u")
17589 (unspec:XF [(match_dup 2) (match_dup 3)]
17590 UNSPEC_FSCALE_EXP))]
17591 "TARGET_USE_FANCY_MATH_387
17592 && flag_unsafe_math_optimizations"
17594 [(set_attr "type" "fpspc")
17595 (set_attr "mode" "XF")])
17597 (define_expand "expNcorexf3"
17598 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17599 (match_operand:XF 2 "register_operand" "")))
17600 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17601 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17602 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17603 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17604 (parallel [(set (match_operand:XF 0 "register_operand" "")
17605 (unspec:XF [(match_dup 8) (match_dup 4)]
17606 UNSPEC_FSCALE_FRACT))
17608 (unspec:XF [(match_dup 8) (match_dup 4)]
17609 UNSPEC_FSCALE_EXP))])]
17610 "TARGET_USE_FANCY_MATH_387
17611 && flag_unsafe_math_optimizations"
17615 if (optimize_insn_for_size_p ())
17618 for (i = 3; i < 10; i++)
17619 operands[i] = gen_reg_rtx (XFmode);
17621 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17624 (define_expand "expxf2"
17625 [(use (match_operand:XF 0 "register_operand" ""))
17626 (use (match_operand:XF 1 "register_operand" ""))]
17627 "TARGET_USE_FANCY_MATH_387
17628 && flag_unsafe_math_optimizations"
17632 if (optimize_insn_for_size_p ())
17635 op2 = gen_reg_rtx (XFmode);
17636 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17638 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17642 (define_expand "exp<mode>2"
17643 [(use (match_operand:MODEF 0 "register_operand" ""))
17644 (use (match_operand:MODEF 1 "general_operand" ""))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17647 || TARGET_MIX_SSE_I387)
17648 && flag_unsafe_math_optimizations"
17652 if (optimize_insn_for_size_p ())
17655 op0 = gen_reg_rtx (XFmode);
17656 op1 = gen_reg_rtx (XFmode);
17658 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17659 emit_insn (gen_expxf2 (op0, op1));
17660 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17664 (define_expand "exp10xf2"
17665 [(use (match_operand:XF 0 "register_operand" ""))
17666 (use (match_operand:XF 1 "register_operand" ""))]
17667 "TARGET_USE_FANCY_MATH_387
17668 && flag_unsafe_math_optimizations"
17672 if (optimize_insn_for_size_p ())
17675 op2 = gen_reg_rtx (XFmode);
17676 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17678 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17682 (define_expand "exp10<mode>2"
17683 [(use (match_operand:MODEF 0 "register_operand" ""))
17684 (use (match_operand:MODEF 1 "general_operand" ""))]
17685 "TARGET_USE_FANCY_MATH_387
17686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17687 || TARGET_MIX_SSE_I387)
17688 && flag_unsafe_math_optimizations"
17692 if (optimize_insn_for_size_p ())
17695 op0 = gen_reg_rtx (XFmode);
17696 op1 = gen_reg_rtx (XFmode);
17698 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17699 emit_insn (gen_exp10xf2 (op0, op1));
17700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17704 (define_expand "exp2xf2"
17705 [(use (match_operand:XF 0 "register_operand" ""))
17706 (use (match_operand:XF 1 "register_operand" ""))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && flag_unsafe_math_optimizations"
17712 if (optimize_insn_for_size_p ())
17715 op2 = gen_reg_rtx (XFmode);
17716 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17718 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17722 (define_expand "exp2<mode>2"
17723 [(use (match_operand:MODEF 0 "register_operand" ""))
17724 (use (match_operand:MODEF 1 "general_operand" ""))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17727 || TARGET_MIX_SSE_I387)
17728 && flag_unsafe_math_optimizations"
17732 if (optimize_insn_for_size_p ())
17735 op0 = gen_reg_rtx (XFmode);
17736 op1 = gen_reg_rtx (XFmode);
17738 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17739 emit_insn (gen_exp2xf2 (op0, op1));
17740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17744 (define_expand "expm1xf2"
17745 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17747 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17748 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17749 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17750 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17751 (parallel [(set (match_dup 7)
17752 (unspec:XF [(match_dup 6) (match_dup 4)]
17753 UNSPEC_FSCALE_FRACT))
17755 (unspec:XF [(match_dup 6) (match_dup 4)]
17756 UNSPEC_FSCALE_EXP))])
17757 (parallel [(set (match_dup 10)
17758 (unspec:XF [(match_dup 9) (match_dup 8)]
17759 UNSPEC_FSCALE_FRACT))
17760 (set (match_dup 11)
17761 (unspec:XF [(match_dup 9) (match_dup 8)]
17762 UNSPEC_FSCALE_EXP))])
17763 (set (match_dup 12) (minus:XF (match_dup 10)
17764 (float_extend:XF (match_dup 13))))
17765 (set (match_operand:XF 0 "register_operand" "")
17766 (plus:XF (match_dup 12) (match_dup 7)))]
17767 "TARGET_USE_FANCY_MATH_387
17768 && flag_unsafe_math_optimizations"
17772 if (optimize_insn_for_size_p ())
17775 for (i = 2; i < 13; i++)
17776 operands[i] = gen_reg_rtx (XFmode);
17779 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17781 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17784 (define_expand "expm1<mode>2"
17785 [(use (match_operand:MODEF 0 "register_operand" ""))
17786 (use (match_operand:MODEF 1 "general_operand" ""))]
17787 "TARGET_USE_FANCY_MATH_387
17788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17789 || TARGET_MIX_SSE_I387)
17790 && flag_unsafe_math_optimizations"
17794 if (optimize_insn_for_size_p ())
17797 op0 = gen_reg_rtx (XFmode);
17798 op1 = gen_reg_rtx (XFmode);
17800 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17801 emit_insn (gen_expm1xf2 (op0, op1));
17802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17806 (define_expand "ldexpxf3"
17807 [(set (match_dup 3)
17808 (float:XF (match_operand:SI 2 "register_operand" "")))
17809 (parallel [(set (match_operand:XF 0 " register_operand" "")
17810 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17812 UNSPEC_FSCALE_FRACT))
17814 (unspec:XF [(match_dup 1) (match_dup 3)]
17815 UNSPEC_FSCALE_EXP))])]
17816 "TARGET_USE_FANCY_MATH_387
17817 && flag_unsafe_math_optimizations"
17819 if (optimize_insn_for_size_p ())
17822 operands[3] = gen_reg_rtx (XFmode);
17823 operands[4] = gen_reg_rtx (XFmode);
17826 (define_expand "ldexp<mode>3"
17827 [(use (match_operand:MODEF 0 "register_operand" ""))
17828 (use (match_operand:MODEF 1 "general_operand" ""))
17829 (use (match_operand:SI 2 "register_operand" ""))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832 || TARGET_MIX_SSE_I387)
17833 && flag_unsafe_math_optimizations"
17837 if (optimize_insn_for_size_p ())
17840 op0 = gen_reg_rtx (XFmode);
17841 op1 = gen_reg_rtx (XFmode);
17843 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17844 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17849 (define_expand "scalbxf3"
17850 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17851 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17852 (match_operand:XF 2 "register_operand" "")]
17853 UNSPEC_FSCALE_FRACT))
17855 (unspec:XF [(match_dup 1) (match_dup 2)]
17856 UNSPEC_FSCALE_EXP))])]
17857 "TARGET_USE_FANCY_MATH_387
17858 && flag_unsafe_math_optimizations"
17860 if (optimize_insn_for_size_p ())
17863 operands[3] = gen_reg_rtx (XFmode);
17866 (define_expand "scalb<mode>3"
17867 [(use (match_operand:MODEF 0 "register_operand" ""))
17868 (use (match_operand:MODEF 1 "general_operand" ""))
17869 (use (match_operand:MODEF 2 "register_operand" ""))]
17870 "TARGET_USE_FANCY_MATH_387
17871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17872 || TARGET_MIX_SSE_I387)
17873 && flag_unsafe_math_optimizations"
17877 if (optimize_insn_for_size_p ())
17880 op0 = gen_reg_rtx (XFmode);
17881 op1 = gen_reg_rtx (XFmode);
17882 op2 = gen_reg_rtx (XFmode);
17884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17885 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17886 emit_insn (gen_scalbxf3 (op0, op1, op2));
17887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17892 (define_insn "sse4_1_round<mode>2"
17893 [(set (match_operand:MODEF 0 "register_operand" "=x")
17894 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17895 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17898 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17899 [(set_attr "type" "ssecvt")
17900 (set_attr "prefix_extra" "1")
17901 (set_attr "prefix" "maybe_vex")
17902 (set_attr "mode" "<MODE>")])
17904 (define_insn "rintxf2"
17905 [(set (match_operand:XF 0 "register_operand" "=f")
17906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17908 "TARGET_USE_FANCY_MATH_387
17909 && flag_unsafe_math_optimizations"
17911 [(set_attr "type" "fpspc")
17912 (set_attr "mode" "XF")])
17914 (define_expand "rint<mode>2"
17915 [(use (match_operand:MODEF 0 "register_operand" ""))
17916 (use (match_operand:MODEF 1 "register_operand" ""))]
17917 "(TARGET_USE_FANCY_MATH_387
17918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17919 || TARGET_MIX_SSE_I387)
17920 && flag_unsafe_math_optimizations)
17921 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922 && !flag_trapping_math)"
17924 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17925 && !flag_trapping_math)
17927 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17930 emit_insn (gen_sse4_1_round<mode>2
17931 (operands[0], operands[1], GEN_INT (0x04)));
17933 ix86_expand_rint (operand0, operand1);
17937 rtx op0 = gen_reg_rtx (XFmode);
17938 rtx op1 = gen_reg_rtx (XFmode);
17940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17941 emit_insn (gen_rintxf2 (op0, op1));
17943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17948 (define_expand "round<mode>2"
17949 [(match_operand:MODEF 0 "register_operand" "")
17950 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17951 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952 && !flag_trapping_math && !flag_rounding_math"
17954 if (optimize_insn_for_size_p ())
17956 if (TARGET_64BIT || (<MODE>mode != DFmode))
17957 ix86_expand_round (operand0, operand1);
17959 ix86_expand_rounddf_32 (operand0, operand1);
17963 (define_insn_and_split "*fistdi2_1"
17964 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17965 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17967 "TARGET_USE_FANCY_MATH_387
17968 && !(reload_completed || reload_in_progress)"
17973 if (memory_operand (operands[0], VOIDmode))
17974 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17977 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17978 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17983 [(set_attr "type" "fpspc")
17984 (set_attr "mode" "DI")])
17986 (define_insn "fistdi2"
17987 [(set (match_operand:DI 0 "memory_operand" "=m")
17988 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17990 (clobber (match_scratch:XF 2 "=&1f"))]
17991 "TARGET_USE_FANCY_MATH_387"
17992 "* return output_fix_trunc (insn, operands, 0);"
17993 [(set_attr "type" "fpspc")
17994 (set_attr "mode" "DI")])
17996 (define_insn "fistdi2_with_temp"
17997 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17998 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18000 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18001 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18002 "TARGET_USE_FANCY_MATH_387"
18004 [(set_attr "type" "fpspc")
18005 (set_attr "mode" "DI")])
18008 [(set (match_operand:DI 0 "register_operand" "")
18009 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18011 (clobber (match_operand:DI 2 "memory_operand" ""))
18012 (clobber (match_scratch 3 ""))]
18014 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18015 (clobber (match_dup 3))])
18016 (set (match_dup 0) (match_dup 2))]
18020 [(set (match_operand:DI 0 "memory_operand" "")
18021 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18023 (clobber (match_operand:DI 2 "memory_operand" ""))
18024 (clobber (match_scratch 3 ""))]
18026 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18027 (clobber (match_dup 3))])]
18030 (define_insn_and_split "*fist<mode>2_1"
18031 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18032 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18034 "TARGET_USE_FANCY_MATH_387
18035 && !(reload_completed || reload_in_progress)"
18040 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18041 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18045 [(set_attr "type" "fpspc")
18046 (set_attr "mode" "<MODE>")])
18048 (define_insn "fist<mode>2"
18049 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18050 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18052 "TARGET_USE_FANCY_MATH_387"
18053 "* return output_fix_trunc (insn, operands, 0);"
18054 [(set_attr "type" "fpspc")
18055 (set_attr "mode" "<MODE>")])
18057 (define_insn "fist<mode>2_with_temp"
18058 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18059 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18061 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18062 "TARGET_USE_FANCY_MATH_387"
18064 [(set_attr "type" "fpspc")
18065 (set_attr "mode" "<MODE>")])
18068 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18069 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18071 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18073 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18074 (set (match_dup 0) (match_dup 2))]
18078 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18079 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18081 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18083 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18086 (define_expand "lrintxf<mode>2"
18087 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18088 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18090 "TARGET_USE_FANCY_MATH_387"
18093 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18094 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18095 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18096 UNSPEC_FIX_NOTRUNC))]
18097 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18098 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18101 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18102 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18103 (match_operand:MODEF 1 "register_operand" "")]
18104 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18105 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18106 && !flag_trapping_math && !flag_rounding_math"
18108 if (optimize_insn_for_size_p ())
18110 ix86_expand_lround (operand0, operand1);
18114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18115 (define_insn_and_split "frndintxf2_floor"
18116 [(set (match_operand:XF 0 "register_operand" "")
18117 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18118 UNSPEC_FRNDINT_FLOOR))
18119 (clobber (reg:CC FLAGS_REG))]
18120 "TARGET_USE_FANCY_MATH_387
18121 && flag_unsafe_math_optimizations
18122 && !(reload_completed || reload_in_progress)"
18127 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18129 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18130 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18132 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18133 operands[2], operands[3]));
18136 [(set_attr "type" "frndint")
18137 (set_attr "i387_cw" "floor")
18138 (set_attr "mode" "XF")])
18140 (define_insn "frndintxf2_floor_i387"
18141 [(set (match_operand:XF 0 "register_operand" "=f")
18142 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143 UNSPEC_FRNDINT_FLOOR))
18144 (use (match_operand:HI 2 "memory_operand" "m"))
18145 (use (match_operand:HI 3 "memory_operand" "m"))]
18146 "TARGET_USE_FANCY_MATH_387
18147 && flag_unsafe_math_optimizations"
18148 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18149 [(set_attr "type" "frndint")
18150 (set_attr "i387_cw" "floor")
18151 (set_attr "mode" "XF")])
18153 (define_expand "floorxf2"
18154 [(use (match_operand:XF 0 "register_operand" ""))
18155 (use (match_operand:XF 1 "register_operand" ""))]
18156 "TARGET_USE_FANCY_MATH_387
18157 && flag_unsafe_math_optimizations"
18159 if (optimize_insn_for_size_p ())
18161 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18165 (define_expand "floor<mode>2"
18166 [(use (match_operand:MODEF 0 "register_operand" ""))
18167 (use (match_operand:MODEF 1 "register_operand" ""))]
18168 "(TARGET_USE_FANCY_MATH_387
18169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18170 || TARGET_MIX_SSE_I387)
18171 && flag_unsafe_math_optimizations)
18172 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173 && !flag_trapping_math)"
18175 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18176 && !flag_trapping_math
18177 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18179 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18182 emit_insn (gen_sse4_1_round<mode>2
18183 (operands[0], operands[1], GEN_INT (0x01)));
18184 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18185 ix86_expand_floorceil (operand0, operand1, true);
18187 ix86_expand_floorceildf_32 (operand0, operand1, true);
18193 if (optimize_insn_for_size_p ())
18196 op0 = gen_reg_rtx (XFmode);
18197 op1 = gen_reg_rtx (XFmode);
18198 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18199 emit_insn (gen_frndintxf2_floor (op0, op1));
18201 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18206 (define_insn_and_split "*fist<mode>2_floor_1"
18207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18208 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18209 UNSPEC_FIST_FLOOR))
18210 (clobber (reg:CC FLAGS_REG))]
18211 "TARGET_USE_FANCY_MATH_387
18212 && flag_unsafe_math_optimizations
18213 && !(reload_completed || reload_in_progress)"
18218 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18220 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18221 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18222 if (memory_operand (operands[0], VOIDmode))
18223 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18224 operands[2], operands[3]));
18227 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18228 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18229 operands[2], operands[3],
18234 [(set_attr "type" "fistp")
18235 (set_attr "i387_cw" "floor")
18236 (set_attr "mode" "<MODE>")])
18238 (define_insn "fistdi2_floor"
18239 [(set (match_operand:DI 0 "memory_operand" "=m")
18240 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18241 UNSPEC_FIST_FLOOR))
18242 (use (match_operand:HI 2 "memory_operand" "m"))
18243 (use (match_operand:HI 3 "memory_operand" "m"))
18244 (clobber (match_scratch:XF 4 "=&1f"))]
18245 "TARGET_USE_FANCY_MATH_387
18246 && flag_unsafe_math_optimizations"
18247 "* return output_fix_trunc (insn, operands, 0);"
18248 [(set_attr "type" "fistp")
18249 (set_attr "i387_cw" "floor")
18250 (set_attr "mode" "DI")])
18252 (define_insn "fistdi2_floor_with_temp"
18253 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18254 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18255 UNSPEC_FIST_FLOOR))
18256 (use (match_operand:HI 2 "memory_operand" "m,m"))
18257 (use (match_operand:HI 3 "memory_operand" "m,m"))
18258 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18259 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18260 "TARGET_USE_FANCY_MATH_387
18261 && flag_unsafe_math_optimizations"
18263 [(set_attr "type" "fistp")
18264 (set_attr "i387_cw" "floor")
18265 (set_attr "mode" "DI")])
18268 [(set (match_operand:DI 0 "register_operand" "")
18269 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18270 UNSPEC_FIST_FLOOR))
18271 (use (match_operand:HI 2 "memory_operand" ""))
18272 (use (match_operand:HI 3 "memory_operand" ""))
18273 (clobber (match_operand:DI 4 "memory_operand" ""))
18274 (clobber (match_scratch 5 ""))]
18276 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18277 (use (match_dup 2))
18278 (use (match_dup 3))
18279 (clobber (match_dup 5))])
18280 (set (match_dup 0) (match_dup 4))]
18284 [(set (match_operand:DI 0 "memory_operand" "")
18285 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18286 UNSPEC_FIST_FLOOR))
18287 (use (match_operand:HI 2 "memory_operand" ""))
18288 (use (match_operand:HI 3 "memory_operand" ""))
18289 (clobber (match_operand:DI 4 "memory_operand" ""))
18290 (clobber (match_scratch 5 ""))]
18292 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18293 (use (match_dup 2))
18294 (use (match_dup 3))
18295 (clobber (match_dup 5))])]
18298 (define_insn "fist<mode>2_floor"
18299 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18301 UNSPEC_FIST_FLOOR))
18302 (use (match_operand:HI 2 "memory_operand" "m"))
18303 (use (match_operand:HI 3 "memory_operand" "m"))]
18304 "TARGET_USE_FANCY_MATH_387
18305 && flag_unsafe_math_optimizations"
18306 "* return output_fix_trunc (insn, operands, 0);"
18307 [(set_attr "type" "fistp")
18308 (set_attr "i387_cw" "floor")
18309 (set_attr "mode" "<MODE>")])
18311 (define_insn "fist<mode>2_floor_with_temp"
18312 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18313 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18314 UNSPEC_FIST_FLOOR))
18315 (use (match_operand:HI 2 "memory_operand" "m,m"))
18316 (use (match_operand:HI 3 "memory_operand" "m,m"))
18317 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18318 "TARGET_USE_FANCY_MATH_387
18319 && flag_unsafe_math_optimizations"
18321 [(set_attr "type" "fistp")
18322 (set_attr "i387_cw" "floor")
18323 (set_attr "mode" "<MODE>")])
18326 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328 UNSPEC_FIST_FLOOR))
18329 (use (match_operand:HI 2 "memory_operand" ""))
18330 (use (match_operand:HI 3 "memory_operand" ""))
18331 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18333 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18334 UNSPEC_FIST_FLOOR))
18335 (use (match_dup 2))
18336 (use (match_dup 3))])
18337 (set (match_dup 0) (match_dup 4))]
18341 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18342 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18343 UNSPEC_FIST_FLOOR))
18344 (use (match_operand:HI 2 "memory_operand" ""))
18345 (use (match_operand:HI 3 "memory_operand" ""))
18346 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18348 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18349 UNSPEC_FIST_FLOOR))
18350 (use (match_dup 2))
18351 (use (match_dup 3))])]
18354 (define_expand "lfloorxf<mode>2"
18355 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18356 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18357 UNSPEC_FIST_FLOOR))
18358 (clobber (reg:CC FLAGS_REG))])]
18359 "TARGET_USE_FANCY_MATH_387
18360 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18361 && flag_unsafe_math_optimizations"
18364 (define_expand "lfloor<mode>di2"
18365 [(match_operand:DI 0 "nonimmediate_operand" "")
18366 (match_operand:MODEF 1 "register_operand" "")]
18367 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18368 && !flag_trapping_math"
18370 if (optimize_insn_for_size_p ())
18372 ix86_expand_lfloorceil (operand0, operand1, true);
18376 (define_expand "lfloor<mode>si2"
18377 [(match_operand:SI 0 "nonimmediate_operand" "")
18378 (match_operand:MODEF 1 "register_operand" "")]
18379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18380 && !flag_trapping_math"
18382 if (optimize_insn_for_size_p () && TARGET_64BIT)
18384 ix86_expand_lfloorceil (operand0, operand1, true);
18388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18389 (define_insn_and_split "frndintxf2_ceil"
18390 [(set (match_operand:XF 0 "register_operand" "")
18391 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18392 UNSPEC_FRNDINT_CEIL))
18393 (clobber (reg:CC FLAGS_REG))]
18394 "TARGET_USE_FANCY_MATH_387
18395 && flag_unsafe_math_optimizations
18396 && !(reload_completed || reload_in_progress)"
18401 ix86_optimize_mode_switching[I387_CEIL] = 1;
18403 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18404 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18406 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18407 operands[2], operands[3]));
18410 [(set_attr "type" "frndint")
18411 (set_attr "i387_cw" "ceil")
18412 (set_attr "mode" "XF")])
18414 (define_insn "frndintxf2_ceil_i387"
18415 [(set (match_operand:XF 0 "register_operand" "=f")
18416 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18417 UNSPEC_FRNDINT_CEIL))
18418 (use (match_operand:HI 2 "memory_operand" "m"))
18419 (use (match_operand:HI 3 "memory_operand" "m"))]
18420 "TARGET_USE_FANCY_MATH_387
18421 && flag_unsafe_math_optimizations"
18422 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18423 [(set_attr "type" "frndint")
18424 (set_attr "i387_cw" "ceil")
18425 (set_attr "mode" "XF")])
18427 (define_expand "ceilxf2"
18428 [(use (match_operand:XF 0 "register_operand" ""))
18429 (use (match_operand:XF 1 "register_operand" ""))]
18430 "TARGET_USE_FANCY_MATH_387
18431 && flag_unsafe_math_optimizations"
18433 if (optimize_insn_for_size_p ())
18435 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18439 (define_expand "ceil<mode>2"
18440 [(use (match_operand:MODEF 0 "register_operand" ""))
18441 (use (match_operand:MODEF 1 "register_operand" ""))]
18442 "(TARGET_USE_FANCY_MATH_387
18443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444 || TARGET_MIX_SSE_I387)
18445 && flag_unsafe_math_optimizations)
18446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447 && !flag_trapping_math)"
18449 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18450 && !flag_trapping_math
18451 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18454 emit_insn (gen_sse4_1_round<mode>2
18455 (operands[0], operands[1], GEN_INT (0x02)));
18456 else if (optimize_insn_for_size_p ())
18458 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18459 ix86_expand_floorceil (operand0, operand1, false);
18461 ix86_expand_floorceildf_32 (operand0, operand1, false);
18467 if (optimize_insn_for_size_p ())
18470 op0 = gen_reg_rtx (XFmode);
18471 op1 = gen_reg_rtx (XFmode);
18472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18473 emit_insn (gen_frndintxf2_ceil (op0, op1));
18475 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18480 (define_insn_and_split "*fist<mode>2_ceil_1"
18481 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18482 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18484 (clobber (reg:CC FLAGS_REG))]
18485 "TARGET_USE_FANCY_MATH_387
18486 && flag_unsafe_math_optimizations
18487 && !(reload_completed || reload_in_progress)"
18492 ix86_optimize_mode_switching[I387_CEIL] = 1;
18494 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18495 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18496 if (memory_operand (operands[0], VOIDmode))
18497 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18498 operands[2], operands[3]));
18501 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18502 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18503 operands[2], operands[3],
18508 [(set_attr "type" "fistp")
18509 (set_attr "i387_cw" "ceil")
18510 (set_attr "mode" "<MODE>")])
18512 (define_insn "fistdi2_ceil"
18513 [(set (match_operand:DI 0 "memory_operand" "=m")
18514 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18516 (use (match_operand:HI 2 "memory_operand" "m"))
18517 (use (match_operand:HI 3 "memory_operand" "m"))
18518 (clobber (match_scratch:XF 4 "=&1f"))]
18519 "TARGET_USE_FANCY_MATH_387
18520 && flag_unsafe_math_optimizations"
18521 "* return output_fix_trunc (insn, operands, 0);"
18522 [(set_attr "type" "fistp")
18523 (set_attr "i387_cw" "ceil")
18524 (set_attr "mode" "DI")])
18526 (define_insn "fistdi2_ceil_with_temp"
18527 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18528 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18530 (use (match_operand:HI 2 "memory_operand" "m,m"))
18531 (use (match_operand:HI 3 "memory_operand" "m,m"))
18532 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18533 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18534 "TARGET_USE_FANCY_MATH_387
18535 && flag_unsafe_math_optimizations"
18537 [(set_attr "type" "fistp")
18538 (set_attr "i387_cw" "ceil")
18539 (set_attr "mode" "DI")])
18542 [(set (match_operand:DI 0 "register_operand" "")
18543 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18545 (use (match_operand:HI 2 "memory_operand" ""))
18546 (use (match_operand:HI 3 "memory_operand" ""))
18547 (clobber (match_operand:DI 4 "memory_operand" ""))
18548 (clobber (match_scratch 5 ""))]
18550 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18551 (use (match_dup 2))
18552 (use (match_dup 3))
18553 (clobber (match_dup 5))])
18554 (set (match_dup 0) (match_dup 4))]
18558 [(set (match_operand:DI 0 "memory_operand" "")
18559 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18561 (use (match_operand:HI 2 "memory_operand" ""))
18562 (use (match_operand:HI 3 "memory_operand" ""))
18563 (clobber (match_operand:DI 4 "memory_operand" ""))
18564 (clobber (match_scratch 5 ""))]
18566 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18567 (use (match_dup 2))
18568 (use (match_dup 3))
18569 (clobber (match_dup 5))])]
18572 (define_insn "fist<mode>2_ceil"
18573 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18574 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18576 (use (match_operand:HI 2 "memory_operand" "m"))
18577 (use (match_operand:HI 3 "memory_operand" "m"))]
18578 "TARGET_USE_FANCY_MATH_387
18579 && flag_unsafe_math_optimizations"
18580 "* return output_fix_trunc (insn, operands, 0);"
18581 [(set_attr "type" "fistp")
18582 (set_attr "i387_cw" "ceil")
18583 (set_attr "mode" "<MODE>")])
18585 (define_insn "fist<mode>2_ceil_with_temp"
18586 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18587 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18589 (use (match_operand:HI 2 "memory_operand" "m,m"))
18590 (use (match_operand:HI 3 "memory_operand" "m,m"))
18591 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18592 "TARGET_USE_FANCY_MATH_387
18593 && flag_unsafe_math_optimizations"
18595 [(set_attr "type" "fistp")
18596 (set_attr "i387_cw" "ceil")
18597 (set_attr "mode" "<MODE>")])
18600 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18601 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18603 (use (match_operand:HI 2 "memory_operand" ""))
18604 (use (match_operand:HI 3 "memory_operand" ""))
18605 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18607 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18609 (use (match_dup 2))
18610 (use (match_dup 3))])
18611 (set (match_dup 0) (match_dup 4))]
18615 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18616 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18618 (use (match_operand:HI 2 "memory_operand" ""))
18619 (use (match_operand:HI 3 "memory_operand" ""))
18620 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18622 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18624 (use (match_dup 2))
18625 (use (match_dup 3))])]
18628 (define_expand "lceilxf<mode>2"
18629 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18630 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18632 (clobber (reg:CC FLAGS_REG))])]
18633 "TARGET_USE_FANCY_MATH_387
18634 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18635 && flag_unsafe_math_optimizations"
18638 (define_expand "lceil<mode>di2"
18639 [(match_operand:DI 0 "nonimmediate_operand" "")
18640 (match_operand:MODEF 1 "register_operand" "")]
18641 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18642 && !flag_trapping_math"
18644 ix86_expand_lfloorceil (operand0, operand1, false);
18648 (define_expand "lceil<mode>si2"
18649 [(match_operand:SI 0 "nonimmediate_operand" "")
18650 (match_operand:MODEF 1 "register_operand" "")]
18651 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18652 && !flag_trapping_math"
18654 ix86_expand_lfloorceil (operand0, operand1, false);
18658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18659 (define_insn_and_split "frndintxf2_trunc"
18660 [(set (match_operand:XF 0 "register_operand" "")
18661 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18662 UNSPEC_FRNDINT_TRUNC))
18663 (clobber (reg:CC FLAGS_REG))]
18664 "TARGET_USE_FANCY_MATH_387
18665 && flag_unsafe_math_optimizations
18666 && !(reload_completed || reload_in_progress)"
18671 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18673 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18674 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18676 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18677 operands[2], operands[3]));
18680 [(set_attr "type" "frndint")
18681 (set_attr "i387_cw" "trunc")
18682 (set_attr "mode" "XF")])
18684 (define_insn "frndintxf2_trunc_i387"
18685 [(set (match_operand:XF 0 "register_operand" "=f")
18686 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18687 UNSPEC_FRNDINT_TRUNC))
18688 (use (match_operand:HI 2 "memory_operand" "m"))
18689 (use (match_operand:HI 3 "memory_operand" "m"))]
18690 "TARGET_USE_FANCY_MATH_387
18691 && flag_unsafe_math_optimizations"
18692 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18693 [(set_attr "type" "frndint")
18694 (set_attr "i387_cw" "trunc")
18695 (set_attr "mode" "XF")])
18697 (define_expand "btruncxf2"
18698 [(use (match_operand:XF 0 "register_operand" ""))
18699 (use (match_operand:XF 1 "register_operand" ""))]
18700 "TARGET_USE_FANCY_MATH_387
18701 && flag_unsafe_math_optimizations"
18703 if (optimize_insn_for_size_p ())
18705 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18709 (define_expand "btrunc<mode>2"
18710 [(use (match_operand:MODEF 0 "register_operand" ""))
18711 (use (match_operand:MODEF 1 "register_operand" ""))]
18712 "(TARGET_USE_FANCY_MATH_387
18713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18714 || TARGET_MIX_SSE_I387)
18715 && flag_unsafe_math_optimizations)
18716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717 && !flag_trapping_math)"
18719 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18720 && !flag_trapping_math
18721 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18724 emit_insn (gen_sse4_1_round<mode>2
18725 (operands[0], operands[1], GEN_INT (0x03)));
18726 else if (optimize_insn_for_size_p ())
18728 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18729 ix86_expand_trunc (operand0, operand1);
18731 ix86_expand_truncdf_32 (operand0, operand1);
18737 if (optimize_insn_for_size_p ())
18740 op0 = gen_reg_rtx (XFmode);
18741 op1 = gen_reg_rtx (XFmode);
18742 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18743 emit_insn (gen_frndintxf2_trunc (op0, op1));
18745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18750 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18751 (define_insn_and_split "frndintxf2_mask_pm"
18752 [(set (match_operand:XF 0 "register_operand" "")
18753 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18754 UNSPEC_FRNDINT_MASK_PM))
18755 (clobber (reg:CC FLAGS_REG))]
18756 "TARGET_USE_FANCY_MATH_387
18757 && flag_unsafe_math_optimizations
18758 && !(reload_completed || reload_in_progress)"
18763 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18765 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18766 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18768 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18769 operands[2], operands[3]));
18772 [(set_attr "type" "frndint")
18773 (set_attr "i387_cw" "mask_pm")
18774 (set_attr "mode" "XF")])
18776 (define_insn "frndintxf2_mask_pm_i387"
18777 [(set (match_operand:XF 0 "register_operand" "=f")
18778 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18779 UNSPEC_FRNDINT_MASK_PM))
18780 (use (match_operand:HI 2 "memory_operand" "m"))
18781 (use (match_operand:HI 3 "memory_operand" "m"))]
18782 "TARGET_USE_FANCY_MATH_387
18783 && flag_unsafe_math_optimizations"
18784 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18785 [(set_attr "type" "frndint")
18786 (set_attr "i387_cw" "mask_pm")
18787 (set_attr "mode" "XF")])
18789 (define_expand "nearbyintxf2"
18790 [(use (match_operand:XF 0 "register_operand" ""))
18791 (use (match_operand:XF 1 "register_operand" ""))]
18792 "TARGET_USE_FANCY_MATH_387
18793 && flag_unsafe_math_optimizations"
18795 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18800 (define_expand "nearbyint<mode>2"
18801 [(use (match_operand:MODEF 0 "register_operand" ""))
18802 (use (match_operand:MODEF 1 "register_operand" ""))]
18803 "TARGET_USE_FANCY_MATH_387
18804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18805 || TARGET_MIX_SSE_I387)
18806 && flag_unsafe_math_optimizations"
18808 rtx op0 = gen_reg_rtx (XFmode);
18809 rtx op1 = gen_reg_rtx (XFmode);
18811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18812 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18818 (define_insn "fxam<mode>2_i387"
18819 [(set (match_operand:HI 0 "register_operand" "=a")
18821 [(match_operand:X87MODEF 1 "register_operand" "f")]
18823 "TARGET_USE_FANCY_MATH_387"
18824 "fxam\n\tfnstsw\t%0"
18825 [(set_attr "type" "multi")
18826 (set_attr "unit" "i387")
18827 (set_attr "mode" "<MODE>")])
18829 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18830 [(set (match_operand:HI 0 "register_operand" "")
18832 [(match_operand:MODEF 1 "memory_operand" "")]
18834 "TARGET_USE_FANCY_MATH_387
18835 && !(reload_completed || reload_in_progress)"
18838 [(set (match_dup 2)(match_dup 1))
18840 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18842 operands[2] = gen_reg_rtx (<MODE>mode);
18844 MEM_VOLATILE_P (operands[1]) = 1;
18846 [(set_attr "type" "multi")
18847 (set_attr "unit" "i387")
18848 (set_attr "mode" "<MODE>")])
18850 (define_expand "isinfxf2"
18851 [(use (match_operand:SI 0 "register_operand" ""))
18852 (use (match_operand:XF 1 "register_operand" ""))]
18853 "TARGET_USE_FANCY_MATH_387
18854 && TARGET_C99_FUNCTIONS"
18856 rtx mask = GEN_INT (0x45);
18857 rtx val = GEN_INT (0x05);
18861 rtx scratch = gen_reg_rtx (HImode);
18862 rtx res = gen_reg_rtx (QImode);
18864 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18866 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18867 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18868 cond = gen_rtx_fmt_ee (EQ, QImode,
18869 gen_rtx_REG (CCmode, FLAGS_REG),
18871 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18872 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18876 (define_expand "isinf<mode>2"
18877 [(use (match_operand:SI 0 "register_operand" ""))
18878 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18879 "TARGET_USE_FANCY_MATH_387
18880 && TARGET_C99_FUNCTIONS
18881 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18883 rtx mask = GEN_INT (0x45);
18884 rtx val = GEN_INT (0x05);
18888 rtx scratch = gen_reg_rtx (HImode);
18889 rtx res = gen_reg_rtx (QImode);
18891 /* Remove excess precision by forcing value through memory. */
18892 if (memory_operand (operands[1], VOIDmode))
18893 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18896 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18897 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18899 emit_move_insn (temp, operands[1]);
18900 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18903 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18904 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18905 cond = gen_rtx_fmt_ee (EQ, QImode,
18906 gen_rtx_REG (CCmode, FLAGS_REG),
18908 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18909 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18913 (define_expand "signbit<mode>2"
18914 [(use (match_operand:SI 0 "register_operand" ""))
18915 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18916 "TARGET_USE_FANCY_MATH_387
18917 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18919 rtx mask = GEN_INT (0x0200);
18921 rtx scratch = gen_reg_rtx (HImode);
18923 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18924 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18928 ;; Block operation instructions
18931 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18934 [(set_attr "length" "1")
18935 (set_attr "length_immediate" "0")
18936 (set_attr "modrm" "0")])
18938 (define_expand "movmemsi"
18939 [(use (match_operand:BLK 0 "memory_operand" ""))
18940 (use (match_operand:BLK 1 "memory_operand" ""))
18941 (use (match_operand:SI 2 "nonmemory_operand" ""))
18942 (use (match_operand:SI 3 "const_int_operand" ""))
18943 (use (match_operand:SI 4 "const_int_operand" ""))
18944 (use (match_operand:SI 5 "const_int_operand" ""))]
18947 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18948 operands[4], operands[5]))
18954 (define_expand "movmemdi"
18955 [(use (match_operand:BLK 0 "memory_operand" ""))
18956 (use (match_operand:BLK 1 "memory_operand" ""))
18957 (use (match_operand:DI 2 "nonmemory_operand" ""))
18958 (use (match_operand:DI 3 "const_int_operand" ""))
18959 (use (match_operand:SI 4 "const_int_operand" ""))
18960 (use (match_operand:SI 5 "const_int_operand" ""))]
18963 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18964 operands[4], operands[5]))
18970 ;; Most CPUs don't like single string operations
18971 ;; Handle this case here to simplify previous expander.
18973 (define_expand "strmov"
18974 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18975 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18976 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18977 (clobber (reg:CC FLAGS_REG))])
18978 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18979 (clobber (reg:CC FLAGS_REG))])]
18982 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18984 /* If .md ever supports :P for Pmode, these can be directly
18985 in the pattern above. */
18986 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18987 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18989 /* Can't use this if the user has appropriated esi or edi. */
18990 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18991 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18993 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18994 operands[2], operands[3],
18995 operands[5], operands[6]));
18999 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19002 (define_expand "strmov_singleop"
19003 [(parallel [(set (match_operand 1 "memory_operand" "")
19004 (match_operand 3 "memory_operand" ""))
19005 (set (match_operand 0 "register_operand" "")
19006 (match_operand 4 "" ""))
19007 (set (match_operand 2 "register_operand" "")
19008 (match_operand 5 "" ""))])]
19010 "ix86_current_function_needs_cld = 1;")
19012 (define_insn "*strmovdi_rex_1"
19013 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19014 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19015 (set (match_operand:DI 0 "register_operand" "=D")
19016 (plus:DI (match_dup 2)
19018 (set (match_operand:DI 1 "register_operand" "=S")
19019 (plus:DI (match_dup 3)
19022 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19024 [(set_attr "type" "str")
19025 (set_attr "mode" "DI")
19026 (set_attr "memory" "both")])
19028 (define_insn "*strmovsi_1"
19029 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19030 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19031 (set (match_operand:SI 0 "register_operand" "=D")
19032 (plus:SI (match_dup 2)
19034 (set (match_operand:SI 1 "register_operand" "=S")
19035 (plus:SI (match_dup 3)
19038 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19040 [(set_attr "type" "str")
19041 (set_attr "mode" "SI")
19042 (set_attr "memory" "both")])
19044 (define_insn "*strmovsi_rex_1"
19045 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19046 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19047 (set (match_operand:DI 0 "register_operand" "=D")
19048 (plus:DI (match_dup 2)
19050 (set (match_operand:DI 1 "register_operand" "=S")
19051 (plus:DI (match_dup 3)
19054 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19056 [(set_attr "type" "str")
19057 (set_attr "mode" "SI")
19058 (set_attr "memory" "both")])
19060 (define_insn "*strmovhi_1"
19061 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19062 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19063 (set (match_operand:SI 0 "register_operand" "=D")
19064 (plus:SI (match_dup 2)
19066 (set (match_operand:SI 1 "register_operand" "=S")
19067 (plus:SI (match_dup 3)
19070 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19072 [(set_attr "type" "str")
19073 (set_attr "memory" "both")
19074 (set_attr "mode" "HI")])
19076 (define_insn "*strmovhi_rex_1"
19077 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19078 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19079 (set (match_operand:DI 0 "register_operand" "=D")
19080 (plus:DI (match_dup 2)
19082 (set (match_operand:DI 1 "register_operand" "=S")
19083 (plus:DI (match_dup 3)
19086 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19088 [(set_attr "type" "str")
19089 (set_attr "memory" "both")
19090 (set_attr "mode" "HI")])
19092 (define_insn "*strmovqi_1"
19093 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19094 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19095 (set (match_operand:SI 0 "register_operand" "=D")
19096 (plus:SI (match_dup 2)
19098 (set (match_operand:SI 1 "register_operand" "=S")
19099 (plus:SI (match_dup 3)
19102 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19104 [(set_attr "type" "str")
19105 (set_attr "memory" "both")
19106 (set_attr "mode" "QI")])
19108 (define_insn "*strmovqi_rex_1"
19109 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19110 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19111 (set (match_operand:DI 0 "register_operand" "=D")
19112 (plus:DI (match_dup 2)
19114 (set (match_operand:DI 1 "register_operand" "=S")
19115 (plus:DI (match_dup 3)
19118 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19120 [(set_attr "type" "str")
19121 (set_attr "memory" "both")
19122 (set_attr "mode" "QI")])
19124 (define_expand "rep_mov"
19125 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19126 (set (match_operand 0 "register_operand" "")
19127 (match_operand 5 "" ""))
19128 (set (match_operand 2 "register_operand" "")
19129 (match_operand 6 "" ""))
19130 (set (match_operand 1 "memory_operand" "")
19131 (match_operand 3 "memory_operand" ""))
19132 (use (match_dup 4))])]
19134 "ix86_current_function_needs_cld = 1;")
19136 (define_insn "*rep_movdi_rex64"
19137 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19138 (set (match_operand:DI 0 "register_operand" "=D")
19139 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19141 (match_operand:DI 3 "register_operand" "0")))
19142 (set (match_operand:DI 1 "register_operand" "=S")
19143 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19144 (match_operand:DI 4 "register_operand" "1")))
19145 (set (mem:BLK (match_dup 3))
19146 (mem:BLK (match_dup 4)))
19147 (use (match_dup 5))]
19149 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19151 [(set_attr "type" "str")
19152 (set_attr "prefix_rep" "1")
19153 (set_attr "memory" "both")
19154 (set_attr "mode" "DI")])
19156 (define_insn "*rep_movsi"
19157 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19158 (set (match_operand:SI 0 "register_operand" "=D")
19159 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19161 (match_operand:SI 3 "register_operand" "0")))
19162 (set (match_operand:SI 1 "register_operand" "=S")
19163 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19164 (match_operand:SI 4 "register_operand" "1")))
19165 (set (mem:BLK (match_dup 3))
19166 (mem:BLK (match_dup 4)))
19167 (use (match_dup 5))]
19169 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19170 "rep{%;} movs{l|d}"
19171 [(set_attr "type" "str")
19172 (set_attr "prefix_rep" "1")
19173 (set_attr "memory" "both")
19174 (set_attr "mode" "SI")])
19176 (define_insn "*rep_movsi_rex64"
19177 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19178 (set (match_operand:DI 0 "register_operand" "=D")
19179 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19181 (match_operand:DI 3 "register_operand" "0")))
19182 (set (match_operand:DI 1 "register_operand" "=S")
19183 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19184 (match_operand:DI 4 "register_operand" "1")))
19185 (set (mem:BLK (match_dup 3))
19186 (mem:BLK (match_dup 4)))
19187 (use (match_dup 5))]
19189 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19190 "rep{%;} movs{l|d}"
19191 [(set_attr "type" "str")
19192 (set_attr "prefix_rep" "1")
19193 (set_attr "memory" "both")
19194 (set_attr "mode" "SI")])
19196 (define_insn "*rep_movqi"
19197 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19198 (set (match_operand:SI 0 "register_operand" "=D")
19199 (plus:SI (match_operand:SI 3 "register_operand" "0")
19200 (match_operand:SI 5 "register_operand" "2")))
19201 (set (match_operand:SI 1 "register_operand" "=S")
19202 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19203 (set (mem:BLK (match_dup 3))
19204 (mem:BLK (match_dup 4)))
19205 (use (match_dup 5))]
19207 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19209 [(set_attr "type" "str")
19210 (set_attr "prefix_rep" "1")
19211 (set_attr "memory" "both")
19212 (set_attr "mode" "SI")])
19214 (define_insn "*rep_movqi_rex64"
19215 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19216 (set (match_operand:DI 0 "register_operand" "=D")
19217 (plus:DI (match_operand:DI 3 "register_operand" "0")
19218 (match_operand:DI 5 "register_operand" "2")))
19219 (set (match_operand:DI 1 "register_operand" "=S")
19220 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19221 (set (mem:BLK (match_dup 3))
19222 (mem:BLK (match_dup 4)))
19223 (use (match_dup 5))]
19225 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19227 [(set_attr "type" "str")
19228 (set_attr "prefix_rep" "1")
19229 (set_attr "memory" "both")
19230 (set_attr "mode" "SI")])
19232 (define_expand "setmemsi"
19233 [(use (match_operand:BLK 0 "memory_operand" ""))
19234 (use (match_operand:SI 1 "nonmemory_operand" ""))
19235 (use (match_operand 2 "const_int_operand" ""))
19236 (use (match_operand 3 "const_int_operand" ""))
19237 (use (match_operand:SI 4 "const_int_operand" ""))
19238 (use (match_operand:SI 5 "const_int_operand" ""))]
19241 if (ix86_expand_setmem (operands[0], operands[1],
19242 operands[2], operands[3],
19243 operands[4], operands[5]))
19249 (define_expand "setmemdi"
19250 [(use (match_operand:BLK 0 "memory_operand" ""))
19251 (use (match_operand:DI 1 "nonmemory_operand" ""))
19252 (use (match_operand 2 "const_int_operand" ""))
19253 (use (match_operand 3 "const_int_operand" ""))
19254 (use (match_operand 4 "const_int_operand" ""))
19255 (use (match_operand 5 "const_int_operand" ""))]
19258 if (ix86_expand_setmem (operands[0], operands[1],
19259 operands[2], operands[3],
19260 operands[4], operands[5]))
19266 ;; Most CPUs don't like single string operations
19267 ;; Handle this case here to simplify previous expander.
19269 (define_expand "strset"
19270 [(set (match_operand 1 "memory_operand" "")
19271 (match_operand 2 "register_operand" ""))
19272 (parallel [(set (match_operand 0 "register_operand" "")
19274 (clobber (reg:CC FLAGS_REG))])]
19277 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19278 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19280 /* If .md ever supports :P for Pmode, this can be directly
19281 in the pattern above. */
19282 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19283 GEN_INT (GET_MODE_SIZE (GET_MODE
19285 /* Can't use this if the user has appropriated eax or edi. */
19286 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19287 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
19289 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19295 (define_expand "strset_singleop"
19296 [(parallel [(set (match_operand 1 "memory_operand" "")
19297 (match_operand 2 "register_operand" ""))
19298 (set (match_operand 0 "register_operand" "")
19299 (match_operand 3 "" ""))])]
19301 "ix86_current_function_needs_cld = 1;")
19303 (define_insn "*strsetdi_rex_1"
19304 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19305 (match_operand:DI 2 "register_operand" "a"))
19306 (set (match_operand:DI 0 "register_operand" "=D")
19307 (plus:DI (match_dup 1)
19310 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19312 [(set_attr "type" "str")
19313 (set_attr "memory" "store")
19314 (set_attr "mode" "DI")])
19316 (define_insn "*strsetsi_1"
19317 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19318 (match_operand:SI 2 "register_operand" "a"))
19319 (set (match_operand:SI 0 "register_operand" "=D")
19320 (plus:SI (match_dup 1)
19323 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19325 [(set_attr "type" "str")
19326 (set_attr "memory" "store")
19327 (set_attr "mode" "SI")])
19329 (define_insn "*strsetsi_rex_1"
19330 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19331 (match_operand:SI 2 "register_operand" "a"))
19332 (set (match_operand:DI 0 "register_operand" "=D")
19333 (plus:DI (match_dup 1)
19336 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19338 [(set_attr "type" "str")
19339 (set_attr "memory" "store")
19340 (set_attr "mode" "SI")])
19342 (define_insn "*strsethi_1"
19343 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19344 (match_operand:HI 2 "register_operand" "a"))
19345 (set (match_operand:SI 0 "register_operand" "=D")
19346 (plus:SI (match_dup 1)
19349 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19351 [(set_attr "type" "str")
19352 (set_attr "memory" "store")
19353 (set_attr "mode" "HI")])
19355 (define_insn "*strsethi_rex_1"
19356 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19357 (match_operand:HI 2 "register_operand" "a"))
19358 (set (match_operand:DI 0 "register_operand" "=D")
19359 (plus:DI (match_dup 1)
19362 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19364 [(set_attr "type" "str")
19365 (set_attr "memory" "store")
19366 (set_attr "mode" "HI")])
19368 (define_insn "*strsetqi_1"
19369 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19370 (match_operand:QI 2 "register_operand" "a"))
19371 (set (match_operand:SI 0 "register_operand" "=D")
19372 (plus:SI (match_dup 1)
19375 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19377 [(set_attr "type" "str")
19378 (set_attr "memory" "store")
19379 (set_attr "mode" "QI")])
19381 (define_insn "*strsetqi_rex_1"
19382 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19383 (match_operand:QI 2 "register_operand" "a"))
19384 (set (match_operand:DI 0 "register_operand" "=D")
19385 (plus:DI (match_dup 1)
19388 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19390 [(set_attr "type" "str")
19391 (set_attr "memory" "store")
19392 (set_attr "mode" "QI")])
19394 (define_expand "rep_stos"
19395 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19396 (set (match_operand 0 "register_operand" "")
19397 (match_operand 4 "" ""))
19398 (set (match_operand 2 "memory_operand" "") (const_int 0))
19399 (use (match_operand 3 "register_operand" ""))
19400 (use (match_dup 1))])]
19402 "ix86_current_function_needs_cld = 1;")
19404 (define_insn "*rep_stosdi_rex64"
19405 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19406 (set (match_operand:DI 0 "register_operand" "=D")
19407 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19409 (match_operand:DI 3 "register_operand" "0")))
19410 (set (mem:BLK (match_dup 3))
19412 (use (match_operand:DI 2 "register_operand" "a"))
19413 (use (match_dup 4))]
19415 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19417 [(set_attr "type" "str")
19418 (set_attr "prefix_rep" "1")
19419 (set_attr "memory" "store")
19420 (set_attr "mode" "DI")])
19422 (define_insn "*rep_stossi"
19423 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19424 (set (match_operand:SI 0 "register_operand" "=D")
19425 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19427 (match_operand:SI 3 "register_operand" "0")))
19428 (set (mem:BLK (match_dup 3))
19430 (use (match_operand:SI 2 "register_operand" "a"))
19431 (use (match_dup 4))]
19433 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19434 "rep{%;} stos{l|d}"
19435 [(set_attr "type" "str")
19436 (set_attr "prefix_rep" "1")
19437 (set_attr "memory" "store")
19438 (set_attr "mode" "SI")])
19440 (define_insn "*rep_stossi_rex64"
19441 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19442 (set (match_operand:DI 0 "register_operand" "=D")
19443 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19445 (match_operand:DI 3 "register_operand" "0")))
19446 (set (mem:BLK (match_dup 3))
19448 (use (match_operand:SI 2 "register_operand" "a"))
19449 (use (match_dup 4))]
19451 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19452 "rep{%;} stos{l|d}"
19453 [(set_attr "type" "str")
19454 (set_attr "prefix_rep" "1")
19455 (set_attr "memory" "store")
19456 (set_attr "mode" "SI")])
19458 (define_insn "*rep_stosqi"
19459 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19460 (set (match_operand:SI 0 "register_operand" "=D")
19461 (plus:SI (match_operand:SI 3 "register_operand" "0")
19462 (match_operand:SI 4 "register_operand" "1")))
19463 (set (mem:BLK (match_dup 3))
19465 (use (match_operand:QI 2 "register_operand" "a"))
19466 (use (match_dup 4))]
19468 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19470 [(set_attr "type" "str")
19471 (set_attr "prefix_rep" "1")
19472 (set_attr "memory" "store")
19473 (set_attr "mode" "QI")])
19475 (define_insn "*rep_stosqi_rex64"
19476 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19477 (set (match_operand:DI 0 "register_operand" "=D")
19478 (plus:DI (match_operand:DI 3 "register_operand" "0")
19479 (match_operand:DI 4 "register_operand" "1")))
19480 (set (mem:BLK (match_dup 3))
19482 (use (match_operand:QI 2 "register_operand" "a"))
19483 (use (match_dup 4))]
19485 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19487 [(set_attr "type" "str")
19488 (set_attr "prefix_rep" "1")
19489 (set_attr "memory" "store")
19490 (set_attr "mode" "QI")])
19492 (define_expand "cmpstrnsi"
19493 [(set (match_operand:SI 0 "register_operand" "")
19494 (compare:SI (match_operand:BLK 1 "general_operand" "")
19495 (match_operand:BLK 2 "general_operand" "")))
19496 (use (match_operand 3 "general_operand" ""))
19497 (use (match_operand 4 "immediate_operand" ""))]
19500 rtx addr1, addr2, out, outlow, count, countreg, align;
19502 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19505 /* Can't use this if the user has appropriated ecx, esi or edi. */
19506 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
19511 out = gen_reg_rtx (SImode);
19513 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19514 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19515 if (addr1 != XEXP (operands[1], 0))
19516 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19517 if (addr2 != XEXP (operands[2], 0))
19518 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19520 count = operands[3];
19521 countreg = ix86_zero_extend_to_Pmode (count);
19523 /* %%% Iff we are testing strict equality, we can use known alignment
19524 to good advantage. This may be possible with combine, particularly
19525 once cc0 is dead. */
19526 align = operands[4];
19528 if (CONST_INT_P (count))
19530 if (INTVAL (count) == 0)
19532 emit_move_insn (operands[0], const0_rtx);
19535 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19536 operands[1], operands[2]));
19541 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19543 emit_insn (gen_cmpsi_1 (countreg, countreg));
19544 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19545 operands[1], operands[2]));
19548 outlow = gen_lowpart (QImode, out);
19549 emit_insn (gen_cmpintqi (outlow));
19550 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19552 if (operands[0] != out)
19553 emit_move_insn (operands[0], out);
19558 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19560 (define_expand "cmpintqi"
19561 [(set (match_dup 1)
19562 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19564 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19565 (parallel [(set (match_operand:QI 0 "register_operand" "")
19566 (minus:QI (match_dup 1)
19568 (clobber (reg:CC FLAGS_REG))])]
19570 "operands[1] = gen_reg_rtx (QImode);
19571 operands[2] = gen_reg_rtx (QImode);")
19573 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19574 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19576 (define_expand "cmpstrnqi_nz_1"
19577 [(parallel [(set (reg:CC FLAGS_REG)
19578 (compare:CC (match_operand 4 "memory_operand" "")
19579 (match_operand 5 "memory_operand" "")))
19580 (use (match_operand 2 "register_operand" ""))
19581 (use (match_operand:SI 3 "immediate_operand" ""))
19582 (clobber (match_operand 0 "register_operand" ""))
19583 (clobber (match_operand 1 "register_operand" ""))
19584 (clobber (match_dup 2))])]
19586 "ix86_current_function_needs_cld = 1;")
19588 (define_insn "*cmpstrnqi_nz_1"
19589 [(set (reg:CC FLAGS_REG)
19590 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19591 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19592 (use (match_operand:SI 6 "register_operand" "2"))
19593 (use (match_operand:SI 3 "immediate_operand" "i"))
19594 (clobber (match_operand:SI 0 "register_operand" "=S"))
19595 (clobber (match_operand:SI 1 "register_operand" "=D"))
19596 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19598 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19600 [(set_attr "type" "str")
19601 (set_attr "mode" "QI")
19602 (set_attr "prefix_rep" "1")])
19604 (define_insn "*cmpstrnqi_nz_rex_1"
19605 [(set (reg:CC FLAGS_REG)
19606 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19607 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19608 (use (match_operand:DI 6 "register_operand" "2"))
19609 (use (match_operand:SI 3 "immediate_operand" "i"))
19610 (clobber (match_operand:DI 0 "register_operand" "=S"))
19611 (clobber (match_operand:DI 1 "register_operand" "=D"))
19612 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19614 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19616 [(set_attr "type" "str")
19617 (set_attr "mode" "QI")
19618 (set_attr "prefix_rep" "1")])
19620 ;; The same, but the count is not known to not be zero.
19622 (define_expand "cmpstrnqi_1"
19623 [(parallel [(set (reg:CC FLAGS_REG)
19624 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19626 (compare:CC (match_operand 4 "memory_operand" "")
19627 (match_operand 5 "memory_operand" ""))
19629 (use (match_operand:SI 3 "immediate_operand" ""))
19630 (use (reg:CC FLAGS_REG))
19631 (clobber (match_operand 0 "register_operand" ""))
19632 (clobber (match_operand 1 "register_operand" ""))
19633 (clobber (match_dup 2))])]
19635 "ix86_current_function_needs_cld = 1;")
19637 (define_insn "*cmpstrnqi_1"
19638 [(set (reg:CC FLAGS_REG)
19639 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19641 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19642 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19644 (use (match_operand:SI 3 "immediate_operand" "i"))
19645 (use (reg:CC FLAGS_REG))
19646 (clobber (match_operand:SI 0 "register_operand" "=S"))
19647 (clobber (match_operand:SI 1 "register_operand" "=D"))
19648 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19650 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19652 [(set_attr "type" "str")
19653 (set_attr "mode" "QI")
19654 (set_attr "prefix_rep" "1")])
19656 (define_insn "*cmpstrnqi_rex_1"
19657 [(set (reg:CC FLAGS_REG)
19658 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19660 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19661 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19663 (use (match_operand:SI 3 "immediate_operand" "i"))
19664 (use (reg:CC FLAGS_REG))
19665 (clobber (match_operand:DI 0 "register_operand" "=S"))
19666 (clobber (match_operand:DI 1 "register_operand" "=D"))
19667 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19669 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19671 [(set_attr "type" "str")
19672 (set_attr "mode" "QI")
19673 (set_attr "prefix_rep" "1")])
19675 (define_expand "strlensi"
19676 [(set (match_operand:SI 0 "register_operand" "")
19677 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19678 (match_operand:QI 2 "immediate_operand" "")
19679 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19682 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19688 (define_expand "strlendi"
19689 [(set (match_operand:DI 0 "register_operand" "")
19690 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19691 (match_operand:QI 2 "immediate_operand" "")
19692 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19695 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19701 (define_expand "strlenqi_1"
19702 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19703 (clobber (match_operand 1 "register_operand" ""))
19704 (clobber (reg:CC FLAGS_REG))])]
19706 "ix86_current_function_needs_cld = 1;")
19708 (define_insn "*strlenqi_1"
19709 [(set (match_operand:SI 0 "register_operand" "=&c")
19710 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19711 (match_operand:QI 2 "register_operand" "a")
19712 (match_operand:SI 3 "immediate_operand" "i")
19713 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19714 (clobber (match_operand:SI 1 "register_operand" "=D"))
19715 (clobber (reg:CC FLAGS_REG))]
19717 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19719 [(set_attr "type" "str")
19720 (set_attr "mode" "QI")
19721 (set_attr "prefix_rep" "1")])
19723 (define_insn "*strlenqi_rex_1"
19724 [(set (match_operand:DI 0 "register_operand" "=&c")
19725 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19726 (match_operand:QI 2 "register_operand" "a")
19727 (match_operand:DI 3 "immediate_operand" "i")
19728 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19729 (clobber (match_operand:DI 1 "register_operand" "=D"))
19730 (clobber (reg:CC FLAGS_REG))]
19732 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19734 [(set_attr "type" "str")
19735 (set_attr "mode" "QI")
19736 (set_attr "prefix_rep" "1")])
19738 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19739 ;; handled in combine, but it is not currently up to the task.
19740 ;; When used for their truth value, the cmpstrn* expanders generate
19749 ;; The intermediate three instructions are unnecessary.
19751 ;; This one handles cmpstrn*_nz_1...
19754 (set (reg:CC FLAGS_REG)
19755 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19756 (mem:BLK (match_operand 5 "register_operand" ""))))
19757 (use (match_operand 6 "register_operand" ""))
19758 (use (match_operand:SI 3 "immediate_operand" ""))
19759 (clobber (match_operand 0 "register_operand" ""))
19760 (clobber (match_operand 1 "register_operand" ""))
19761 (clobber (match_operand 2 "register_operand" ""))])
19762 (set (match_operand:QI 7 "register_operand" "")
19763 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19764 (set (match_operand:QI 8 "register_operand" "")
19765 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19766 (set (reg FLAGS_REG)
19767 (compare (match_dup 7) (match_dup 8)))
19769 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19771 (set (reg:CC FLAGS_REG)
19772 (compare:CC (mem:BLK (match_dup 4))
19773 (mem:BLK (match_dup 5))))
19774 (use (match_dup 6))
19775 (use (match_dup 3))
19776 (clobber (match_dup 0))
19777 (clobber (match_dup 1))
19778 (clobber (match_dup 2))])]
19781 ;; ...and this one handles cmpstrn*_1.
19784 (set (reg:CC FLAGS_REG)
19785 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19787 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19788 (mem:BLK (match_operand 5 "register_operand" "")))
19790 (use (match_operand:SI 3 "immediate_operand" ""))
19791 (use (reg:CC FLAGS_REG))
19792 (clobber (match_operand 0 "register_operand" ""))
19793 (clobber (match_operand 1 "register_operand" ""))
19794 (clobber (match_operand 2 "register_operand" ""))])
19795 (set (match_operand:QI 7 "register_operand" "")
19796 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19797 (set (match_operand:QI 8 "register_operand" "")
19798 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19799 (set (reg FLAGS_REG)
19800 (compare (match_dup 7) (match_dup 8)))
19802 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19804 (set (reg:CC FLAGS_REG)
19805 (if_then_else:CC (ne (match_dup 6)
19807 (compare:CC (mem:BLK (match_dup 4))
19808 (mem:BLK (match_dup 5)))
19810 (use (match_dup 3))
19811 (use (reg:CC FLAGS_REG))
19812 (clobber (match_dup 0))
19813 (clobber (match_dup 1))
19814 (clobber (match_dup 2))])]
19819 ;; Conditional move instructions.
19821 (define_expand "movdicc"
19822 [(set (match_operand:DI 0 "register_operand" "")
19823 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19824 (match_operand:DI 2 "general_operand" "")
19825 (match_operand:DI 3 "general_operand" "")))]
19827 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19829 (define_insn "x86_movdicc_0_m1_rex64"
19830 [(set (match_operand:DI 0 "register_operand" "=r")
19831 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19834 (clobber (reg:CC FLAGS_REG))]
19837 ; Since we don't have the proper number of operands for an alu insn,
19838 ; fill in all the blanks.
19839 [(set_attr "type" "alu")
19840 (set_attr "pent_pair" "pu")
19841 (set_attr "memory" "none")
19842 (set_attr "imm_disp" "false")
19843 (set_attr "mode" "DI")
19844 (set_attr "length_immediate" "0")])
19846 (define_insn "*x86_movdicc_0_m1_se"
19847 [(set (match_operand:DI 0 "register_operand" "=r")
19848 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19851 (clobber (reg:CC FLAGS_REG))]
19854 [(set_attr "type" "alu")
19855 (set_attr "pent_pair" "pu")
19856 (set_attr "memory" "none")
19857 (set_attr "imm_disp" "false")
19858 (set_attr "mode" "DI")
19859 (set_attr "length_immediate" "0")])
19861 (define_insn "*movdicc_c_rex64"
19862 [(set (match_operand:DI 0 "register_operand" "=r,r")
19863 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19864 [(reg FLAGS_REG) (const_int 0)])
19865 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19866 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19867 "TARGET_64BIT && TARGET_CMOVE
19868 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19870 cmov%O2%C1\t{%2, %0|%0, %2}
19871 cmov%O2%c1\t{%3, %0|%0, %3}"
19872 [(set_attr "type" "icmov")
19873 (set_attr "mode" "DI")])
19875 (define_expand "movsicc"
19876 [(set (match_operand:SI 0 "register_operand" "")
19877 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19878 (match_operand:SI 2 "general_operand" "")
19879 (match_operand:SI 3 "general_operand" "")))]
19881 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19883 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19884 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19885 ;; So just document what we're doing explicitly.
19887 (define_insn "x86_movsicc_0_m1"
19888 [(set (match_operand:SI 0 "register_operand" "=r")
19889 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19892 (clobber (reg:CC FLAGS_REG))]
19895 ; Since we don't have the proper number of operands for an alu insn,
19896 ; fill in all the blanks.
19897 [(set_attr "type" "alu")
19898 (set_attr "pent_pair" "pu")
19899 (set_attr "memory" "none")
19900 (set_attr "imm_disp" "false")
19901 (set_attr "mode" "SI")
19902 (set_attr "length_immediate" "0")])
19904 (define_insn "*x86_movsicc_0_m1_se"
19905 [(set (match_operand:SI 0 "register_operand" "=r")
19906 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19909 (clobber (reg:CC FLAGS_REG))]
19912 [(set_attr "type" "alu")
19913 (set_attr "pent_pair" "pu")
19914 (set_attr "memory" "none")
19915 (set_attr "imm_disp" "false")
19916 (set_attr "mode" "SI")
19917 (set_attr "length_immediate" "0")])
19919 (define_insn "*movsicc_noc"
19920 [(set (match_operand:SI 0 "register_operand" "=r,r")
19921 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19922 [(reg FLAGS_REG) (const_int 0)])
19923 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19924 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19926 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19928 cmov%O2%C1\t{%2, %0|%0, %2}
19929 cmov%O2%c1\t{%3, %0|%0, %3}"
19930 [(set_attr "type" "icmov")
19931 (set_attr "mode" "SI")])
19933 (define_expand "movhicc"
19934 [(set (match_operand:HI 0 "register_operand" "")
19935 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19936 (match_operand:HI 2 "general_operand" "")
19937 (match_operand:HI 3 "general_operand" "")))]
19938 "TARGET_HIMODE_MATH"
19939 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19941 (define_insn "*movhicc_noc"
19942 [(set (match_operand:HI 0 "register_operand" "=r,r")
19943 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19944 [(reg FLAGS_REG) (const_int 0)])
19945 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19946 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19948 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19950 cmov%O2%C1\t{%2, %0|%0, %2}
19951 cmov%O2%c1\t{%3, %0|%0, %3}"
19952 [(set_attr "type" "icmov")
19953 (set_attr "mode" "HI")])
19955 (define_expand "movqicc"
19956 [(set (match_operand:QI 0 "register_operand" "")
19957 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19958 (match_operand:QI 2 "general_operand" "")
19959 (match_operand:QI 3 "general_operand" "")))]
19960 "TARGET_QIMODE_MATH"
19961 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19963 (define_insn_and_split "*movqicc_noc"
19964 [(set (match_operand:QI 0 "register_operand" "=r,r")
19965 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19966 [(match_operand 4 "flags_reg_operand" "")
19968 (match_operand:QI 2 "register_operand" "r,0")
19969 (match_operand:QI 3 "register_operand" "0,r")))]
19970 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19972 "&& reload_completed"
19973 [(set (match_dup 0)
19974 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19977 "operands[0] = gen_lowpart (SImode, operands[0]);
19978 operands[2] = gen_lowpart (SImode, operands[2]);
19979 operands[3] = gen_lowpart (SImode, operands[3]);"
19980 [(set_attr "type" "icmov")
19981 (set_attr "mode" "SI")])
19983 (define_expand "mov<mode>cc"
19984 [(set (match_operand:X87MODEF 0 "register_operand" "")
19985 (if_then_else:X87MODEF
19986 (match_operand 1 "comparison_operator" "")
19987 (match_operand:X87MODEF 2 "register_operand" "")
19988 (match_operand:X87MODEF 3 "register_operand" "")))]
19989 "(TARGET_80387 && TARGET_CMOVE)
19990 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19991 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19993 (define_insn "*movsfcc_1_387"
19994 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19995 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19996 [(reg FLAGS_REG) (const_int 0)])
19997 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19998 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19999 "TARGET_80387 && TARGET_CMOVE
20000 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20002 fcmov%F1\t{%2, %0|%0, %2}
20003 fcmov%f1\t{%3, %0|%0, %3}
20004 cmov%O2%C1\t{%2, %0|%0, %2}
20005 cmov%O2%c1\t{%3, %0|%0, %3}"
20006 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20007 (set_attr "mode" "SF,SF,SI,SI")])
20009 (define_insn "*movdfcc_1"
20010 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20011 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20012 [(reg FLAGS_REG) (const_int 0)])
20013 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20014 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20015 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20016 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20018 fcmov%F1\t{%2, %0|%0, %2}
20019 fcmov%f1\t{%3, %0|%0, %3}
20022 [(set_attr "type" "fcmov,fcmov,multi,multi")
20023 (set_attr "mode" "DF")])
20025 (define_insn "*movdfcc_1_rex64"
20026 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20027 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20028 [(reg FLAGS_REG) (const_int 0)])
20029 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20030 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20031 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20032 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20034 fcmov%F1\t{%2, %0|%0, %2}
20035 fcmov%f1\t{%3, %0|%0, %3}
20036 cmov%O2%C1\t{%2, %0|%0, %2}
20037 cmov%O2%c1\t{%3, %0|%0, %3}"
20038 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20039 (set_attr "mode" "DF")])
20042 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20043 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20044 [(match_operand 4 "flags_reg_operand" "")
20046 (match_operand:DF 2 "nonimmediate_operand" "")
20047 (match_operand:DF 3 "nonimmediate_operand" "")))]
20048 "!TARGET_64BIT && reload_completed"
20049 [(set (match_dup 2)
20050 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20054 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20057 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20058 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20060 (define_insn "*movxfcc_1"
20061 [(set (match_operand:XF 0 "register_operand" "=f,f")
20062 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20063 [(reg FLAGS_REG) (const_int 0)])
20064 (match_operand:XF 2 "register_operand" "f,0")
20065 (match_operand:XF 3 "register_operand" "0,f")))]
20066 "TARGET_80387 && TARGET_CMOVE"
20068 fcmov%F1\t{%2, %0|%0, %2}
20069 fcmov%f1\t{%3, %0|%0, %3}"
20070 [(set_attr "type" "fcmov")
20071 (set_attr "mode" "XF")])
20073 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20074 ;; the scalar versions to have only XMM registers as operands.
20076 ;; SSE5 conditional move
20077 (define_insn "*sse5_pcmov_<mode>"
20078 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20079 (if_then_else:MODEF
20080 (match_operand:MODEF 1 "register_operand" "x,0")
20081 (match_operand:MODEF 2 "register_operand" "0,x")
20082 (match_operand:MODEF 3 "register_operand" "x,x")))]
20083 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20084 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20085 [(set_attr "type" "sse4arg")])
20087 ;; These versions of the min/max patterns are intentionally ignorant of
20088 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20089 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20090 ;; are undefined in this condition, we're certain this is correct.
20092 (define_insn "*avx_<code><mode>3"
20093 [(set (match_operand:MODEF 0 "register_operand" "=x")
20095 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20096 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20097 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20098 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20099 [(set_attr "type" "sseadd")
20100 (set_attr "prefix" "vex")
20101 (set_attr "mode" "<MODE>")])
20103 (define_insn "<code><mode>3"
20104 [(set (match_operand:MODEF 0 "register_operand" "=x")
20106 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20107 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20108 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20109 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20110 [(set_attr "type" "sseadd")
20111 (set_attr "mode" "<MODE>")])
20113 ;; These versions of the min/max patterns implement exactly the operations
20114 ;; min = (op1 < op2 ? op1 : op2)
20115 ;; max = (!(op1 < op2) ? op1 : op2)
20116 ;; Their operands are not commutative, and thus they may be used in the
20117 ;; presence of -0.0 and NaN.
20119 (define_insn "*avx_ieee_smin<mode>3"
20120 [(set (match_operand:MODEF 0 "register_operand" "=x")
20122 [(match_operand:MODEF 1 "register_operand" "x")
20123 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20125 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20126 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20127 [(set_attr "type" "sseadd")
20128 (set_attr "prefix" "vex")
20129 (set_attr "mode" "<MODE>")])
20131 (define_insn "*ieee_smin<mode>3"
20132 [(set (match_operand:MODEF 0 "register_operand" "=x")
20134 [(match_operand:MODEF 1 "register_operand" "0")
20135 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20137 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20138 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20139 [(set_attr "type" "sseadd")
20140 (set_attr "mode" "<MODE>")])
20142 (define_insn "*avx_ieee_smax<mode>3"
20143 [(set (match_operand:MODEF 0 "register_operand" "=x")
20145 [(match_operand:MODEF 1 "register_operand" "0")
20146 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20148 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20149 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20150 [(set_attr "type" "sseadd")
20151 (set_attr "prefix" "vex")
20152 (set_attr "mode" "<MODE>")])
20154 (define_insn "*ieee_smax<mode>3"
20155 [(set (match_operand:MODEF 0 "register_operand" "=x")
20157 [(match_operand:MODEF 1 "register_operand" "0")
20158 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20160 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20161 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20162 [(set_attr "type" "sseadd")
20163 (set_attr "mode" "<MODE>")])
20165 ;; Make two stack loads independent:
20167 ;; fld %st(0) -> fld bb
20168 ;; fmul bb fmul %st(1), %st
20170 ;; Actually we only match the last two instructions for simplicity.
20172 [(set (match_operand 0 "fp_register_operand" "")
20173 (match_operand 1 "fp_register_operand" ""))
20175 (match_operator 2 "binary_fp_operator"
20177 (match_operand 3 "memory_operand" "")]))]
20178 "REGNO (operands[0]) != REGNO (operands[1])"
20179 [(set (match_dup 0) (match_dup 3))
20180 (set (match_dup 0) (match_dup 4))]
20182 ;; The % modifier is not operational anymore in peephole2's, so we have to
20183 ;; swap the operands manually in the case of addition and multiplication.
20184 "if (COMMUTATIVE_ARITH_P (operands[2]))
20185 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20186 operands[0], operands[1]);
20188 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20189 operands[1], operands[0]);")
20191 ;; Conditional addition patterns
20192 (define_expand "add<mode>cc"
20193 [(match_operand:SWI 0 "register_operand" "")
20194 (match_operand 1 "comparison_operator" "")
20195 (match_operand:SWI 2 "register_operand" "")
20196 (match_operand:SWI 3 "const_int_operand" "")]
20198 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20201 ;; Misc patterns (?)
20203 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20204 ;; Otherwise there will be nothing to keep
20206 ;; [(set (reg ebp) (reg esp))]
20207 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20208 ;; (clobber (eflags)]
20209 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20211 ;; in proper program order.
20212 (define_insn "pro_epilogue_adjust_stack_1"
20213 [(set (match_operand:SI 0 "register_operand" "=r,r")
20214 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20215 (match_operand:SI 2 "immediate_operand" "i,i")))
20216 (clobber (reg:CC FLAGS_REG))
20217 (clobber (mem:BLK (scratch)))]
20220 switch (get_attr_type (insn))
20223 return "mov{l}\t{%1, %0|%0, %1}";
20226 if (CONST_INT_P (operands[2])
20227 && (INTVAL (operands[2]) == 128
20228 || (INTVAL (operands[2]) < 0
20229 && INTVAL (operands[2]) != -128)))
20231 operands[2] = GEN_INT (-INTVAL (operands[2]));
20232 return "sub{l}\t{%2, %0|%0, %2}";
20234 return "add{l}\t{%2, %0|%0, %2}";
20237 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20238 return "lea{l}\t{%a2, %0|%0, %a2}";
20241 gcc_unreachable ();
20244 [(set (attr "type")
20245 (cond [(eq_attr "alternative" "0")
20246 (const_string "alu")
20247 (match_operand:SI 2 "const0_operand" "")
20248 (const_string "imov")
20250 (const_string "lea")))
20251 (set_attr "mode" "SI")])
20253 (define_insn "pro_epilogue_adjust_stack_rex64"
20254 [(set (match_operand:DI 0 "register_operand" "=r,r")
20255 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20256 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20257 (clobber (reg:CC FLAGS_REG))
20258 (clobber (mem:BLK (scratch)))]
20261 switch (get_attr_type (insn))
20264 return "mov{q}\t{%1, %0|%0, %1}";
20267 if (CONST_INT_P (operands[2])
20268 /* Avoid overflows. */
20269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20270 && (INTVAL (operands[2]) == 128
20271 || (INTVAL (operands[2]) < 0
20272 && INTVAL (operands[2]) != -128)))
20274 operands[2] = GEN_INT (-INTVAL (operands[2]));
20275 return "sub{q}\t{%2, %0|%0, %2}";
20277 return "add{q}\t{%2, %0|%0, %2}";
20280 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20281 return "lea{q}\t{%a2, %0|%0, %a2}";
20284 gcc_unreachable ();
20287 [(set (attr "type")
20288 (cond [(eq_attr "alternative" "0")
20289 (const_string "alu")
20290 (match_operand:DI 2 "const0_operand" "")
20291 (const_string "imov")
20293 (const_string "lea")))
20294 (set_attr "mode" "DI")])
20296 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20297 [(set (match_operand:DI 0 "register_operand" "=r,r")
20298 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20299 (match_operand:DI 3 "immediate_operand" "i,i")))
20300 (use (match_operand:DI 2 "register_operand" "r,r"))
20301 (clobber (reg:CC FLAGS_REG))
20302 (clobber (mem:BLK (scratch)))]
20305 switch (get_attr_type (insn))
20308 return "add{q}\t{%2, %0|%0, %2}";
20311 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20312 return "lea{q}\t{%a2, %0|%0, %a2}";
20315 gcc_unreachable ();
20318 [(set_attr "type" "alu,lea")
20319 (set_attr "mode" "DI")])
20321 (define_insn "allocate_stack_worker_32"
20322 [(set (match_operand:SI 0 "register_operand" "=a")
20323 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20324 UNSPECV_STACK_PROBE))
20325 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20326 (clobber (reg:CC FLAGS_REG))]
20327 "!TARGET_64BIT && TARGET_STACK_PROBE"
20329 [(set_attr "type" "multi")
20330 (set_attr "length" "5")])
20332 (define_insn "allocate_stack_worker_64"
20333 [(set (match_operand:DI 0 "register_operand" "=a")
20334 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20335 UNSPECV_STACK_PROBE))
20336 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20337 (clobber (reg:DI R10_REG))
20338 (clobber (reg:DI R11_REG))
20339 (clobber (reg:CC FLAGS_REG))]
20340 "TARGET_64BIT && TARGET_STACK_PROBE"
20342 [(set_attr "type" "multi")
20343 (set_attr "length" "5")])
20345 (define_expand "allocate_stack"
20346 [(match_operand 0 "register_operand" "")
20347 (match_operand 1 "general_operand" "")]
20348 "TARGET_STACK_PROBE"
20352 #ifndef CHECK_STACK_LIMIT
20353 #define CHECK_STACK_LIMIT 0
20356 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20357 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20359 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20360 stack_pointer_rtx, 0, OPTAB_DIRECT);
20361 if (x != stack_pointer_rtx)
20362 emit_move_insn (stack_pointer_rtx, x);
20366 x = copy_to_mode_reg (Pmode, operands[1]);
20368 x = gen_allocate_stack_worker_64 (x, x);
20370 x = gen_allocate_stack_worker_32 (x, x);
20374 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20378 (define_expand "builtin_setjmp_receiver"
20379 [(label_ref (match_operand 0 "" ""))]
20380 "!TARGET_64BIT && flag_pic"
20386 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20387 rtx label_rtx = gen_label_rtx ();
20388 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20389 xops[0] = xops[1] = picreg;
20390 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20391 ix86_expand_binary_operator (MINUS, SImode, xops);
20395 emit_insn (gen_set_got (pic_offset_table_rtx));
20399 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20402 [(set (match_operand 0 "register_operand" "")
20403 (match_operator 3 "promotable_binary_operator"
20404 [(match_operand 1 "register_operand" "")
20405 (match_operand 2 "aligned_operand" "")]))
20406 (clobber (reg:CC FLAGS_REG))]
20407 "! TARGET_PARTIAL_REG_STALL && reload_completed
20408 && ((GET_MODE (operands[0]) == HImode
20409 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20410 /* ??? next two lines just !satisfies_constraint_K (...) */
20411 || !CONST_INT_P (operands[2])
20412 || satisfies_constraint_K (operands[2])))
20413 || (GET_MODE (operands[0]) == QImode
20414 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20415 [(parallel [(set (match_dup 0)
20416 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20417 (clobber (reg:CC FLAGS_REG))])]
20418 "operands[0] = gen_lowpart (SImode, operands[0]);
20419 operands[1] = gen_lowpart (SImode, operands[1]);
20420 if (GET_CODE (operands[3]) != ASHIFT)
20421 operands[2] = gen_lowpart (SImode, operands[2]);
20422 PUT_MODE (operands[3], SImode);")
20424 ; Promote the QImode tests, as i386 has encoding of the AND
20425 ; instruction with 32-bit sign-extended immediate and thus the
20426 ; instruction size is unchanged, except in the %eax case for
20427 ; which it is increased by one byte, hence the ! optimize_size.
20429 [(set (match_operand 0 "flags_reg_operand" "")
20430 (match_operator 2 "compare_operator"
20431 [(and (match_operand 3 "aligned_operand" "")
20432 (match_operand 4 "const_int_operand" ""))
20434 (set (match_operand 1 "register_operand" "")
20435 (and (match_dup 3) (match_dup 4)))]
20436 "! TARGET_PARTIAL_REG_STALL && reload_completed
20437 && optimize_insn_for_speed_p ()
20438 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20439 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20440 /* Ensure that the operand will remain sign-extended immediate. */
20441 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20442 [(parallel [(set (match_dup 0)
20443 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20446 (and:SI (match_dup 3) (match_dup 4)))])]
20449 = gen_int_mode (INTVAL (operands[4])
20450 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20451 operands[1] = gen_lowpart (SImode, operands[1]);
20452 operands[3] = gen_lowpart (SImode, operands[3]);
20455 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20456 ; the TEST instruction with 32-bit sign-extended immediate and thus
20457 ; the instruction size would at least double, which is not what we
20458 ; want even with ! optimize_size.
20460 [(set (match_operand 0 "flags_reg_operand" "")
20461 (match_operator 1 "compare_operator"
20462 [(and (match_operand:HI 2 "aligned_operand" "")
20463 (match_operand:HI 3 "const_int_operand" ""))
20465 "! TARGET_PARTIAL_REG_STALL && reload_completed
20466 && ! TARGET_FAST_PREFIX
20467 && optimize_insn_for_speed_p ()
20468 /* Ensure that the operand will remain sign-extended immediate. */
20469 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20470 [(set (match_dup 0)
20471 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20475 = gen_int_mode (INTVAL (operands[3])
20476 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20477 operands[2] = gen_lowpart (SImode, operands[2]);
20481 [(set (match_operand 0 "register_operand" "")
20482 (neg (match_operand 1 "register_operand" "")))
20483 (clobber (reg:CC FLAGS_REG))]
20484 "! TARGET_PARTIAL_REG_STALL && reload_completed
20485 && (GET_MODE (operands[0]) == HImode
20486 || (GET_MODE (operands[0]) == QImode
20487 && (TARGET_PROMOTE_QImode
20488 || optimize_insn_for_size_p ())))"
20489 [(parallel [(set (match_dup 0)
20490 (neg:SI (match_dup 1)))
20491 (clobber (reg:CC FLAGS_REG))])]
20492 "operands[0] = gen_lowpart (SImode, operands[0]);
20493 operands[1] = gen_lowpart (SImode, operands[1]);")
20496 [(set (match_operand 0 "register_operand" "")
20497 (not (match_operand 1 "register_operand" "")))]
20498 "! TARGET_PARTIAL_REG_STALL && reload_completed
20499 && (GET_MODE (operands[0]) == HImode
20500 || (GET_MODE (operands[0]) == QImode
20501 && (TARGET_PROMOTE_QImode
20502 || optimize_insn_for_size_p ())))"
20503 [(set (match_dup 0)
20504 (not:SI (match_dup 1)))]
20505 "operands[0] = gen_lowpart (SImode, operands[0]);
20506 operands[1] = gen_lowpart (SImode, operands[1]);")
20509 [(set (match_operand 0 "register_operand" "")
20510 (if_then_else (match_operator 1 "comparison_operator"
20511 [(reg FLAGS_REG) (const_int 0)])
20512 (match_operand 2 "register_operand" "")
20513 (match_operand 3 "register_operand" "")))]
20514 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20515 && (GET_MODE (operands[0]) == HImode
20516 || (GET_MODE (operands[0]) == QImode
20517 && (TARGET_PROMOTE_QImode
20518 || optimize_insn_for_size_p ())))"
20519 [(set (match_dup 0)
20520 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20521 "operands[0] = gen_lowpart (SImode, operands[0]);
20522 operands[2] = gen_lowpart (SImode, operands[2]);
20523 operands[3] = gen_lowpart (SImode, operands[3]);")
20526 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20527 ;; transform a complex memory operation into two memory to register operations.
20529 ;; Don't push memory operands
20531 [(set (match_operand:SI 0 "push_operand" "")
20532 (match_operand:SI 1 "memory_operand" ""))
20533 (match_scratch:SI 2 "r")]
20534 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20535 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20536 [(set (match_dup 2) (match_dup 1))
20537 (set (match_dup 0) (match_dup 2))]
20541 [(set (match_operand:DI 0 "push_operand" "")
20542 (match_operand:DI 1 "memory_operand" ""))
20543 (match_scratch:DI 2 "r")]
20544 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20545 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20546 [(set (match_dup 2) (match_dup 1))
20547 (set (match_dup 0) (match_dup 2))]
20550 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20553 [(set (match_operand:SF 0 "push_operand" "")
20554 (match_operand:SF 1 "memory_operand" ""))
20555 (match_scratch:SF 2 "r")]
20556 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20557 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20558 [(set (match_dup 2) (match_dup 1))
20559 (set (match_dup 0) (match_dup 2))]
20563 [(set (match_operand:HI 0 "push_operand" "")
20564 (match_operand:HI 1 "memory_operand" ""))
20565 (match_scratch:HI 2 "r")]
20566 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20567 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20568 [(set (match_dup 2) (match_dup 1))
20569 (set (match_dup 0) (match_dup 2))]
20573 [(set (match_operand:QI 0 "push_operand" "")
20574 (match_operand:QI 1 "memory_operand" ""))
20575 (match_scratch:QI 2 "q")]
20576 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20577 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20578 [(set (match_dup 2) (match_dup 1))
20579 (set (match_dup 0) (match_dup 2))]
20582 ;; Don't move an immediate directly to memory when the instruction
20585 [(match_scratch:SI 1 "r")
20586 (set (match_operand:SI 0 "memory_operand" "")
20588 "optimize_insn_for_speed_p ()
20589 && ! TARGET_USE_MOV0
20590 && TARGET_SPLIT_LONG_MOVES
20591 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20592 && peep2_regno_dead_p (0, FLAGS_REG)"
20593 [(parallel [(set (match_dup 1) (const_int 0))
20594 (clobber (reg:CC FLAGS_REG))])
20595 (set (match_dup 0) (match_dup 1))]
20599 [(match_scratch:HI 1 "r")
20600 (set (match_operand:HI 0 "memory_operand" "")
20602 "optimize_insn_for_speed_p ()
20603 && ! TARGET_USE_MOV0
20604 && TARGET_SPLIT_LONG_MOVES
20605 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20606 && peep2_regno_dead_p (0, FLAGS_REG)"
20607 [(parallel [(set (match_dup 2) (const_int 0))
20608 (clobber (reg:CC FLAGS_REG))])
20609 (set (match_dup 0) (match_dup 1))]
20610 "operands[2] = gen_lowpart (SImode, operands[1]);")
20613 [(match_scratch:QI 1 "q")
20614 (set (match_operand:QI 0 "memory_operand" "")
20616 "optimize_insn_for_speed_p ()
20617 && ! TARGET_USE_MOV0
20618 && TARGET_SPLIT_LONG_MOVES
20619 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20620 && peep2_regno_dead_p (0, FLAGS_REG)"
20621 [(parallel [(set (match_dup 2) (const_int 0))
20622 (clobber (reg:CC FLAGS_REG))])
20623 (set (match_dup 0) (match_dup 1))]
20624 "operands[2] = gen_lowpart (SImode, operands[1]);")
20627 [(match_scratch:SI 2 "r")
20628 (set (match_operand:SI 0 "memory_operand" "")
20629 (match_operand:SI 1 "immediate_operand" ""))]
20630 "optimize_insn_for_speed_p ()
20631 && TARGET_SPLIT_LONG_MOVES
20632 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20633 [(set (match_dup 2) (match_dup 1))
20634 (set (match_dup 0) (match_dup 2))]
20638 [(match_scratch:HI 2 "r")
20639 (set (match_operand:HI 0 "memory_operand" "")
20640 (match_operand:HI 1 "immediate_operand" ""))]
20641 "optimize_insn_for_speed_p ()
20642 && TARGET_SPLIT_LONG_MOVES
20643 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20644 [(set (match_dup 2) (match_dup 1))
20645 (set (match_dup 0) (match_dup 2))]
20649 [(match_scratch:QI 2 "q")
20650 (set (match_operand:QI 0 "memory_operand" "")
20651 (match_operand:QI 1 "immediate_operand" ""))]
20652 "optimize_insn_for_speed_p ()
20653 && TARGET_SPLIT_LONG_MOVES
20654 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20655 [(set (match_dup 2) (match_dup 1))
20656 (set (match_dup 0) (match_dup 2))]
20659 ;; Don't compare memory with zero, load and use a test instead.
20661 [(set (match_operand 0 "flags_reg_operand" "")
20662 (match_operator 1 "compare_operator"
20663 [(match_operand:SI 2 "memory_operand" "")
20665 (match_scratch:SI 3 "r")]
20666 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20667 [(set (match_dup 3) (match_dup 2))
20668 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20671 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20672 ;; Don't split NOTs with a displacement operand, because resulting XOR
20673 ;; will not be pairable anyway.
20675 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20676 ;; represented using a modRM byte. The XOR replacement is long decoded,
20677 ;; so this split helps here as well.
20679 ;; Note: Can't do this as a regular split because we can't get proper
20680 ;; lifetime information then.
20683 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20684 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20685 "optimize_insn_for_speed_p ()
20686 && ((TARGET_NOT_UNPAIRABLE
20687 && (!MEM_P (operands[0])
20688 || !memory_displacement_operand (operands[0], SImode)))
20689 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20690 && peep2_regno_dead_p (0, FLAGS_REG)"
20691 [(parallel [(set (match_dup 0)
20692 (xor:SI (match_dup 1) (const_int -1)))
20693 (clobber (reg:CC FLAGS_REG))])]
20697 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20698 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20699 "optimize_insn_for_speed_p ()
20700 && ((TARGET_NOT_UNPAIRABLE
20701 && (!MEM_P (operands[0])
20702 || !memory_displacement_operand (operands[0], HImode)))
20703 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20704 && peep2_regno_dead_p (0, FLAGS_REG)"
20705 [(parallel [(set (match_dup 0)
20706 (xor:HI (match_dup 1) (const_int -1)))
20707 (clobber (reg:CC FLAGS_REG))])]
20711 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20712 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20713 "optimize_insn_for_speed_p ()
20714 && ((TARGET_NOT_UNPAIRABLE
20715 && (!MEM_P (operands[0])
20716 || !memory_displacement_operand (operands[0], QImode)))
20717 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20718 && peep2_regno_dead_p (0, FLAGS_REG)"
20719 [(parallel [(set (match_dup 0)
20720 (xor:QI (match_dup 1) (const_int -1)))
20721 (clobber (reg:CC FLAGS_REG))])]
20724 ;; Non pairable "test imm, reg" instructions can be translated to
20725 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20726 ;; byte opcode instead of two, have a short form for byte operands),
20727 ;; so do it for other CPUs as well. Given that the value was dead,
20728 ;; this should not create any new dependencies. Pass on the sub-word
20729 ;; versions if we're concerned about partial register stalls.
20732 [(set (match_operand 0 "flags_reg_operand" "")
20733 (match_operator 1 "compare_operator"
20734 [(and:SI (match_operand:SI 2 "register_operand" "")
20735 (match_operand:SI 3 "immediate_operand" ""))
20737 "ix86_match_ccmode (insn, CCNOmode)
20738 && (true_regnum (operands[2]) != AX_REG
20739 || satisfies_constraint_K (operands[3]))
20740 && peep2_reg_dead_p (1, operands[2])"
20742 [(set (match_dup 0)
20743 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20746 (and:SI (match_dup 2) (match_dup 3)))])]
20749 ;; We don't need to handle HImode case, because it will be promoted to SImode
20750 ;; on ! TARGET_PARTIAL_REG_STALL
20753 [(set (match_operand 0 "flags_reg_operand" "")
20754 (match_operator 1 "compare_operator"
20755 [(and:QI (match_operand:QI 2 "register_operand" "")
20756 (match_operand:QI 3 "immediate_operand" ""))
20758 "! TARGET_PARTIAL_REG_STALL
20759 && ix86_match_ccmode (insn, CCNOmode)
20760 && true_regnum (operands[2]) != AX_REG
20761 && peep2_reg_dead_p (1, operands[2])"
20763 [(set (match_dup 0)
20764 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20767 (and:QI (match_dup 2) (match_dup 3)))])]
20771 [(set (match_operand 0 "flags_reg_operand" "")
20772 (match_operator 1 "compare_operator"
20775 (match_operand 2 "ext_register_operand" "")
20778 (match_operand 3 "const_int_operand" ""))
20780 "! TARGET_PARTIAL_REG_STALL
20781 && ix86_match_ccmode (insn, CCNOmode)
20782 && true_regnum (operands[2]) != AX_REG
20783 && peep2_reg_dead_p (1, operands[2])"
20784 [(parallel [(set (match_dup 0)
20793 (set (zero_extract:SI (match_dup 2)
20804 ;; Don't do logical operations with memory inputs.
20806 [(match_scratch:SI 2 "r")
20807 (parallel [(set (match_operand:SI 0 "register_operand" "")
20808 (match_operator:SI 3 "arith_or_logical_operator"
20810 (match_operand:SI 1 "memory_operand" "")]))
20811 (clobber (reg:CC FLAGS_REG))])]
20812 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20813 [(set (match_dup 2) (match_dup 1))
20814 (parallel [(set (match_dup 0)
20815 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20816 (clobber (reg:CC FLAGS_REG))])]
20820 [(match_scratch:SI 2 "r")
20821 (parallel [(set (match_operand:SI 0 "register_operand" "")
20822 (match_operator:SI 3 "arith_or_logical_operator"
20823 [(match_operand:SI 1 "memory_operand" "")
20825 (clobber (reg:CC FLAGS_REG))])]
20826 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20827 [(set (match_dup 2) (match_dup 1))
20828 (parallel [(set (match_dup 0)
20829 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20830 (clobber (reg:CC FLAGS_REG))])]
20833 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20834 ;; refers to the destination of the load!
20837 [(set (match_operand:SI 0 "register_operand" "")
20838 (match_operand:SI 1 "register_operand" ""))
20839 (parallel [(set (match_dup 0)
20840 (match_operator:SI 3 "commutative_operator"
20842 (match_operand:SI 2 "memory_operand" "")]))
20843 (clobber (reg:CC FLAGS_REG))])]
20844 "REGNO (operands[0]) != REGNO (operands[1])
20845 && GENERAL_REGNO_P (REGNO (operands[0]))
20846 && GENERAL_REGNO_P (REGNO (operands[1]))"
20847 [(set (match_dup 0) (match_dup 4))
20848 (parallel [(set (match_dup 0)
20849 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20850 (clobber (reg:CC FLAGS_REG))])]
20851 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20854 [(set (match_operand 0 "register_operand" "")
20855 (match_operand 1 "register_operand" ""))
20857 (match_operator 3 "commutative_operator"
20859 (match_operand 2 "memory_operand" "")]))]
20860 "REGNO (operands[0]) != REGNO (operands[1])
20861 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20862 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20863 [(set (match_dup 0) (match_dup 2))
20865 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20868 ; Don't do logical operations with memory outputs
20870 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20871 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20872 ; the same decoder scheduling characteristics as the original.
20875 [(match_scratch:SI 2 "r")
20876 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20877 (match_operator:SI 3 "arith_or_logical_operator"
20879 (match_operand:SI 1 "nonmemory_operand" "")]))
20880 (clobber (reg:CC FLAGS_REG))])]
20881 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20882 [(set (match_dup 2) (match_dup 0))
20883 (parallel [(set (match_dup 2)
20884 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20885 (clobber (reg:CC FLAGS_REG))])
20886 (set (match_dup 0) (match_dup 2))]
20890 [(match_scratch:SI 2 "r")
20891 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20892 (match_operator:SI 3 "arith_or_logical_operator"
20893 [(match_operand:SI 1 "nonmemory_operand" "")
20895 (clobber (reg:CC FLAGS_REG))])]
20896 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20897 [(set (match_dup 2) (match_dup 0))
20898 (parallel [(set (match_dup 2)
20899 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20900 (clobber (reg:CC FLAGS_REG))])
20901 (set (match_dup 0) (match_dup 2))]
20904 ;; Attempt to always use XOR for zeroing registers.
20906 [(set (match_operand 0 "register_operand" "")
20907 (match_operand 1 "const0_operand" ""))]
20908 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20909 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20910 && GENERAL_REG_P (operands[0])
20911 && peep2_regno_dead_p (0, FLAGS_REG)"
20912 [(parallel [(set (match_dup 0) (const_int 0))
20913 (clobber (reg:CC FLAGS_REG))])]
20915 operands[0] = gen_lowpart (word_mode, operands[0]);
20919 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20921 "(GET_MODE (operands[0]) == QImode
20922 || GET_MODE (operands[0]) == HImode)
20923 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20924 && peep2_regno_dead_p (0, FLAGS_REG)"
20925 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20926 (clobber (reg:CC FLAGS_REG))])])
20928 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20930 [(set (match_operand 0 "register_operand" "")
20932 "(GET_MODE (operands[0]) == HImode
20933 || GET_MODE (operands[0]) == SImode
20934 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20935 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20936 && peep2_regno_dead_p (0, FLAGS_REG)"
20937 [(parallel [(set (match_dup 0) (const_int -1))
20938 (clobber (reg:CC FLAGS_REG))])]
20939 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20942 ;; Attempt to convert simple leas to adds. These can be created by
20945 [(set (match_operand:SI 0 "register_operand" "")
20946 (plus:SI (match_dup 0)
20947 (match_operand:SI 1 "nonmemory_operand" "")))]
20948 "peep2_regno_dead_p (0, FLAGS_REG)"
20949 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20950 (clobber (reg:CC FLAGS_REG))])]
20954 [(set (match_operand:SI 0 "register_operand" "")
20955 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20956 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20957 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20958 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20959 (clobber (reg:CC FLAGS_REG))])]
20960 "operands[2] = gen_lowpart (SImode, operands[2]);")
20963 [(set (match_operand:DI 0 "register_operand" "")
20964 (plus:DI (match_dup 0)
20965 (match_operand:DI 1 "x86_64_general_operand" "")))]
20966 "peep2_regno_dead_p (0, FLAGS_REG)"
20967 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20968 (clobber (reg:CC FLAGS_REG))])]
20972 [(set (match_operand:SI 0 "register_operand" "")
20973 (mult:SI (match_dup 0)
20974 (match_operand:SI 1 "const_int_operand" "")))]
20975 "exact_log2 (INTVAL (operands[1])) >= 0
20976 && peep2_regno_dead_p (0, FLAGS_REG)"
20977 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20978 (clobber (reg:CC FLAGS_REG))])]
20979 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20982 [(set (match_operand:DI 0 "register_operand" "")
20983 (mult:DI (match_dup 0)
20984 (match_operand:DI 1 "const_int_operand" "")))]
20985 "exact_log2 (INTVAL (operands[1])) >= 0
20986 && peep2_regno_dead_p (0, FLAGS_REG)"
20987 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20988 (clobber (reg:CC FLAGS_REG))])]
20989 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20992 [(set (match_operand:SI 0 "register_operand" "")
20993 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20994 (match_operand:DI 2 "const_int_operand" "")) 0))]
20995 "exact_log2 (INTVAL (operands[2])) >= 0
20996 && REGNO (operands[0]) == REGNO (operands[1])
20997 && peep2_regno_dead_p (0, FLAGS_REG)"
20998 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20999 (clobber (reg:CC FLAGS_REG))])]
21000 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21002 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21003 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21004 ;; many CPUs it is also faster, since special hardware to avoid esp
21005 ;; dependencies is present.
21007 ;; While some of these conversions may be done using splitters, we use peepholes
21008 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21010 ;; Convert prologue esp subtractions to push.
21011 ;; We need register to push. In order to keep verify_flow_info happy we have
21013 ;; - use scratch and clobber it in order to avoid dependencies
21014 ;; - use already live register
21015 ;; We can't use the second way right now, since there is no reliable way how to
21016 ;; verify that given register is live. First choice will also most likely in
21017 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21018 ;; call clobbered registers are dead. We may want to use base pointer as an
21019 ;; alternative when no register is available later.
21022 [(match_scratch:SI 0 "r")
21023 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21024 (clobber (reg:CC FLAGS_REG))
21025 (clobber (mem:BLK (scratch)))])]
21026 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21027 [(clobber (match_dup 0))
21028 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21029 (clobber (mem:BLK (scratch)))])])
21032 [(match_scratch:SI 0 "r")
21033 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21034 (clobber (reg:CC FLAGS_REG))
21035 (clobber (mem:BLK (scratch)))])]
21036 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21037 [(clobber (match_dup 0))
21038 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21039 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21040 (clobber (mem:BLK (scratch)))])])
21042 ;; Convert esp subtractions to push.
21044 [(match_scratch:SI 0 "r")
21045 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21046 (clobber (reg:CC FLAGS_REG))])]
21047 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21048 [(clobber (match_dup 0))
21049 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21052 [(match_scratch:SI 0 "r")
21053 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21054 (clobber (reg:CC FLAGS_REG))])]
21055 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21056 [(clobber (match_dup 0))
21057 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21058 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21060 ;; Convert epilogue deallocator to pop.
21062 [(match_scratch:SI 0 "r")
21063 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21064 (clobber (reg:CC FLAGS_REG))
21065 (clobber (mem:BLK (scratch)))])]
21066 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21067 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21068 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21069 (clobber (mem:BLK (scratch)))])]
21072 ;; Two pops case is tricky, since pop causes dependency on destination register.
21073 ;; We use two registers if available.
21075 [(match_scratch:SI 0 "r")
21076 (match_scratch:SI 1 "r")
21077 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21078 (clobber (reg:CC FLAGS_REG))
21079 (clobber (mem:BLK (scratch)))])]
21080 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21081 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21082 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21083 (clobber (mem:BLK (scratch)))])
21084 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21089 [(match_scratch:SI 0 "r")
21090 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21091 (clobber (reg:CC FLAGS_REG))
21092 (clobber (mem:BLK (scratch)))])]
21093 "optimize_insn_for_size_p ()"
21094 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21095 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21096 (clobber (mem:BLK (scratch)))])
21097 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21098 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21101 ;; Convert esp additions to pop.
21103 [(match_scratch:SI 0 "r")
21104 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21105 (clobber (reg:CC FLAGS_REG))])]
21107 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21108 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21111 ;; Two pops case is tricky, since pop causes dependency on destination register.
21112 ;; We use two registers if available.
21114 [(match_scratch:SI 0 "r")
21115 (match_scratch:SI 1 "r")
21116 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21117 (clobber (reg:CC FLAGS_REG))])]
21119 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21120 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21121 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21122 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21126 [(match_scratch:SI 0 "r")
21127 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21128 (clobber (reg:CC FLAGS_REG))])]
21129 "optimize_insn_for_size_p ()"
21130 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21131 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21132 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21133 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21136 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21137 ;; required and register dies. Similarly for 128 to -128.
21139 [(set (match_operand 0 "flags_reg_operand" "")
21140 (match_operator 1 "compare_operator"
21141 [(match_operand 2 "register_operand" "")
21142 (match_operand 3 "const_int_operand" "")]))]
21143 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21144 && incdec_operand (operands[3], GET_MODE (operands[3])))
21145 || (!TARGET_FUSE_CMP_AND_BRANCH
21146 && INTVAL (operands[3]) == 128))
21147 && ix86_match_ccmode (insn, CCGCmode)
21148 && peep2_reg_dead_p (1, operands[2])"
21149 [(parallel [(set (match_dup 0)
21150 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21151 (clobber (match_dup 2))])]
21155 [(match_scratch:DI 0 "r")
21156 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21157 (clobber (reg:CC FLAGS_REG))
21158 (clobber (mem:BLK (scratch)))])]
21159 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21160 [(clobber (match_dup 0))
21161 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21162 (clobber (mem:BLK (scratch)))])])
21165 [(match_scratch:DI 0 "r")
21166 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21167 (clobber (reg:CC FLAGS_REG))
21168 (clobber (mem:BLK (scratch)))])]
21169 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21170 [(clobber (match_dup 0))
21171 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21172 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21173 (clobber (mem:BLK (scratch)))])])
21175 ;; Convert esp subtractions to push.
21177 [(match_scratch:DI 0 "r")
21178 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21179 (clobber (reg:CC FLAGS_REG))])]
21180 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21181 [(clobber (match_dup 0))
21182 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21185 [(match_scratch:DI 0 "r")
21186 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21187 (clobber (reg:CC FLAGS_REG))])]
21188 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21189 [(clobber (match_dup 0))
21190 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21191 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21193 ;; Convert epilogue deallocator to pop.
21195 [(match_scratch:DI 0 "r")
21196 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21197 (clobber (reg:CC FLAGS_REG))
21198 (clobber (mem:BLK (scratch)))])]
21199 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21200 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21201 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21202 (clobber (mem:BLK (scratch)))])]
21205 ;; Two pops case is tricky, since pop causes dependency on destination register.
21206 ;; We use two registers if available.
21208 [(match_scratch:DI 0 "r")
21209 (match_scratch:DI 1 "r")
21210 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21211 (clobber (reg:CC FLAGS_REG))
21212 (clobber (mem:BLK (scratch)))])]
21213 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21214 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21215 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21216 (clobber (mem:BLK (scratch)))])
21217 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21218 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21222 [(match_scratch:DI 0 "r")
21223 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21224 (clobber (reg:CC FLAGS_REG))
21225 (clobber (mem:BLK (scratch)))])]
21226 "optimize_insn_for_size_p ()"
21227 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21228 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21229 (clobber (mem:BLK (scratch)))])
21230 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21231 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21234 ;; Convert esp additions to pop.
21236 [(match_scratch:DI 0 "r")
21237 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21238 (clobber (reg:CC FLAGS_REG))])]
21240 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21241 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21244 ;; Two pops case is tricky, since pop causes dependency on destination register.
21245 ;; We use two registers if available.
21247 [(match_scratch:DI 0 "r")
21248 (match_scratch:DI 1 "r")
21249 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21250 (clobber (reg:CC FLAGS_REG))])]
21252 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21253 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21254 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21255 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21259 [(match_scratch:DI 0 "r")
21260 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21261 (clobber (reg:CC FLAGS_REG))])]
21262 "optimize_insn_for_size_p ()"
21263 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21264 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21265 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21266 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21269 ;; Convert imul by three, five and nine into lea
21272 [(set (match_operand:SI 0 "register_operand" "")
21273 (mult:SI (match_operand:SI 1 "register_operand" "")
21274 (match_operand:SI 2 "const_int_operand" "")))
21275 (clobber (reg:CC FLAGS_REG))])]
21276 "INTVAL (operands[2]) == 3
21277 || INTVAL (operands[2]) == 5
21278 || INTVAL (operands[2]) == 9"
21279 [(set (match_dup 0)
21280 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21282 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21286 [(set (match_operand:SI 0 "register_operand" "")
21287 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21288 (match_operand:SI 2 "const_int_operand" "")))
21289 (clobber (reg:CC FLAGS_REG))])]
21290 "optimize_insn_for_speed_p ()
21291 && (INTVAL (operands[2]) == 3
21292 || INTVAL (operands[2]) == 5
21293 || INTVAL (operands[2]) == 9)"
21294 [(set (match_dup 0) (match_dup 1))
21296 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21298 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21302 [(set (match_operand:DI 0 "register_operand" "")
21303 (mult:DI (match_operand:DI 1 "register_operand" "")
21304 (match_operand:DI 2 "const_int_operand" "")))
21305 (clobber (reg:CC FLAGS_REG))])]
21307 && (INTVAL (operands[2]) == 3
21308 || INTVAL (operands[2]) == 5
21309 || INTVAL (operands[2]) == 9)"
21310 [(set (match_dup 0)
21311 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21313 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21317 [(set (match_operand:DI 0 "register_operand" "")
21318 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21319 (match_operand:DI 2 "const_int_operand" "")))
21320 (clobber (reg:CC FLAGS_REG))])]
21322 && optimize_insn_for_speed_p ()
21323 && (INTVAL (operands[2]) == 3
21324 || INTVAL (operands[2]) == 5
21325 || INTVAL (operands[2]) == 9)"
21326 [(set (match_dup 0) (match_dup 1))
21328 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21330 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21332 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21333 ;; imul $32bit_imm, reg, reg is direct decoded.
21335 [(match_scratch:DI 3 "r")
21336 (parallel [(set (match_operand:DI 0 "register_operand" "")
21337 (mult:DI (match_operand:DI 1 "memory_operand" "")
21338 (match_operand:DI 2 "immediate_operand" "")))
21339 (clobber (reg:CC FLAGS_REG))])]
21340 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21341 && !satisfies_constraint_K (operands[2])"
21342 [(set (match_dup 3) (match_dup 1))
21343 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21344 (clobber (reg:CC FLAGS_REG))])]
21348 [(match_scratch:SI 3 "r")
21349 (parallel [(set (match_operand:SI 0 "register_operand" "")
21350 (mult:SI (match_operand:SI 1 "memory_operand" "")
21351 (match_operand:SI 2 "immediate_operand" "")))
21352 (clobber (reg:CC FLAGS_REG))])]
21353 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21354 && !satisfies_constraint_K (operands[2])"
21355 [(set (match_dup 3) (match_dup 1))
21356 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21357 (clobber (reg:CC FLAGS_REG))])]
21361 [(match_scratch:SI 3 "r")
21362 (parallel [(set (match_operand:DI 0 "register_operand" "")
21364 (mult:SI (match_operand:SI 1 "memory_operand" "")
21365 (match_operand:SI 2 "immediate_operand" ""))))
21366 (clobber (reg:CC FLAGS_REG))])]
21367 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21368 && !satisfies_constraint_K (operands[2])"
21369 [(set (match_dup 3) (match_dup 1))
21370 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21371 (clobber (reg:CC FLAGS_REG))])]
21374 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21375 ;; Convert it into imul reg, reg
21376 ;; It would be better to force assembler to encode instruction using long
21377 ;; immediate, but there is apparently no way to do so.
21379 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21380 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21381 (match_operand:DI 2 "const_int_operand" "")))
21382 (clobber (reg:CC FLAGS_REG))])
21383 (match_scratch:DI 3 "r")]
21384 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21385 && satisfies_constraint_K (operands[2])"
21386 [(set (match_dup 3) (match_dup 2))
21387 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21388 (clobber (reg:CC FLAGS_REG))])]
21390 if (!rtx_equal_p (operands[0], operands[1]))
21391 emit_move_insn (operands[0], operands[1]);
21395 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21396 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21397 (match_operand:SI 2 "const_int_operand" "")))
21398 (clobber (reg:CC FLAGS_REG))])
21399 (match_scratch:SI 3 "r")]
21400 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21401 && satisfies_constraint_K (operands[2])"
21402 [(set (match_dup 3) (match_dup 2))
21403 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21404 (clobber (reg:CC FLAGS_REG))])]
21406 if (!rtx_equal_p (operands[0], operands[1]))
21407 emit_move_insn (operands[0], operands[1]);
21411 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21412 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21413 (match_operand:HI 2 "immediate_operand" "")))
21414 (clobber (reg:CC FLAGS_REG))])
21415 (match_scratch:HI 3 "r")]
21416 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21417 [(set (match_dup 3) (match_dup 2))
21418 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21419 (clobber (reg:CC FLAGS_REG))])]
21421 if (!rtx_equal_p (operands[0], operands[1]))
21422 emit_move_insn (operands[0], operands[1]);
21425 ;; After splitting up read-modify operations, array accesses with memory
21426 ;; operands might end up in form:
21428 ;; movl 4(%esp), %edx
21430 ;; instead of pre-splitting:
21432 ;; addl 4(%esp), %eax
21434 ;; movl 4(%esp), %edx
21435 ;; leal (%edx,%eax,4), %eax
21438 [(parallel [(set (match_operand 0 "register_operand" "")
21439 (ashift (match_operand 1 "register_operand" "")
21440 (match_operand 2 "const_int_operand" "")))
21441 (clobber (reg:CC FLAGS_REG))])
21442 (set (match_operand 3 "register_operand")
21443 (match_operand 4 "x86_64_general_operand" ""))
21444 (parallel [(set (match_operand 5 "register_operand" "")
21445 (plus (match_operand 6 "register_operand" "")
21446 (match_operand 7 "register_operand" "")))
21447 (clobber (reg:CC FLAGS_REG))])]
21448 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21449 /* Validate MODE for lea. */
21450 && ((!TARGET_PARTIAL_REG_STALL
21451 && (GET_MODE (operands[0]) == QImode
21452 || GET_MODE (operands[0]) == HImode))
21453 || GET_MODE (operands[0]) == SImode
21454 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21455 /* We reorder load and the shift. */
21456 && !rtx_equal_p (operands[1], operands[3])
21457 && !reg_overlap_mentioned_p (operands[0], operands[4])
21458 /* Last PLUS must consist of operand 0 and 3. */
21459 && !rtx_equal_p (operands[0], operands[3])
21460 && (rtx_equal_p (operands[3], operands[6])
21461 || rtx_equal_p (operands[3], operands[7]))
21462 && (rtx_equal_p (operands[0], operands[6])
21463 || rtx_equal_p (operands[0], operands[7]))
21464 /* The intermediate operand 0 must die or be same as output. */
21465 && (rtx_equal_p (operands[0], operands[5])
21466 || peep2_reg_dead_p (3, operands[0]))"
21467 [(set (match_dup 3) (match_dup 4))
21468 (set (match_dup 0) (match_dup 1))]
21470 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21471 int scale = 1 << INTVAL (operands[2]);
21472 rtx index = gen_lowpart (Pmode, operands[1]);
21473 rtx base = gen_lowpart (Pmode, operands[3]);
21474 rtx dest = gen_lowpart (mode, operands[5]);
21476 operands[1] = gen_rtx_PLUS (Pmode, base,
21477 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21479 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21480 operands[0] = dest;
21483 ;; Call-value patterns last so that the wildcard operand does not
21484 ;; disrupt insn-recog's switch tables.
21486 (define_insn "*call_value_pop_0"
21487 [(set (match_operand 0 "" "")
21488 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21489 (match_operand:SI 2 "" "")))
21490 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21491 (match_operand:SI 3 "immediate_operand" "")))]
21494 if (SIBLING_CALL_P (insn))
21497 return "call\t%P1";
21499 [(set_attr "type" "callv")])
21501 (define_insn "*call_value_pop_1"
21502 [(set (match_operand 0 "" "")
21503 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
21504 (match_operand:SI 2 "" "")))
21505 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21506 (match_operand:SI 3 "immediate_operand" "i")))]
21507 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
21509 if (constant_call_address_operand (operands[1], Pmode))
21510 return "call\t%P1";
21511 return "call\t%A1";
21513 [(set_attr "type" "callv")])
21515 (define_insn "*sibcall_value_pop_1"
21516 [(set (match_operand 0 "" "")
21517 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21518 (match_operand:SI 2 "" "")))
21519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21520 (match_operand:SI 3 "immediate_operand" "i,i")))]
21521 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21525 [(set_attr "type" "callv")])
21527 (define_insn "*call_value_0"
21528 [(set (match_operand 0 "" "")
21529 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21530 (match_operand:SI 2 "" "")))]
21533 if (SIBLING_CALL_P (insn))
21536 return "call\t%P1";
21538 [(set_attr "type" "callv")])
21540 (define_insn "*call_value_0_rex64"
21541 [(set (match_operand 0 "" "")
21542 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21543 (match_operand:DI 2 "const_int_operand" "")))]
21546 if (SIBLING_CALL_P (insn))
21549 return "call\t%P1";
21551 [(set_attr "type" "callv")])
21553 (define_insn "*call_value_0_rex64_ms_sysv"
21554 [(set (match_operand 0 "" "")
21555 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21556 (match_operand:DI 2 "const_int_operand" "")))
21557 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21558 (clobber (reg:TI XMM6_REG))
21559 (clobber (reg:TI XMM7_REG))
21560 (clobber (reg:TI XMM8_REG))
21561 (clobber (reg:TI XMM9_REG))
21562 (clobber (reg:TI XMM10_REG))
21563 (clobber (reg:TI XMM11_REG))
21564 (clobber (reg:TI XMM12_REG))
21565 (clobber (reg:TI XMM13_REG))
21566 (clobber (reg:TI XMM14_REG))
21567 (clobber (reg:TI XMM15_REG))
21568 (clobber (reg:DI SI_REG))
21569 (clobber (reg:DI DI_REG))]
21570 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21572 if (SIBLING_CALL_P (insn))
21575 return "call\t%P1";
21577 [(set_attr "type" "callv")])
21579 (define_insn "*call_value_1"
21580 [(set (match_operand 0 "" "")
21581 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
21582 (match_operand:SI 2 "" "")))]
21583 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
21585 if (constant_call_address_operand (operands[1], Pmode))
21586 return "call\t%P1";
21587 return "call\t%A1";
21589 [(set_attr "type" "callv")])
21591 (define_insn "*sibcall_value_1"
21592 [(set (match_operand 0 "" "")
21593 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21594 (match_operand:SI 2 "" "")))]
21595 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21599 [(set_attr "type" "callv")])
21601 (define_insn "*call_value_1_rex64"
21602 [(set (match_operand 0 "" "")
21603 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21604 (match_operand:DI 2 "" "")))]
21605 "TARGET_64BIT && !SIBLING_CALL_P (insn)
21606 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21608 if (constant_call_address_operand (operands[1], Pmode))
21609 return "call\t%P1";
21610 return "call\t%A1";
21612 [(set_attr "type" "callv")])
21614 (define_insn "*call_value_1_rex64_ms_sysv"
21615 [(set (match_operand 0 "" "")
21616 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21617 (match_operand:DI 2 "" "")))
21618 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21619 (clobber (reg:TI 27))
21620 (clobber (reg:TI 28))
21621 (clobber (reg:TI 45))
21622 (clobber (reg:TI 46))
21623 (clobber (reg:TI 47))
21624 (clobber (reg:TI 48))
21625 (clobber (reg:TI 49))
21626 (clobber (reg:TI 50))
21627 (clobber (reg:TI 51))
21628 (clobber (reg:TI 52))
21629 (clobber (reg:DI SI_REG))
21630 (clobber (reg:DI DI_REG))]
21631 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21633 if (constant_call_address_operand (operands[1], Pmode))
21634 return "call\t%P1";
21635 return "call\t%A1";
21637 [(set_attr "type" "callv")])
21639 (define_insn "*call_value_1_rex64_large"
21640 [(set (match_operand 0 "" "")
21641 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21642 (match_operand:DI 2 "" "")))]
21643 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21645 [(set_attr "type" "callv")])
21647 (define_insn "*sibcall_value_1_rex64"
21648 [(set (match_operand 0 "" "")
21649 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21650 (match_operand:DI 2 "" "")))]
21651 "TARGET_64BIT && SIBLING_CALL_P (insn)"
21655 [(set_attr "type" "callv")])
21657 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21658 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21659 ;; caught for use by garbage collectors and the like. Using an insn that
21660 ;; maps to SIGILL makes it more likely the program will rightfully die.
21661 ;; Keeping with tradition, "6" is in honor of #UD.
21662 (define_insn "trap"
21663 [(trap_if (const_int 1) (const_int 6))]
21665 { return ASM_SHORT "0x0b0f"; }
21666 [(set_attr "length" "2")])
21668 (define_expand "sse_prologue_save"
21669 [(parallel [(set (match_operand:BLK 0 "" "")
21670 (unspec:BLK [(reg:DI 21)
21677 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21678 (use (match_operand:DI 1 "register_operand" ""))
21679 (use (match_operand:DI 2 "immediate_operand" ""))
21680 (use (label_ref:DI (match_operand 3 "" "")))])]
21684 (define_insn "*sse_prologue_save_insn"
21685 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21686 (match_operand:DI 4 "const_int_operand" "n")))
21687 (unspec:BLK [(reg:DI 21)
21694 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21695 (use (match_operand:DI 1 "register_operand" "r"))
21696 (use (match_operand:DI 2 "const_int_operand" "i"))
21697 (use (label_ref:DI (match_operand 3 "" "X")))]
21699 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21700 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21703 operands[0] = gen_rtx_MEM (Pmode,
21704 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21705 /* VEX instruction with a REX prefix will #UD. */
21706 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21707 gcc_unreachable ();
21709 output_asm_insn ("jmp\t%A1", operands);
21710 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21712 operands[4] = adjust_address (operands[0], DImode, i*16);
21713 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21714 PUT_MODE (operands[4], TImode);
21715 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21716 output_asm_insn ("rex", operands);
21717 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21719 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21720 CODE_LABEL_NUMBER (operands[3]));
21723 [(set_attr "type" "other")
21724 (set_attr "length_immediate" "0")
21725 (set_attr "length_address" "0")
21726 (set (attr "length")
21728 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21729 (const_string "34")
21730 (const_string "42")))
21731 (set_attr "memory" "store")
21732 (set_attr "modrm" "0")
21733 (set_attr "prefix" "maybe_vex")
21734 (set_attr "mode" "DI")])
21736 (define_expand "prefetch"
21737 [(prefetch (match_operand 0 "address_operand" "")
21738 (match_operand:SI 1 "const_int_operand" "")
21739 (match_operand:SI 2 "const_int_operand" ""))]
21740 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21742 int rw = INTVAL (operands[1]);
21743 int locality = INTVAL (operands[2]);
21745 gcc_assert (rw == 0 || rw == 1);
21746 gcc_assert (locality >= 0 && locality <= 3);
21747 gcc_assert (GET_MODE (operands[0]) == Pmode
21748 || GET_MODE (operands[0]) == VOIDmode);
21750 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21751 supported by SSE counterpart or the SSE prefetch is not available
21752 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21754 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21755 operands[2] = GEN_INT (3);
21757 operands[1] = const0_rtx;
21760 (define_insn "*prefetch_sse"
21761 [(prefetch (match_operand:SI 0 "address_operand" "p")
21763 (match_operand:SI 1 "const_int_operand" ""))]
21764 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21766 static const char * const patterns[4] = {
21767 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21770 int locality = INTVAL (operands[1]);
21771 gcc_assert (locality >= 0 && locality <= 3);
21773 return patterns[locality];
21775 [(set_attr "type" "sse")
21776 (set_attr "memory" "none")])
21778 (define_insn "*prefetch_sse_rex"
21779 [(prefetch (match_operand:DI 0 "address_operand" "p")
21781 (match_operand:SI 1 "const_int_operand" ""))]
21782 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21784 static const char * const patterns[4] = {
21785 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21788 int locality = INTVAL (operands[1]);
21789 gcc_assert (locality >= 0 && locality <= 3);
21791 return patterns[locality];
21793 [(set_attr "type" "sse")
21794 (set_attr "memory" "none")])
21796 (define_insn "*prefetch_3dnow"
21797 [(prefetch (match_operand:SI 0 "address_operand" "p")
21798 (match_operand:SI 1 "const_int_operand" "n")
21800 "TARGET_3DNOW && !TARGET_64BIT"
21802 if (INTVAL (operands[1]) == 0)
21803 return "prefetch\t%a0";
21805 return "prefetchw\t%a0";
21807 [(set_attr "type" "mmx")
21808 (set_attr "memory" "none")])
21810 (define_insn "*prefetch_3dnow_rex"
21811 [(prefetch (match_operand:DI 0 "address_operand" "p")
21812 (match_operand:SI 1 "const_int_operand" "n")
21814 "TARGET_3DNOW && TARGET_64BIT"
21816 if (INTVAL (operands[1]) == 0)
21817 return "prefetch\t%a0";
21819 return "prefetchw\t%a0";
21821 [(set_attr "type" "mmx")
21822 (set_attr "memory" "none")])
21824 (define_expand "stack_protect_set"
21825 [(match_operand 0 "memory_operand" "")
21826 (match_operand 1 "memory_operand" "")]
21829 #ifdef TARGET_THREAD_SSP_OFFSET
21831 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21832 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21834 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21835 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21838 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21840 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21845 (define_insn "stack_protect_set_si"
21846 [(set (match_operand:SI 0 "memory_operand" "=m")
21847 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21848 (set (match_scratch:SI 2 "=&r") (const_int 0))
21849 (clobber (reg:CC FLAGS_REG))]
21851 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21852 [(set_attr "type" "multi")])
21854 (define_insn "stack_protect_set_di"
21855 [(set (match_operand:DI 0 "memory_operand" "=m")
21856 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21857 (set (match_scratch:DI 2 "=&r") (const_int 0))
21858 (clobber (reg:CC FLAGS_REG))]
21860 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21861 [(set_attr "type" "multi")])
21863 (define_insn "stack_tls_protect_set_si"
21864 [(set (match_operand:SI 0 "memory_operand" "=m")
21865 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21866 (set (match_scratch:SI 2 "=&r") (const_int 0))
21867 (clobber (reg:CC FLAGS_REG))]
21869 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21870 [(set_attr "type" "multi")])
21872 (define_insn "stack_tls_protect_set_di"
21873 [(set (match_operand:DI 0 "memory_operand" "=m")
21874 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21875 (set (match_scratch:DI 2 "=&r") (const_int 0))
21876 (clobber (reg:CC FLAGS_REG))]
21879 /* The kernel uses a different segment register for performance reasons; a
21880 system call would not have to trash the userspace segment register,
21881 which would be expensive */
21882 if (ix86_cmodel != CM_KERNEL)
21883 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21885 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21887 [(set_attr "type" "multi")])
21889 (define_expand "stack_protect_test"
21890 [(match_operand 0 "memory_operand" "")
21891 (match_operand 1 "memory_operand" "")
21892 (match_operand 2 "" "")]
21895 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21896 ix86_compare_op0 = operands[0];
21897 ix86_compare_op1 = operands[1];
21898 ix86_compare_emitted = flags;
21900 #ifdef TARGET_THREAD_SSP_OFFSET
21902 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21903 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21905 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21906 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21909 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21911 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21913 emit_jump_insn (gen_beq (operands[2]));
21917 (define_insn "stack_protect_test_si"
21918 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21919 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21920 (match_operand:SI 2 "memory_operand" "m")]
21922 (clobber (match_scratch:SI 3 "=&r"))]
21924 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21925 [(set_attr "type" "multi")])
21927 (define_insn "stack_protect_test_di"
21928 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21929 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21930 (match_operand:DI 2 "memory_operand" "m")]
21932 (clobber (match_scratch:DI 3 "=&r"))]
21934 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21935 [(set_attr "type" "multi")])
21937 (define_insn "stack_tls_protect_test_si"
21938 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21939 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21940 (match_operand:SI 2 "const_int_operand" "i")]
21941 UNSPEC_SP_TLS_TEST))
21942 (clobber (match_scratch:SI 3 "=r"))]
21944 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21945 [(set_attr "type" "multi")])
21947 (define_insn "stack_tls_protect_test_di"
21948 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21949 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21950 (match_operand:DI 2 "const_int_operand" "i")]
21951 UNSPEC_SP_TLS_TEST))
21952 (clobber (match_scratch:DI 3 "=r"))]
21955 /* The kernel uses a different segment register for performance reasons; a
21956 system call would not have to trash the userspace segment register,
21957 which would be expensive */
21958 if (ix86_cmodel != CM_KERNEL)
21959 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21961 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21963 [(set_attr "type" "multi")])
21965 (define_mode_iterator CRC32MODE [QI HI SI])
21966 (define_mode_attr crc32modesuffix [(QI "{b}") (HI "{w}") (SI "{l}")])
21967 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21969 (define_insn "sse4_2_crc32<mode>"
21970 [(set (match_operand:SI 0 "register_operand" "=r")
21972 [(match_operand:SI 1 "register_operand" "0")
21973 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21976 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21977 [(set_attr "type" "sselog1")
21978 (set_attr "prefix_rep" "1")
21979 (set_attr "prefix_extra" "1")
21980 (set_attr "mode" "SI")])
21982 (define_insn "sse4_2_crc32di"
21983 [(set (match_operand:DI 0 "register_operand" "=r")
21985 [(match_operand:DI 1 "register_operand" "0")
21986 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21988 "TARGET_SSE4_2 && TARGET_64BIT"
21989 "crc32{q}\t{%2, %0|%0, %2}"
21990 [(set_attr "type" "sselog1")
21991 (set_attr "prefix_rep" "1")
21992 (set_attr "prefix_extra" "1")
21993 (set_attr "mode" "DI")])
21997 (include "sync.md")