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 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
94 ;; Other random patterns
103 UNSPEC_LD_MPIC ; load_macho_picbase
106 ;; For SSE/MMX support:
124 UNSPEC_MS_TO_SYSV_CALL
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
183 ;; For SSE4.1 support
193 ;; For SSE4.2 support
199 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_XOP_UNSIGNED_CMP
213 UNSPEC_AESKEYGENASSIST
215 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
234 UNSPECV_PROBE_STACK_RANGE
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
264 ;; Constants to represent pcomtrue/pcomfalse variants
274 ;; Constants used in the XOP pperm instruction
276 [(PPERM_SRC 0x00) /* copy source */
277 (PPERM_INVERT 0x20) /* invert source */
278 (PPERM_REVERSE 0x40) /* bit reverse source */
279 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
280 (PPERM_ZERO 0x80) /* all 0's */
281 (PPERM_ONES 0xa0) /* all 1's */
282 (PPERM_SIGN 0xc0) /* propagate sign bit */
283 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
284 (PPERM_SRC1 0x00) /* use first source byte */
285 (PPERM_SRC2 0x10) /* use second source byte */
288 ;; Registers by name.
341 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
344 ;; In C guard expressions, put expressions which may be compile-time
345 ;; constants first. This allows for better optimization. For
346 ;; example, write "TARGET_64BIT && reload_completed", not
347 ;; "reload_completed && TARGET_64BIT".
351 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
352 generic64,amdfam10,bdver1"
353 (const (symbol_ref "ix86_schedule")))
355 ;; A basic instruction type. Refinements due to arguments to be
356 ;; provided in other attributes.
359 alu,alu1,negnot,imov,imovx,lea,
360 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
361 icmp,test,ibr,setcc,icmov,
362 push,pop,call,callv,leave,
364 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
365 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
366 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
367 ssemuladd,sse4arg,lwp,
368 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
369 (const_string "other"))
371 ;; Main data type used by the insn
373 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
374 (const_string "unknown"))
376 ;; The CPU unit operations uses.
377 (define_attr "unit" "integer,i387,sse,mmx,unknown"
378 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
379 (const_string "i387")
380 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
381 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
382 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
384 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
386 (eq_attr "type" "other")
387 (const_string "unknown")]
388 (const_string "integer")))
390 ;; The (bounding maximum) length of an instruction immediate.
391 (define_attr "length_immediate" ""
392 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
395 (eq_attr "unit" "i387,sse,mmx")
397 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
399 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
400 (eq_attr "type" "imov,test")
401 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
402 (eq_attr "type" "call")
403 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (eq_attr "type" "callv")
407 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 ;; We don't know the size before shorten_branches. Expect
411 ;; the instruction to fit for better scheduling.
412 (eq_attr "type" "ibr")
415 (symbol_ref "/* Update immediate_length and other attributes! */
416 gcc_unreachable (),1")))
418 ;; The (bounding maximum) length of an instruction address.
419 (define_attr "length_address" ""
420 (cond [(eq_attr "type" "str,other,multi,fxch")
422 (and (eq_attr "type" "call")
423 (match_operand 0 "constant_call_address_operand" ""))
425 (and (eq_attr "type" "callv")
426 (match_operand 1 "constant_call_address_operand" ""))
429 (symbol_ref "ix86_attr_length_address_default (insn)")))
431 ;; Set when length prefix is used.
432 (define_attr "prefix_data16" ""
433 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
435 (eq_attr "mode" "HI")
437 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442 ;; Set when string REP prefix is used.
443 (define_attr "prefix_rep" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
446 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451 ;; Set when 0f opcode prefix is used.
452 (define_attr "prefix_0f" ""
454 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
455 (eq_attr "unit" "sse,mmx"))
459 ;; Set when REX opcode prefix is used.
460 (define_attr "prefix_rex" ""
461 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
463 (and (eq_attr "mode" "DI")
464 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
465 (eq_attr "unit" "!mmx")))
467 (and (eq_attr "mode" "QI")
468 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
471 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
474 (and (eq_attr "type" "imovx")
475 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 ;; There are also additional prefixes in 3DNOW, SSSE3.
481 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
482 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
483 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
484 (define_attr "prefix_extra" ""
485 (cond [(eq_attr "type" "ssemuladd,sse4arg")
487 (eq_attr "type" "sseiadd1,ssecvt1")
492 ;; Prefix used: original, VEX or maybe VEX.
493 (define_attr "prefix" "orig,vex,maybe_vex"
494 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
496 (const_string "orig")))
498 ;; VEX W bit is used.
499 (define_attr "prefix_vex_w" "" (const_int 0))
501 ;; The length of VEX prefix
502 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
503 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
504 ;; still prefix_0f 1, with prefix_extra 1.
505 (define_attr "length_vex" ""
506 (if_then_else (and (eq_attr "prefix_0f" "1")
507 (eq_attr "prefix_extra" "0"))
508 (if_then_else (eq_attr "prefix_vex_w" "1")
509 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
510 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
511 (if_then_else (eq_attr "prefix_vex_w" "1")
512 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
515 ;; Set when modrm byte is used.
516 (define_attr "modrm" ""
517 (cond [(eq_attr "type" "str,leave")
519 (eq_attr "unit" "i387")
521 (and (eq_attr "type" "incdec")
522 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
523 (ior (match_operand:SI 1 "register_operand" "")
524 (match_operand:HI 1 "register_operand" ""))))
526 (and (eq_attr "type" "push")
527 (not (match_operand 1 "memory_operand" "")))
529 (and (eq_attr "type" "pop")
530 (not (match_operand 0 "memory_operand" "")))
532 (and (eq_attr "type" "imov")
533 (and (not (eq_attr "mode" "DI"))
534 (ior (and (match_operand 0 "register_operand" "")
535 (match_operand 1 "immediate_operand" ""))
536 (ior (and (match_operand 0 "ax_reg_operand" "")
537 (match_operand 1 "memory_displacement_only_operand" ""))
538 (and (match_operand 0 "memory_displacement_only_operand" "")
539 (match_operand 1 "ax_reg_operand" ""))))))
541 (and (eq_attr "type" "call")
542 (match_operand 0 "constant_call_address_operand" ""))
544 (and (eq_attr "type" "callv")
545 (match_operand 1 "constant_call_address_operand" ""))
547 (and (eq_attr "type" "alu,alu1,icmp,test")
548 (match_operand 0 "ax_reg_operand" ""))
549 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
553 ;; The (bounding maximum) length of an instruction in bytes.
554 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
555 ;; Later we may want to split them and compute proper length as for
557 (define_attr "length" ""
558 (cond [(eq_attr "type" "other,multi,fistp,frndint")
560 (eq_attr "type" "fcmp")
562 (eq_attr "unit" "i387")
564 (plus (attr "prefix_data16")
565 (attr "length_address")))
566 (ior (eq_attr "prefix" "vex")
567 (and (eq_attr "prefix" "maybe_vex")
568 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
569 (plus (attr "length_vex")
570 (plus (attr "length_immediate")
572 (attr "length_address"))))]
573 (plus (plus (attr "modrm")
574 (plus (attr "prefix_0f")
575 (plus (attr "prefix_rex")
576 (plus (attr "prefix_extra")
578 (plus (attr "prefix_rep")
579 (plus (attr "prefix_data16")
580 (plus (attr "length_immediate")
581 (attr "length_address")))))))
583 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
584 ;; `store' if there is a simple memory reference therein, or `unknown'
585 ;; if the instruction is complex.
587 (define_attr "memory" "none,load,store,both,unknown"
588 (cond [(eq_attr "type" "other,multi,str,lwp")
589 (const_string "unknown")
590 (eq_attr "type" "lea,fcmov,fpspc")
591 (const_string "none")
592 (eq_attr "type" "fistp,leave")
593 (const_string "both")
594 (eq_attr "type" "frndint")
595 (const_string "load")
596 (eq_attr "type" "push")
597 (if_then_else (match_operand 1 "memory_operand" "")
598 (const_string "both")
599 (const_string "store"))
600 (eq_attr "type" "pop")
601 (if_then_else (match_operand 0 "memory_operand" "")
602 (const_string "both")
603 (const_string "load"))
604 (eq_attr "type" "setcc")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "store")
607 (const_string "none"))
608 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
609 (if_then_else (ior (match_operand 0 "memory_operand" "")
610 (match_operand 1 "memory_operand" ""))
611 (const_string "load")
612 (const_string "none"))
613 (eq_attr "type" "ibr")
614 (if_then_else (match_operand 0 "memory_operand" "")
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "call")
618 (if_then_else (match_operand 0 "constant_call_address_operand" "")
619 (const_string "none")
620 (const_string "load"))
621 (eq_attr "type" "callv")
622 (if_then_else (match_operand 1 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
626 (match_operand 1 "memory_operand" ""))
627 (const_string "both")
628 (and (match_operand 0 "memory_operand" "")
629 (match_operand 1 "memory_operand" ""))
630 (const_string "both")
631 (match_operand 0 "memory_operand" "")
632 (const_string "store")
633 (match_operand 1 "memory_operand" "")
634 (const_string "load")
636 "!alu1,negnot,ishift1,
637 imov,imovx,icmp,test,bitmanip,
639 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
640 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
641 (match_operand 2 "memory_operand" ""))
642 (const_string "load")
643 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
644 (match_operand 3 "memory_operand" ""))
645 (const_string "load")
647 (const_string "none")))
649 ;; Indicates if an instruction has both an immediate and a displacement.
651 (define_attr "imm_disp" "false,true,unknown"
652 (cond [(eq_attr "type" "other,multi")
653 (const_string "unknown")
654 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
655 (and (match_operand 0 "memory_displacement_operand" "")
656 (match_operand 1 "immediate_operand" "")))
657 (const_string "true")
658 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 2 "immediate_operand" "")))
661 (const_string "true")
663 (const_string "false")))
665 ;; Indicates if an FP operation has an integer source.
667 (define_attr "fp_int_src" "false,true"
668 (const_string "false"))
670 ;; Defines rounding mode of an FP operation.
672 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
673 (const_string "any"))
675 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
676 (define_attr "use_carry" "0,1" (const_string "0"))
678 ;; Define attribute to indicate unaligned ssemov insns
679 (define_attr "movu" "0,1" (const_string "0"))
681 ;; Describe a user's asm statement.
682 (define_asm_attributes
683 [(set_attr "length" "128")
684 (set_attr "type" "multi")])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; 64bit single word integer modes.
767 (define_mode_iterator SWI1248x [QI HI SI DI])
769 ;; 64bit single word integer modes without QImode and HImode.
770 (define_mode_iterator SWI48x [SI DI])
772 ;; Single word integer modes.
773 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without SImode and DImode.
776 (define_mode_iterator SWI12 [QI HI])
778 ;; Single word integer modes without DImode.
779 (define_mode_iterator SWI124 [QI HI SI])
781 ;; Single word integer modes without QImode and DImode.
782 (define_mode_iterator SWI24 [HI SI])
784 ;; Single word integer modes without QImode.
785 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787 ;; Single word integer modes without QImode and HImode.
788 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790 ;; All math-dependant single and double word integer modes.
791 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
792 (HI "TARGET_HIMODE_MATH")
793 SI DI (TI "TARGET_64BIT")])
795 ;; Math-dependant single word integer modes.
796 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
797 (HI "TARGET_HIMODE_MATH")
798 SI (DI "TARGET_64BIT")])
800 ;; Math-dependant single word integer modes without DImode.
801 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
802 (HI "TARGET_HIMODE_MATH")
805 ;; Math-dependant single word integer modes without QImode.
806 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
807 SI (DI "TARGET_64BIT")])
809 ;; Double word integer modes.
810 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
811 (TI "TARGET_64BIT")])
813 ;; Double word integer modes as mode attribute.
814 (define_mode_attr DWI [(SI "DI") (DI "TI")])
815 (define_mode_attr dwi [(SI "di") (DI "ti")])
817 ;; Half mode for double word integer modes.
818 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
819 (DI "TARGET_64BIT")])
821 ;; Instruction suffix for integer modes.
822 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824 ;; Register class for integer modes.
825 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
827 ;; Immediate operand constraint for integer modes.
828 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
830 ;; General operand constraint for word modes.
831 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
833 ;; Immediate operand constraint for double integer modes.
834 (define_mode_attr di [(SI "iF") (DI "e")])
836 ;; Immediate operand constraint for shifts.
837 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
839 ;; General operand predicate for integer modes.
840 (define_mode_attr general_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "general_operand")
844 (DI "x86_64_general_operand")
845 (TI "x86_64_general_operand")])
847 ;; General sign/zero extend operand predicate for integer modes.
848 (define_mode_attr general_szext_operand
849 [(QI "general_operand")
850 (HI "general_operand")
851 (SI "general_operand")
852 (DI "x86_64_szext_general_operand")])
854 ;; Immediate operand predicate for integer modes.
855 (define_mode_attr immediate_operand
856 [(QI "immediate_operand")
857 (HI "immediate_operand")
858 (SI "immediate_operand")
859 (DI "x86_64_immediate_operand")])
861 ;; Nonmemory operand predicate for integer modes.
862 (define_mode_attr nonmemory_operand
863 [(QI "nonmemory_operand")
864 (HI "nonmemory_operand")
865 (SI "nonmemory_operand")
866 (DI "x86_64_nonmemory_operand")])
868 ;; Operand predicate for shifts.
869 (define_mode_attr shift_operand
870 [(QI "nonimmediate_operand")
871 (HI "nonimmediate_operand")
872 (SI "nonimmediate_operand")
873 (DI "shiftdi_operand")
874 (TI "register_operand")])
876 ;; Operand predicate for shift argument.
877 (define_mode_attr shift_immediate_operand
878 [(QI "const_1_to_31_operand")
879 (HI "const_1_to_31_operand")
880 (SI "const_1_to_31_operand")
881 (DI "const_1_to_63_operand")])
883 ;; Input operand predicate for arithmetic left shifts.
884 (define_mode_attr ashl_input_operand
885 [(QI "nonimmediate_operand")
886 (HI "nonimmediate_operand")
887 (SI "nonimmediate_operand")
888 (DI "ashldi_input_operand")
889 (TI "reg_or_pm1_operand")])
891 ;; SSE and x87 SFmode and DFmode floating point modes
892 (define_mode_iterator MODEF [SF DF])
894 ;; All x87 floating point modes
895 (define_mode_iterator X87MODEF [SF DF XF])
897 ;; All integer modes handled by x87 fisttp operator.
898 (define_mode_iterator X87MODEI [HI SI DI])
900 ;; All integer modes handled by integer x87 operators.
901 (define_mode_iterator X87MODEI12 [HI SI])
903 ;; All integer modes handled by SSE cvtts?2si* operators.
904 (define_mode_iterator SSEMODEI24 [SI DI])
906 ;; SSE asm suffix for floating point modes
907 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
909 ;; SSE vector mode corresponding to a scalar mode
910 (define_mode_attr ssevecmode
911 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
913 ;; Instruction suffix for REX 64bit operators.
914 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
916 ;; This mode iterator allows :P to be used for patterns that operate on
917 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
918 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
920 ;; Scheduling descriptions
922 (include "pentium.md")
925 (include "athlon.md")
930 ;; Operand and operator predicates and constraints
932 (include "predicates.md")
933 (include "constraints.md")
936 ;; Compare and branch/compare and store instructions.
938 (define_expand "cbranch<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
941 (match_operand:SDWIM 2 "<general_operand>" "")))
942 (set (pc) (if_then_else
943 (match_operator 0 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)])
945 (label_ref (match_operand 3 "" ""))
949 if (MEM_P (operands[1]) && MEM_P (operands[2]))
950 operands[1] = force_reg (<MODE>mode, operands[1]);
951 ix86_expand_branch (GET_CODE (operands[0]),
952 operands[1], operands[2], operands[3]);
956 (define_expand "cstore<mode>4"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
959 (match_operand:SWIM 3 "<general_operand>" "")))
960 (set (match_operand:QI 0 "register_operand" "")
961 (match_operator 1 "ordered_comparison_operator"
962 [(reg:CC FLAGS_REG) (const_int 0)]))]
965 if (MEM_P (operands[2]) && MEM_P (operands[3]))
966 operands[2] = force_reg (<MODE>mode, operands[2]);
967 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
968 operands[2], operands[3]);
972 (define_expand "cmp<mode>_1"
973 [(set (reg:CC FLAGS_REG)
974 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
975 (match_operand:SWI48 1 "<general_operand>" "")))]
979 (define_insn "*cmp<mode>_ccno_1"
980 [(set (reg FLAGS_REG)
981 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
982 (match_operand:SWI 1 "const0_operand" "")))]
983 "ix86_match_ccmode (insn, CCNOmode)"
985 test{<imodesuffix>}\t%0, %0
986 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "test,icmp")
988 (set_attr "length_immediate" "0,1")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmp<mode>_1"
992 [(set (reg FLAGS_REG)
993 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
995 "ix86_match_ccmode (insn, CCmode)"
996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "<MODE>")])
1000 (define_insn "*cmp<mode>_minus_1"
1001 [(set (reg FLAGS_REG)
1003 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1004 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1006 "ix86_match_ccmode (insn, CCGOCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1011 (define_insn "*cmpqi_ext_1"
1012 [(set (reg FLAGS_REG)
1014 (match_operand:QI 0 "general_operand" "Qm")
1017 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)) 0)))]
1020 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1021 "cmp{b}\t{%h1, %0|%0, %h1}"
1022 [(set_attr "type" "icmp")
1023 (set_attr "mode" "QI")])
1025 (define_insn "*cmpqi_ext_1_rex64"
1026 [(set (reg FLAGS_REG)
1028 (match_operand:QI 0 "register_operand" "Q")
1031 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)) 0)))]
1034 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035 "cmp{b}\t{%h1, %0|%0, %h1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "QI")])
1039 (define_insn "*cmpqi_ext_2"
1040 [(set (reg FLAGS_REG)
1044 (match_operand 0 "ext_register_operand" "Q")
1047 (match_operand:QI 1 "const0_operand" "")))]
1048 "ix86_match_ccmode (insn, CCNOmode)"
1050 [(set_attr "type" "test")
1051 (set_attr "length_immediate" "0")
1052 (set_attr "mode" "QI")])
1054 (define_expand "cmpqi_ext_3"
1055 [(set (reg:CC FLAGS_REG)
1059 (match_operand 0 "ext_register_operand" "")
1062 (match_operand:QI 1 "immediate_operand" "")))]
1066 (define_insn "*cmpqi_ext_3_insn"
1067 [(set (reg FLAGS_REG)
1071 (match_operand 0 "ext_register_operand" "Q")
1074 (match_operand:QI 1 "general_operand" "Qmn")))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_3_insn_rex64"
1082 [(set (reg FLAGS_REG)
1086 (match_operand 0 "ext_register_operand" "Q")
1089 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%1, %h0|%h0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "modrm" "1")
1094 (set_attr "mode" "QI")])
1096 (define_insn "*cmpqi_ext_4"
1097 [(set (reg FLAGS_REG)
1101 (match_operand 0 "ext_register_operand" "Q")
1106 (match_operand 1 "ext_register_operand" "Q")
1108 (const_int 8)) 0)))]
1109 "ix86_match_ccmode (insn, CCmode)"
1110 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1111 [(set_attr "type" "icmp")
1112 (set_attr "mode" "QI")])
1114 ;; These implement float point compares.
1115 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1116 ;; which would allow mix and match FP modes on the compares. Which is what
1117 ;; the old patterns did, but with many more of them.
1119 (define_expand "cbranchxf4"
1120 [(set (reg:CC FLAGS_REG)
1121 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1122 (match_operand:XF 2 "nonmemory_operand" "")))
1123 (set (pc) (if_then_else
1124 (match_operator 0 "ix86_fp_comparison_operator"
1127 (label_ref (match_operand 3 "" ""))
1131 ix86_expand_branch (GET_CODE (operands[0]),
1132 operands[1], operands[2], operands[3]);
1136 (define_expand "cstorexf4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1139 (match_operand:XF 3 "nonmemory_operand" "")))
1140 (set (match_operand:QI 0 "register_operand" "")
1141 (match_operator 1 "ix86_fp_comparison_operator"
1146 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1147 operands[2], operands[3]);
1151 (define_expand "cbranch<mode>4"
1152 [(set (reg:CC FLAGS_REG)
1153 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1154 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1155 (set (pc) (if_then_else
1156 (match_operator 0 "ix86_fp_comparison_operator"
1159 (label_ref (match_operand 3 "" ""))
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1163 ix86_expand_branch (GET_CODE (operands[0]),
1164 operands[1], operands[2], operands[3]);
1168 (define_expand "cstore<mode>4"
1169 [(set (reg:CC FLAGS_REG)
1170 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1171 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1172 (set (match_operand:QI 0 "register_operand" "")
1173 (match_operator 1 "ix86_fp_comparison_operator"
1176 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1178 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1179 operands[2], operands[3]);
1183 (define_expand "cbranchcc4"
1184 [(set (pc) (if_then_else
1185 (match_operator 0 "comparison_operator"
1186 [(match_operand 1 "flags_reg_operand" "")
1187 (match_operand 2 "const0_operand" "")])
1188 (label_ref (match_operand 3 "" ""))
1192 ix86_expand_branch (GET_CODE (operands[0]),
1193 operands[1], operands[2], operands[3]);
1197 (define_expand "cstorecc4"
1198 [(set (match_operand:QI 0 "register_operand" "")
1199 (match_operator 1 "comparison_operator"
1200 [(match_operand 2 "flags_reg_operand" "")
1201 (match_operand 3 "const0_operand" "")]))]
1204 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205 operands[2], operands[3]);
1210 ;; FP compares, step 1:
1211 ;; Set the FP condition codes.
1213 ;; CCFPmode compare with exceptions
1214 ;; CCFPUmode compare with no exceptions
1216 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1217 ;; used to manage the reg stack popping would not be preserved.
1219 (define_insn "*cmpfp_0"
1220 [(set (match_operand:HI 0 "register_operand" "=a")
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand" ""))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228 "* return output_fp_compare (insn, operands, 0, 0);"
1229 [(set_attr "type" "multi")
1230 (set_attr "unit" "i387")
1232 (cond [(match_operand:SF 1 "" "")
1234 (match_operand:DF 1 "" "")
1237 (const_string "XF")))])
1239 (define_insn_and_split "*cmpfp_0_cc"
1240 [(set (reg:CCFP FLAGS_REG)
1242 (match_operand 1 "register_operand" "f")
1243 (match_operand 2 "const0_operand" "")))
1244 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1246 && TARGET_SAHF && !TARGET_CMOVE
1247 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "&& reload_completed"
1252 [(compare:CCFP (match_dup 1)(match_dup 2))]
1254 (set (reg:CC FLAGS_REG)
1255 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1260 (cond [(match_operand:SF 1 "" "")
1262 (match_operand:DF 1 "" "")
1265 (const_string "XF")))])
1267 (define_insn "*cmpfp_xf"
1268 [(set (match_operand:HI 0 "register_operand" "=a")
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f"))]
1275 "* return output_fp_compare (insn, operands, 0, 0);"
1276 [(set_attr "type" "multi")
1277 (set_attr "unit" "i387")
1278 (set_attr "mode" "XF")])
1280 (define_insn_and_split "*cmpfp_xf_cc"
1281 [(set (reg:CCFP FLAGS_REG)
1283 (match_operand:XF 1 "register_operand" "f")
1284 (match_operand:XF 2 "register_operand" "f")))
1285 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1287 && TARGET_SAHF && !TARGET_CMOVE"
1289 "&& reload_completed"
1292 [(compare:CCFP (match_dup 1)(match_dup 2))]
1294 (set (reg:CC FLAGS_REG)
1295 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1301 (define_insn "*cmpfp_<mode>"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1309 "* return output_fp_compare (insn, operands, 0, 0);"
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1312 (set_attr "mode" "<MODE>")])
1314 (define_insn_and_split "*cmpfp_<mode>_cc"
1315 [(set (reg:CCFP FLAGS_REG)
1317 (match_operand:MODEF 1 "register_operand" "f")
1318 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1319 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1321 && TARGET_SAHF && !TARGET_CMOVE"
1323 "&& reload_completed"
1326 [(compare:CCFP (match_dup 1)(match_dup 2))]
1328 (set (reg:CC FLAGS_REG)
1329 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmpfp_u"
1336 [(set (match_operand:HI 0 "register_operand" "=a")
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f"))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344 "* return output_fp_compare (insn, operands, 0, 1);"
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1348 (cond [(match_operand:SF 1 "" "")
1350 (match_operand:DF 1 "" "")
1353 (const_string "XF")))])
1355 (define_insn_and_split "*cmpfp_u_cc"
1356 [(set (reg:CCFPU FLAGS_REG)
1358 (match_operand 1 "register_operand" "f")
1359 (match_operand 2 "register_operand" "f")))
1360 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1362 && TARGET_SAHF && !TARGET_CMOVE
1363 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "&& reload_completed"
1368 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1370 (set (reg:CC FLAGS_REG)
1371 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1376 (cond [(match_operand:SF 1 "" "")
1378 (match_operand:DF 1 "" "")
1381 (const_string "XF")))])
1383 (define_insn "*cmpfp_<mode>"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1387 (match_operand 1 "register_operand" "f")
1388 (match_operator 3 "float_operator"
1389 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "* return output_fp_compare (insn, operands, 0, 0);"
1395 [(set_attr "type" "multi")
1396 (set_attr "unit" "i387")
1397 (set_attr "fp_int_src" "true")
1398 (set_attr "mode" "<MODE>")])
1400 (define_insn_and_split "*cmpfp_<mode>_cc"
1401 [(set (reg:CCFP FLAGS_REG)
1403 (match_operand 1 "register_operand" "f")
1404 (match_operator 3 "float_operator"
1405 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1406 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1407 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408 && TARGET_SAHF && !TARGET_CMOVE
1409 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1410 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1412 "&& reload_completed"
1417 (match_op_dup 3 [(match_dup 2)]))]
1419 (set (reg:CC FLAGS_REG)
1420 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1422 [(set_attr "type" "multi")
1423 (set_attr "unit" "i387")
1424 (set_attr "fp_int_src" "true")
1425 (set_attr "mode" "<MODE>")])
1427 ;; FP compares, step 2
1428 ;; Move the fpsw to ax.
1430 (define_insn "x86_fnstsw_1"
1431 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1435 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1448 #ifndef HAVE_AS_IX86_SAHF
1450 return ASM_BYTE "0x9e";
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "mode" "SI")])
1460 ;; Pentium Pro can do steps 1 through 3 in one go.
1461 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1462 (define_insn "*cmpfp_i_mixed"
1463 [(set (reg:CCFP FLAGS_REG)
1464 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1465 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1466 "TARGET_MIX_SSE_I387
1467 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1468 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1469 "* return output_fp_compare (insn, operands, 1, 0);"
1470 [(set_attr "type" "fcmp,ssecomi")
1471 (set_attr "prefix" "orig,maybe_vex")
1473 (if_then_else (match_operand:SF 1 "" "")
1475 (const_string "DF")))
1476 (set (attr "prefix_rep")
1477 (if_then_else (eq_attr "type" "ssecomi")
1479 (const_string "*")))
1480 (set (attr "prefix_data16")
1481 (cond [(eq_attr "type" "fcmp")
1483 (eq_attr "mode" "DF")
1486 (const_string "0")))
1487 (set_attr "athlon_decode" "vector")
1488 (set_attr "amdfam10_decode" "direct")])
1490 (define_insn "*cmpfp_i_sse"
1491 [(set (reg:CCFP FLAGS_REG)
1492 (compare:CCFP (match_operand 0 "register_operand" "x")
1493 (match_operand 1 "nonimmediate_operand" "xm")))]
1495 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497 "* return output_fp_compare (insn, operands, 1, 0);"
1498 [(set_attr "type" "ssecomi")
1499 (set_attr "prefix" "maybe_vex")
1501 (if_then_else (match_operand:SF 1 "" "")
1503 (const_string "DF")))
1504 (set_attr "prefix_rep" "0")
1505 (set (attr "prefix_data16")
1506 (if_then_else (eq_attr "mode" "DF")
1508 (const_string "0")))
1509 (set_attr "athlon_decode" "vector")
1510 (set_attr "amdfam10_decode" "direct")])
1512 (define_insn "*cmpfp_i_i387"
1513 [(set (reg:CCFP FLAGS_REG)
1514 (compare:CCFP (match_operand 0 "register_operand" "f")
1515 (match_operand 1 "register_operand" "f")))]
1516 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1518 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1519 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520 "* return output_fp_compare (insn, operands, 1, 0);"
1521 [(set_attr "type" "fcmp")
1523 (cond [(match_operand:SF 1 "" "")
1525 (match_operand:DF 1 "" "")
1528 (const_string "XF")))
1529 (set_attr "athlon_decode" "vector")
1530 (set_attr "amdfam10_decode" "direct")])
1532 (define_insn "*cmpfp_iu_mixed"
1533 [(set (reg:CCFPU FLAGS_REG)
1534 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1535 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1536 "TARGET_MIX_SSE_I387
1537 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1538 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1539 "* return output_fp_compare (insn, operands, 1, 1);"
1540 [(set_attr "type" "fcmp,ssecomi")
1541 (set_attr "prefix" "orig,maybe_vex")
1543 (if_then_else (match_operand:SF 1 "" "")
1545 (const_string "DF")))
1546 (set (attr "prefix_rep")
1547 (if_then_else (eq_attr "type" "ssecomi")
1549 (const_string "*")))
1550 (set (attr "prefix_data16")
1551 (cond [(eq_attr "type" "fcmp")
1553 (eq_attr "mode" "DF")
1556 (const_string "0")))
1557 (set_attr "athlon_decode" "vector")
1558 (set_attr "amdfam10_decode" "direct")])
1560 (define_insn "*cmpfp_iu_sse"
1561 [(set (reg:CCFPU FLAGS_REG)
1562 (compare:CCFPU (match_operand 0 "register_operand" "x")
1563 (match_operand 1 "nonimmediate_operand" "xm")))]
1565 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1566 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1567 "* return output_fp_compare (insn, operands, 1, 1);"
1568 [(set_attr "type" "ssecomi")
1569 (set_attr "prefix" "maybe_vex")
1571 (if_then_else (match_operand:SF 1 "" "")
1573 (const_string "DF")))
1574 (set_attr "prefix_rep" "0")
1575 (set (attr "prefix_data16")
1576 (if_then_else (eq_attr "mode" "DF")
1578 (const_string "0")))
1579 (set_attr "athlon_decode" "vector")
1580 (set_attr "amdfam10_decode" "direct")])
1582 (define_insn "*cmpfp_iu_387"
1583 [(set (reg:CCFPU FLAGS_REG)
1584 (compare:CCFPU (match_operand 0 "register_operand" "f")
1585 (match_operand 1 "register_operand" "f")))]
1586 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1588 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1589 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1590 "* return output_fp_compare (insn, operands, 1, 1);"
1591 [(set_attr "type" "fcmp")
1593 (cond [(match_operand:SF 1 "" "")
1595 (match_operand:DF 1 "" "")
1598 (const_string "XF")))
1599 (set_attr "athlon_decode" "vector")
1600 (set_attr "amdfam10_decode" "direct")])
1602 ;; Push/pop instructions.
1604 (define_insn "*pushdi2_rex64"
1605 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1606 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1611 [(set_attr "type" "push,multi")
1612 (set_attr "mode" "DI")])
1614 ;; Convert impossible pushes of immediate to existing instructions.
1615 ;; First try to get scratch register and go through it. In case this
1616 ;; fails, push sign extended lower part first and then overwrite
1617 ;; upper part by 32bit move.
1619 [(match_scratch:DI 2 "r")
1620 (set (match_operand:DI 0 "push_operand" "")
1621 (match_operand:DI 1 "immediate_operand" ""))]
1622 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1623 && !x86_64_immediate_operand (operands[1], DImode)"
1624 [(set (match_dup 2) (match_dup 1))
1625 (set (match_dup 0) (match_dup 2))])
1627 ;; We need to define this as both peepholer and splitter for case
1628 ;; peephole2 pass is not run.
1629 ;; "&& 1" is needed to keep it from matching the previous pattern.
1631 [(set (match_operand:DI 0 "push_operand" "")
1632 (match_operand:DI 1 "immediate_operand" ""))]
1633 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1634 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1635 [(set (match_dup 0) (match_dup 1))
1636 (set (match_dup 2) (match_dup 3))]
1638 split_di (&operands[1], 1, &operands[2], &operands[3]);
1640 operands[1] = gen_lowpart (DImode, operands[2]);
1641 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1646 [(set (match_operand:DI 0 "push_operand" "")
1647 (match_operand:DI 1 "immediate_operand" ""))]
1648 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1649 ? epilogue_completed : reload_completed)
1650 && !symbolic_operand (operands[1], DImode)
1651 && !x86_64_immediate_operand (operands[1], DImode)"
1652 [(set (match_dup 0) (match_dup 1))
1653 (set (match_dup 2) (match_dup 3))]
1655 split_di (&operands[1], 1, &operands[2], &operands[3]);
1657 operands[1] = gen_lowpart (DImode, operands[2]);
1658 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662 (define_insn "*pushdi2"
1663 [(set (match_operand:DI 0 "push_operand" "=<")
1664 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1669 [(set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "general_operand" ""))]
1671 "!TARGET_64BIT && reload_completed
1672 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1674 "ix86_split_long_move (operands); DONE;")
1676 (define_insn "*pushsi2"
1677 [(set (match_operand:SI 0 "push_operand" "=<")
1678 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word". But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690 [(set (match_operand:SWI124 0 "push_operand" "=X")
1691 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "DI")])
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:SWI12 0 "push_operand" "=X")
1699 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1702 [(set_attr "type" "push")
1703 (set_attr "mode" "SI")])
1705 (define_insn "*push<mode>2_prologue"
1706 [(set (match_operand:P 0 "push_operand" "=<")
1707 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708 (clobber (mem:BLK (scratch)))]
1710 "push{<imodesuffix>}\t%1"
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "<MODE>")])
1714 (define_insn "*pop<mode>1"
1715 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716 (match_operand:P 1 "pop_operand" ">"))]
1718 "pop{<imodesuffix>}\t%0"
1719 [(set_attr "type" "pop")
1720 (set_attr "mode" "<MODE>")])
1722 (define_insn "*pop<mode>1_epilogue"
1723 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724 (match_operand:P 1 "pop_operand" ">"))
1725 (clobber (mem:BLK (scratch)))]
1727 "pop{<imodesuffix>}\t%0"
1728 [(set_attr "type" "pop")
1729 (set_attr "mode" "<MODE>")])
1731 ;; Move instructions.
1733 (define_expand "movoi"
1734 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735 (match_operand:OI 1 "general_operand" ""))]
1737 "ix86_expand_move (OImode, operands); DONE;")
1739 (define_expand "movti"
1740 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741 (match_operand:TI 1 "nonimmediate_operand" ""))]
1742 "TARGET_64BIT || TARGET_SSE"
1745 ix86_expand_move (TImode, operands);
1746 else if (push_operand (operands[0], TImode))
1747 ix86_expand_push (TImode, operands[1]);
1749 ix86_expand_vector_move (TImode, operands);
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern. Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759 (match_operand:CDI 1 "general_operand" ""))]
1762 if (push_operand (operands[0], CDImode))
1763 emit_move_complex_push (CDImode, operands[0], operands[1]);
1765 emit_move_complex_parts (operands[0], operands[1]);
1769 (define_expand "mov<mode>"
1770 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771 (match_operand:SWI1248x 1 "general_operand" ""))]
1773 "ix86_expand_move (<MODE>mode, operands); DONE;")
1775 (define_insn "*mov<mode>_xor"
1776 [(set (match_operand:SWI48 0 "register_operand" "=r")
1777 (match_operand:SWI48 1 "const0_operand" ""))
1778 (clobber (reg:CC FLAGS_REG))]
1781 [(set_attr "type" "alu1")
1782 (set_attr "mode" "SI")
1783 (set_attr "length_immediate" "0")])
1785 (define_insn "*mov<mode>_or"
1786 [(set (match_operand:SWI48 0 "register_operand" "=r")
1787 (match_operand:SWI48 1 "const_int_operand" ""))
1788 (clobber (reg:CC FLAGS_REG))]
1790 && operands[1] == constm1_rtx"
1791 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792 [(set_attr "type" "alu1")
1793 (set_attr "mode" "<MODE>")
1794 (set_attr "length_immediate" "1")])
1796 (define_insn "*movoi_internal_avx"
1797 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 switch (which_alternative)
1804 return "vxorps\t%0, %0, %0";
1807 if (misaligned_operand (operands[0], OImode)
1808 || misaligned_operand (operands[1], OImode))
1809 return "vmovdqu\t{%1, %0|%0, %1}";
1811 return "vmovdqa\t{%1, %0|%0, %1}";
1816 [(set_attr "type" "sselog1,ssemov,ssemov")
1817 (set_attr "prefix" "vex")
1818 (set_attr "mode" "OI")])
1820 (define_insn "*movti_internal_rex64"
1821 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1822 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1823 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (which_alternative)
1831 if (get_attr_mode (insn) == MODE_V4SF)
1832 return "%vxorps\t%0, %d0";
1834 return "%vpxor\t%0, %d0";
1837 /* TDmode values are passed as TImode on the stack. Moving them
1838 to stack may result in unaligned memory access. */
1839 if (misaligned_operand (operands[0], TImode)
1840 || misaligned_operand (operands[1], TImode))
1842 if (get_attr_mode (insn) == MODE_V4SF)
1843 return "%vmovups\t{%1, %0|%0, %1}";
1845 return "%vmovdqu\t{%1, %0|%0, %1}";
1849 if (get_attr_mode (insn) == MODE_V4SF)
1850 return "%vmovaps\t{%1, %0|%0, %1}";
1852 return "%vmovdqa\t{%1, %0|%0, %1}";
1858 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1859 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1861 (cond [(eq_attr "alternative" "2,3")
1863 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1865 (const_string "V4SF")
1866 (const_string "TI"))
1867 (eq_attr "alternative" "4")
1869 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1871 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1873 (const_string "V4SF")
1874 (const_string "TI"))]
1875 (const_string "DI")))])
1878 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1879 (match_operand:TI 1 "general_operand" ""))]
1881 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1883 "ix86_split_long_move (operands); DONE;")
1885 (define_insn "*movti_internal_sse"
1886 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1887 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1888 "TARGET_SSE && !TARGET_64BIT
1889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891 switch (which_alternative)
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vxorps\t%0, %d0";
1897 return "%vpxor\t%0, %d0";
1900 /* TDmode values are passed as TImode on the stack. Moving them
1901 to stack may result in unaligned memory access. */
1902 if (misaligned_operand (operands[0], TImode)
1903 || misaligned_operand (operands[1], TImode))
1905 if (get_attr_mode (insn) == MODE_V4SF)
1906 return "%vmovups\t{%1, %0|%0, %1}";
1908 return "%vmovdqu\t{%1, %0|%0, %1}";
1912 if (get_attr_mode (insn) == MODE_V4SF)
1913 return "%vmovaps\t{%1, %0|%0, %1}";
1915 return "%vmovdqa\t{%1, %0|%0, %1}";
1921 [(set_attr "type" "sselog1,ssemov,ssemov")
1922 (set_attr "prefix" "maybe_vex")
1924 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1925 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1927 (const_string "V4SF")
1928 (and (eq_attr "alternative" "2")
1929 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1931 (const_string "V4SF")]
1932 (const_string "TI")))])
1934 (define_insn "*movdi_internal_rex64"
1935 [(set (match_operand:DI 0 "nonimmediate_operand"
1936 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1937 (match_operand:DI 1 "general_operand"
1938 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1939 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1941 switch (get_attr_type (insn))
1944 if (SSE_REG_P (operands[0]))
1945 return "movq2dq\t{%1, %0|%0, %1}";
1947 return "movdq2q\t{%1, %0|%0, %1}";
1952 if (get_attr_mode (insn) == MODE_TI)
1953 return "vmovdqa\t{%1, %0|%0, %1}";
1955 return "vmovq\t{%1, %0|%0, %1}";
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "movdqa\t{%1, %0|%0, %1}";
1963 /* Moves from and into integer register is done using movd
1964 opcode with REX prefix. */
1965 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1966 return "movd\t{%1, %0|%0, %1}";
1967 return "movq\t{%1, %0|%0, %1}";
1970 return "%vpxor\t%0, %d0";
1973 return "pxor\t%0, %0";
1979 return "lea{q}\t{%a1, %0|%0, %a1}";
1982 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1983 if (get_attr_mode (insn) == MODE_SI)
1984 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1985 else if (which_alternative == 2)
1986 return "movabs{q}\t{%1, %0|%0, %1}";
1988 return "mov{q}\t{%1, %0|%0, %1}";
1992 (cond [(eq_attr "alternative" "5")
1993 (const_string "mmx")
1994 (eq_attr "alternative" "6,7,8,9,10")
1995 (const_string "mmxmov")
1996 (eq_attr "alternative" "11")
1997 (const_string "sselog1")
1998 (eq_attr "alternative" "12,13,14,15,16")
1999 (const_string "ssemov")
2000 (eq_attr "alternative" "17,18")
2001 (const_string "ssecvt")
2002 (eq_attr "alternative" "4")
2003 (const_string "multi")
2004 (match_operand:DI 1 "pic_32bit_operand" "")
2005 (const_string "lea")
2007 (const_string "imov")))
2010 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2012 (const_string "*")))
2013 (set (attr "length_immediate")
2015 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017 (const_string "*")))
2018 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2019 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2020 (set (attr "prefix")
2021 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2022 (const_string "maybe_vex")
2023 (const_string "orig")))
2024 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2026 ;; Convert impossible stores of immediate to existing instructions.
2027 ;; First try to get scratch register and go through it. In case this
2028 ;; fails, move by 32bit parts.
2030 [(match_scratch:DI 2 "r")
2031 (set (match_operand:DI 0 "memory_operand" "")
2032 (match_operand:DI 1 "immediate_operand" ""))]
2033 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2034 && !x86_64_immediate_operand (operands[1], DImode)"
2035 [(set (match_dup 2) (match_dup 1))
2036 (set (match_dup 0) (match_dup 2))])
2038 ;; We need to define this as both peepholer and splitter for case
2039 ;; peephole2 pass is not run.
2040 ;; "&& 1" is needed to keep it from matching the previous pattern.
2042 [(set (match_operand:DI 0 "memory_operand" "")
2043 (match_operand:DI 1 "immediate_operand" ""))]
2044 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2045 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2046 [(set (match_dup 2) (match_dup 3))
2047 (set (match_dup 4) (match_dup 5))]
2048 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2051 [(set (match_operand:DI 0 "memory_operand" "")
2052 (match_operand:DI 1 "immediate_operand" ""))]
2053 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2054 ? epilogue_completed : reload_completed)
2055 && !symbolic_operand (operands[1], DImode)
2056 && !x86_64_immediate_operand (operands[1], DImode)"
2057 [(set (match_dup 2) (match_dup 3))
2058 (set (match_dup 4) (match_dup 5))]
2059 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2061 (define_insn "*movdi_internal"
2062 [(set (match_operand:DI 0 "nonimmediate_operand"
2063 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2064 (match_operand:DI 1 "general_operand"
2065 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2066 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2071 movq\t{%1, %0|%0, %1}
2072 movq\t{%1, %0|%0, %1}
2074 %vmovq\t{%1, %0|%0, %1}
2075 %vmovdqa\t{%1, %0|%0, %1}
2076 %vmovq\t{%1, %0|%0, %1}
2078 movlps\t{%1, %0|%0, %1}
2079 movaps\t{%1, %0|%0, %1}
2080 movlps\t{%1, %0|%0, %1}"
2081 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2082 (set (attr "prefix")
2083 (if_then_else (eq_attr "alternative" "5,6,7,8")
2084 (const_string "vex")
2085 (const_string "orig")))
2086 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2089 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2090 (match_operand:DI 1 "general_operand" ""))]
2091 "!TARGET_64BIT && reload_completed
2092 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2093 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2095 "ix86_split_long_move (operands); DONE;")
2097 (define_insn "*movsi_internal"
2098 [(set (match_operand:SI 0 "nonimmediate_operand"
2099 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2100 (match_operand:SI 1 "general_operand"
2101 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2102 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2104 switch (get_attr_type (insn))
2107 if (get_attr_mode (insn) == MODE_TI)
2108 return "%vpxor\t%0, %d0";
2109 return "%vxorps\t%0, %d0";
2112 switch (get_attr_mode (insn))
2115 return "%vmovdqa\t{%1, %0|%0, %1}";
2117 return "%vmovaps\t{%1, %0|%0, %1}";
2119 return "%vmovd\t{%1, %0|%0, %1}";
2121 return "%vmovss\t{%1, %0|%0, %1}";
2127 return "pxor\t%0, %0";
2130 if (get_attr_mode (insn) == MODE_DI)
2131 return "movq\t{%1, %0|%0, %1}";
2132 return "movd\t{%1, %0|%0, %1}";
2135 return "lea{l}\t{%a1, %0|%0, %a1}";
2138 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2139 return "mov{l}\t{%1, %0|%0, %1}";
2143 (cond [(eq_attr "alternative" "2")
2144 (const_string "mmx")
2145 (eq_attr "alternative" "3,4,5")
2146 (const_string "mmxmov")
2147 (eq_attr "alternative" "6")
2148 (const_string "sselog1")
2149 (eq_attr "alternative" "7,8,9,10,11")
2150 (const_string "ssemov")
2151 (match_operand:DI 1 "pic_32bit_operand" "")
2152 (const_string "lea")
2154 (const_string "imov")))
2155 (set (attr "prefix")
2156 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2157 (const_string "orig")
2158 (const_string "maybe_vex")))
2159 (set (attr "prefix_data16")
2160 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2162 (const_string "*")))
2164 (cond [(eq_attr "alternative" "2,3")
2166 (eq_attr "alternative" "6,7")
2168 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2169 (const_string "V4SF")
2170 (const_string "TI"))
2171 (and (eq_attr "alternative" "8,9,10,11")
2172 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2175 (const_string "SI")))])
2177 (define_insn "*movhi_internal"
2178 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2179 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2182 switch (get_attr_type (insn))
2185 /* movzwl is faster than movw on p2 due to partial word stalls,
2186 though not as fast as an aligned movl. */
2187 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2189 if (get_attr_mode (insn) == MODE_SI)
2190 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2192 return "mov{w}\t{%1, %0|%0, %1}";
2196 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2198 (const_string "imov")
2199 (and (eq_attr "alternative" "0")
2200 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2202 (eq (symbol_ref "TARGET_HIMODE_MATH")
2204 (const_string "imov")
2205 (and (eq_attr "alternative" "1,2")
2206 (match_operand:HI 1 "aligned_operand" ""))
2207 (const_string "imov")
2208 (and (ne (symbol_ref "TARGET_MOVX")
2210 (eq_attr "alternative" "0,2"))
2211 (const_string "imovx")
2213 (const_string "imov")))
2215 (cond [(eq_attr "type" "imovx")
2217 (and (eq_attr "alternative" "1,2")
2218 (match_operand:HI 1 "aligned_operand" ""))
2220 (and (eq_attr "alternative" "0")
2221 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2223 (eq (symbol_ref "TARGET_HIMODE_MATH")
2227 (const_string "HI")))])
2229 ;; Situation is quite tricky about when to choose full sized (SImode) move
2230 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2231 ;; partial register dependency machines (such as AMD Athlon), where QImode
2232 ;; moves issue extra dependency and for partial register stalls machines
2233 ;; that don't use QImode patterns (and QImode move cause stall on the next
2236 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2237 ;; register stall machines with, where we use QImode instructions, since
2238 ;; partial register stall can be caused there. Then we use movzx.
2239 (define_insn "*movqi_internal"
2240 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2241 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2242 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2244 switch (get_attr_type (insn))
2247 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2248 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2250 if (get_attr_mode (insn) == MODE_SI)
2251 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2253 return "mov{b}\t{%1, %0|%0, %1}";
2257 (cond [(and (eq_attr "alternative" "5")
2258 (not (match_operand:QI 1 "aligned_operand" "")))
2259 (const_string "imovx")
2260 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2262 (const_string "imov")
2263 (and (eq_attr "alternative" "3")
2264 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2266 (eq (symbol_ref "TARGET_QIMODE_MATH")
2268 (const_string "imov")
2269 (eq_attr "alternative" "3,5")
2270 (const_string "imovx")
2271 (and (ne (symbol_ref "TARGET_MOVX")
2273 (eq_attr "alternative" "2"))
2274 (const_string "imovx")
2276 (const_string "imov")))
2278 (cond [(eq_attr "alternative" "3,4,5")
2280 (eq_attr "alternative" "6")
2282 (eq_attr "type" "imovx")
2284 (and (eq_attr "type" "imov")
2285 (and (eq_attr "alternative" "0,1")
2286 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2288 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2290 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2293 ;; Avoid partial register stalls when not using QImode arithmetic
2294 (and (eq_attr "type" "imov")
2295 (and (eq_attr "alternative" "0,1")
2296 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2298 (eq (symbol_ref "TARGET_QIMODE_MATH")
2302 (const_string "QI")))])
2304 ;; Stores and loads of ax to arbitrary constant address.
2305 ;; We fake an second form of instruction to force reload to load address
2306 ;; into register when rax is not available
2307 (define_insn "*movabs<mode>_1"
2308 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2309 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2310 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2312 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2313 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2314 [(set_attr "type" "imov")
2315 (set_attr "modrm" "0,*")
2316 (set_attr "length_address" "8,0")
2317 (set_attr "length_immediate" "0,*")
2318 (set_attr "memory" "store")
2319 (set_attr "mode" "<MODE>")])
2321 (define_insn "*movabs<mode>_2"
2322 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2323 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2324 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2326 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2327 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2328 [(set_attr "type" "imov")
2329 (set_attr "modrm" "0,*")
2330 (set_attr "length_address" "8,0")
2331 (set_attr "length_immediate" "0")
2332 (set_attr "memory" "load")
2333 (set_attr "mode" "<MODE>")])
2335 (define_insn "*swap<mode>"
2336 [(set (match_operand:SWI48 0 "register_operand" "+r")
2337 (match_operand:SWI48 1 "register_operand" "+r"))
2341 "xchg{<imodesuffix>}\t%1, %0"
2342 [(set_attr "type" "imov")
2343 (set_attr "mode" "<MODE>")
2344 (set_attr "pent_pair" "np")
2345 (set_attr "athlon_decode" "vector")
2346 (set_attr "amdfam10_decode" "double")])
2348 (define_insn "*swap<mode>_1"
2349 [(set (match_operand:SWI12 0 "register_operand" "+r")
2350 (match_operand:SWI12 1 "register_operand" "+r"))
2353 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2355 [(set_attr "type" "imov")
2356 (set_attr "mode" "SI")
2357 (set_attr "pent_pair" "np")
2358 (set_attr "athlon_decode" "vector")
2359 (set_attr "amdfam10_decode" "double")])
2361 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2362 ;; is disabled for AMDFAM10
2363 (define_insn "*swap<mode>_2"
2364 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2365 (match_operand:SWI12 1 "register_operand" "+<r>"))
2368 "TARGET_PARTIAL_REG_STALL"
2369 "xchg{<imodesuffix>}\t%1, %0"
2370 [(set_attr "type" "imov")
2371 (set_attr "mode" "<MODE>")
2372 (set_attr "pent_pair" "np")
2373 (set_attr "athlon_decode" "vector")])
2375 (define_expand "movstrict<mode>"
2376 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2377 (match_operand:SWI12 1 "general_operand" ""))]
2380 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2382 /* Don't generate memory->memory moves, go through a register */
2383 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2384 operands[1] = force_reg (<MODE>mode, operands[1]);
2387 (define_insn "*movstrict<mode>_1"
2388 [(set (strict_low_part
2389 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2390 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2391 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2392 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2393 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")])
2397 (define_insn "*movstrict<mode>_xor"
2398 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2399 (match_operand:SWI12 1 "const0_operand" ""))
2400 (clobber (reg:CC FLAGS_REG))]
2402 "xor{<imodesuffix>}\t%0, %0"
2403 [(set_attr "type" "alu1")
2404 (set_attr "mode" "<MODE>")
2405 (set_attr "length_immediate" "0")])
2407 (define_insn "*mov<mode>_extv_1"
2408 [(set (match_operand:SWI24 0 "register_operand" "=R")
2409 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2413 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2414 [(set_attr "type" "imovx")
2415 (set_attr "mode" "SI")])
2417 (define_insn "*movqi_extv_1_rex64"
2418 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2419 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2424 switch (get_attr_type (insn))
2427 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2429 return "mov{b}\t{%h1, %0|%0, %h1}";
2433 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2434 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2435 (ne (symbol_ref "TARGET_MOVX")
2437 (const_string "imovx")
2438 (const_string "imov")))
2440 (if_then_else (eq_attr "type" "imovx")
2442 (const_string "QI")))])
2444 (define_insn "*movqi_extv_1"
2445 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2446 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2451 switch (get_attr_type (insn))
2454 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2456 return "mov{b}\t{%h1, %0|%0, %h1}";
2460 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2461 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2462 (ne (symbol_ref "TARGET_MOVX")
2464 (const_string "imovx")
2465 (const_string "imov")))
2467 (if_then_else (eq_attr "type" "imovx")
2469 (const_string "QI")))])
2471 (define_insn "*mov<mode>_extzv_1"
2472 [(set (match_operand:SWI48 0 "register_operand" "=R")
2473 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2477 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2478 [(set_attr "type" "imovx")
2479 (set_attr "mode" "SI")])
2481 (define_insn "*movqi_extzv_2_rex64"
2482 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2484 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2489 switch (get_attr_type (insn))
2492 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2494 return "mov{b}\t{%h1, %0|%0, %h1}";
2498 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2499 (ne (symbol_ref "TARGET_MOVX")
2501 (const_string "imovx")
2502 (const_string "imov")))
2504 (if_then_else (eq_attr "type" "imovx")
2506 (const_string "QI")))])
2508 (define_insn "*movqi_extzv_2"
2509 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2511 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2516 switch (get_attr_type (insn))
2519 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2521 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2526 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2527 (ne (symbol_ref "TARGET_MOVX")
2529 (const_string "imovx")
2530 (const_string "imov")))
2532 (if_then_else (eq_attr "type" "imovx")
2534 (const_string "QI")))])
2536 (define_expand "mov<mode>_insv_1"
2537 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2540 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2544 (define_insn "*mov<mode>_insv_1_rex64"
2545 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2548 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2550 "mov{b}\t{%b1, %h0|%h0, %b1}"
2551 [(set_attr "type" "imov")
2552 (set_attr "mode" "QI")])
2554 (define_insn "*movsi_insv_1"
2555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2558 (match_operand:SI 1 "general_operand" "Qmn"))]
2560 "mov{b}\t{%b1, %h0|%h0, %b1}"
2561 [(set_attr "type" "imov")
2562 (set_attr "mode" "QI")])
2564 (define_insn "*movqi_insv_2"
2565 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2568 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2571 "mov{b}\t{%h1, %h0|%h0, %h1}"
2572 [(set_attr "type" "imov")
2573 (set_attr "mode" "QI")])
2575 ;; Floating point push instructions.
2577 (define_insn "*pushtf"
2578 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2579 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2582 /* This insn should be already split before reg-stack. */
2585 [(set_attr "type" "multi")
2586 (set_attr "unit" "sse,*,*")
2587 (set_attr "mode" "TF,SI,SI")])
2590 [(set (match_operand:TF 0 "push_operand" "")
2591 (match_operand:TF 1 "sse_reg_operand" ""))]
2592 "TARGET_SSE2 && reload_completed"
2593 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2594 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2597 [(set (match_operand:TF 0 "push_operand" "")
2598 (match_operand:TF 1 "general_operand" ""))]
2599 "TARGET_SSE2 && reload_completed
2600 && !SSE_REG_P (operands[1])"
2602 "ix86_split_long_move (operands); DONE;")
2604 (define_insn "*pushxf"
2605 [(set (match_operand:XF 0 "push_operand" "=<,<")
2606 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2607 "optimize_function_for_speed_p (cfun)"
2609 /* This insn should be already split before reg-stack. */
2612 [(set_attr "type" "multi")
2613 (set_attr "unit" "i387,*")
2614 (set_attr "mode" "XF,SI")])
2616 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2617 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2618 ;; Pushing using integer instructions is longer except for constants
2619 ;; and direct memory references (assuming that any given constant is pushed
2620 ;; only once, but this ought to be handled elsewhere).
2622 (define_insn "*pushxf_nointeger"
2623 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2624 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2625 "optimize_function_for_size_p (cfun)"
2627 /* This insn should be already split before reg-stack. */
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "i387,*,*")
2632 (set_attr "mode" "XF,SI,SI")])
2635 [(set (match_operand:XF 0 "push_operand" "")
2636 (match_operand:XF 1 "fp_register_operand" ""))]
2638 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2639 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2640 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2643 [(set (match_operand:XF 0 "push_operand" "")
2644 (match_operand:XF 1 "general_operand" ""))]
2646 && !FP_REG_P (operands[1])"
2648 "ix86_split_long_move (operands); DONE;")
2650 (define_insn "*pushdf"
2651 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2652 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2653 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*,*")
2660 (set_attr "mode" "DF,SI,DF")])
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2664 ;; On the average, pushdf using integers can be still shorter. Allow this
2665 ;; pattern for optimize_size too.
2667 (define_insn "*pushdf_nointeger"
2668 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2669 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2670 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2672 /* This insn should be already split before reg-stack. */
2675 [(set_attr "type" "multi")
2676 (set_attr "unit" "i387,*,*,*")
2677 (set_attr "mode" "DF,SI,SI,DF")])
2679 ;; %%% Kill this when call knows how to work this out.
2681 [(set (match_operand:DF 0 "push_operand" "")
2682 (match_operand:DF 1 "any_fp_register_operand" ""))]
2684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2685 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2688 [(set (match_operand:DF 0 "push_operand" "")
2689 (match_operand:DF 1 "general_operand" ""))]
2691 && !ANY_FP_REG_P (operands[1])"
2693 "ix86_split_long_move (operands); DONE;")
2695 (define_insn "*pushsf_rex64"
2696 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2697 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2700 /* Anything else should be already split before reg-stack. */
2701 gcc_assert (which_alternative == 1);
2702 return "push{q}\t%q1";
2704 [(set_attr "type" "multi,push,multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "SF,DI,SF")])
2708 (define_insn "*pushsf"
2709 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2710 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2713 /* Anything else should be already split before reg-stack. */
2714 gcc_assert (which_alternative == 1);
2715 return "push{l}\t%1";
2717 [(set_attr "type" "multi,push,multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "SF,SI,SF")])
2722 [(set (match_operand:SF 0 "push_operand" "")
2723 (match_operand:SF 1 "memory_operand" ""))]
2725 && MEM_P (operands[1])
2726 && (operands[2] = find_constant_src (insn))"
2730 ;; %%% Kill this when call knows how to work this out.
2732 [(set (match_operand:SF 0 "push_operand" "")
2733 (match_operand:SF 1 "any_fp_register_operand" ""))]
2735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2736 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2737 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2739 ;; Floating point move instructions.
2741 (define_expand "movtf"
2742 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2743 (match_operand:TF 1 "nonimmediate_operand" ""))]
2746 ix86_expand_move (TFmode, operands);
2750 (define_expand "mov<mode>"
2751 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2752 (match_operand:X87MODEF 1 "general_operand" ""))]
2754 "ix86_expand_move (<MODE>mode, operands); DONE;")
2756 (define_insn "*movtf_internal"
2757 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2758 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2762 switch (which_alternative)
2766 if (get_attr_mode (insn) == MODE_V4SF)
2767 return "%vmovaps\t{%1, %0|%0, %1}";
2769 return "%vmovdqa\t{%1, %0|%0, %1}";
2771 if (get_attr_mode (insn) == MODE_V4SF)
2772 return "%vxorps\t%0, %d0";
2774 return "%vpxor\t%0, %d0";
2782 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2783 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2785 (cond [(eq_attr "alternative" "0,2")
2787 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2789 (const_string "V4SF")
2790 (const_string "TI"))
2791 (eq_attr "alternative" "1")
2793 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2795 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2797 (const_string "V4SF")
2798 (const_string "TI"))]
2799 (const_string "DI")))])
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "general_operand" ""))]
2805 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2807 "ix86_split_long_move (operands); DONE;")
2809 (define_insn "*movxf_internal"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2811 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2812 "optimize_function_for_speed_p (cfun)
2813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 return standard_80387_constant_opcode (operands[1]);
2834 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835 (set_attr "mode" "XF,XF,XF,SI,SI")])
2837 ;; Do not use integer registers when optimizing for size
2838 (define_insn "*movxf_internal_nointeger"
2839 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2840 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2841 "optimize_function_for_size_p (cfun)
2842 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2843 && (reload_in_progress || reload_completed
2844 || standard_80387_constant_p (operands[1])
2845 || GET_CODE (operands[1]) != CONST_DOUBLE
2846 || memory_operand (operands[0], XFmode))"
2848 switch (which_alternative)
2852 return output_387_reg_move (insn, operands);
2855 return standard_80387_constant_opcode (operands[1]);
2863 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2864 (set_attr "mode" "XF,XF,XF,SI,SI")])
2867 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2868 (match_operand:XF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*movdf_internal_rex64"
2881 [(set (match_operand:DF 0 "nonimmediate_operand"
2882 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2883 (match_operand:DF 1 "general_operand"
2884 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2885 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (reload_in_progress || reload_completed
2887 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2889 && optimize_function_for_size_p (cfun)
2890 && standard_80387_constant_p (operands[1]))
2891 || GET_CODE (operands[1]) != CONST_DOUBLE
2892 || memory_operand (operands[0], DFmode))"
2894 switch (which_alternative)
2898 return output_387_reg_move (insn, operands);
2901 return standard_80387_constant_opcode (operands[1]);
2908 switch (get_attr_mode (insn))
2911 return "%vxorps\t%0, %d0";
2913 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2914 return "%vxorps\t%0, %d0";
2916 return "%vxorpd\t%0, %d0";
2918 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2919 return "%vxorps\t%0, %d0";
2921 return "%vpxor\t%0, %d0";
2928 switch (get_attr_mode (insn))
2931 return "%vmovaps\t{%1, %0|%0, %1}";
2933 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2934 return "%vmovaps\t{%1, %0|%0, %1}";
2936 return "%vmovapd\t{%1, %0|%0, %1}";
2938 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovdqa\t{%1, %0|%0, %1}";
2943 return "%vmovq\t{%1, %0|%0, %1}";
2947 if (REG_P (operands[0]) && REG_P (operands[1]))
2948 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2950 return "vmovsd\t{%1, %0|%0, %1}";
2953 return "movsd\t{%1, %0|%0, %1}";
2955 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2957 return "%vmovlps\t{%1, %d0|%d0, %1}";
2964 return "%vmovd\t{%1, %0|%0, %1}";
2970 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2971 (set (attr "prefix")
2972 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2973 (const_string "orig")
2974 (const_string "maybe_vex")))
2975 (set (attr "prefix_data16")
2976 (if_then_else (eq_attr "mode" "V1DF")
2978 (const_string "*")))
2980 (cond [(eq_attr "alternative" "0,1,2")
2982 (eq_attr "alternative" "3,4,9,10")
2985 /* For SSE1, we have many fewer alternatives. */
2986 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2987 (cond [(eq_attr "alternative" "5,6")
2988 (const_string "V4SF")
2990 (const_string "V2SF"))
2992 /* xorps is one byte shorter. */
2993 (eq_attr "alternative" "5")
2994 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2996 (const_string "V4SF")
2997 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3001 (const_string "V2DF"))
3003 /* For architectures resolving dependencies on
3004 whole SSE registers use APD move to break dependency
3005 chains, otherwise use short move to avoid extra work.
3007 movaps encodes one byte shorter. */
3008 (eq_attr "alternative" "6")
3010 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_string "V4SF")
3013 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3015 (const_string "V2DF")
3017 (const_string "DF"))
3018 /* For architectures resolving dependencies on register
3019 parts we may avoid extra work to zero out upper part
3021 (eq_attr "alternative" "7")
3023 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3025 (const_string "V1DF")
3026 (const_string "DF"))
3028 (const_string "DF")))])
3030 (define_insn "*movdf_internal"
3031 [(set (match_operand:DF 0 "nonimmediate_operand"
3032 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3033 (match_operand:DF 1 "general_operand"
3034 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3035 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3036 && optimize_function_for_speed_p (cfun)
3037 && TARGET_INTEGER_DFMODE_MOVES
3038 && (reload_in_progress || reload_completed
3039 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3040 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3041 && optimize_function_for_size_p (cfun)
3042 && standard_80387_constant_p (operands[1]))
3043 || GET_CODE (operands[1]) != CONST_DOUBLE
3044 || memory_operand (operands[0], DFmode))"
3046 switch (which_alternative)
3050 return output_387_reg_move (insn, operands);
3053 return standard_80387_constant_opcode (operands[1]);
3060 switch (get_attr_mode (insn))
3063 return "xorps\t%0, %0";
3065 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3066 return "xorps\t%0, %0";
3068 return "xorpd\t%0, %0";
3070 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3071 return "xorps\t%0, %0";
3073 return "pxor\t%0, %0";
3080 switch (get_attr_mode (insn))
3083 return "movaps\t{%1, %0|%0, %1}";
3085 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086 return "movaps\t{%1, %0|%0, %1}";
3088 return "movapd\t{%1, %0|%0, %1}";
3090 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3091 return "movaps\t{%1, %0|%0, %1}";
3093 return "movdqa\t{%1, %0|%0, %1}";
3095 return "movq\t{%1, %0|%0, %1}";
3097 return "movsd\t{%1, %0|%0, %1}";
3099 return "movlpd\t{%1, %0|%0, %1}";
3101 return "movlps\t{%1, %0|%0, %1}";
3110 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3111 (set (attr "prefix_data16")
3112 (if_then_else (eq_attr "mode" "V1DF")
3114 (const_string "*")))
3116 (cond [(eq_attr "alternative" "0,1,2")
3118 (eq_attr "alternative" "3,4")
3121 /* For SSE1, we have many fewer alternatives. */
3122 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3123 (cond [(eq_attr "alternative" "5,6")
3124 (const_string "V4SF")
3126 (const_string "V2SF"))
3128 /* xorps is one byte shorter. */
3129 (eq_attr "alternative" "5")
3130 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3132 (const_string "V4SF")
3133 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3137 (const_string "V2DF"))
3139 /* For architectures resolving dependencies on
3140 whole SSE registers use APD move to break dependency
3141 chains, otherwise use short move to avoid extra work.
3143 movaps encodes one byte shorter. */
3144 (eq_attr "alternative" "6")
3146 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3148 (const_string "V4SF")
3149 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3151 (const_string "V2DF")
3153 (const_string "DF"))
3154 /* For architectures resolving dependencies on register
3155 parts we may avoid extra work to zero out upper part
3157 (eq_attr "alternative" "7")
3159 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3161 (const_string "V1DF")
3162 (const_string "DF"))
3164 (const_string "DF")))])
3166 ;; Moving is usually shorter when only FP registers are used. This separate
3167 ;; movdf pattern avoids the use of integer registers for FP operations
3168 ;; when optimizing for size.
3170 (define_insn "*movdf_internal_nointeger"
3171 [(set (match_operand:DF 0 "nonimmediate_operand"
3172 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3173 (match_operand:DF 1 "general_operand"
3174 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3175 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3176 && ((optimize_function_for_size_p (cfun)
3177 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3178 && (reload_in_progress || reload_completed
3179 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3180 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3181 && optimize_function_for_size_p (cfun)
3182 && !memory_operand (operands[0], DFmode)
3183 && standard_80387_constant_p (operands[1]))
3184 || GET_CODE (operands[1]) != CONST_DOUBLE
3185 || ((optimize_function_for_size_p (cfun)
3186 || !TARGET_MEMORY_MISMATCH_STALL
3187 || reload_in_progress || reload_completed)
3188 && memory_operand (operands[0], DFmode)))"
3190 switch (which_alternative)
3194 return output_387_reg_move (insn, operands);
3197 return standard_80387_constant_opcode (operands[1]);
3204 switch (get_attr_mode (insn))
3207 return "%vxorps\t%0, %d0";
3209 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3210 return "%vxorps\t%0, %d0";
3212 return "%vxorpd\t%0, %d0";
3214 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3215 return "%vxorps\t%0, %d0";
3217 return "%vpxor\t%0, %d0";
3224 switch (get_attr_mode (insn))
3227 return "%vmovaps\t{%1, %0|%0, %1}";
3229 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3230 return "%vmovaps\t{%1, %0|%0, %1}";
3232 return "%vmovapd\t{%1, %0|%0, %1}";
3234 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3235 return "%vmovaps\t{%1, %0|%0, %1}";
3237 return "%vmovdqa\t{%1, %0|%0, %1}";
3239 return "%vmovq\t{%1, %0|%0, %1}";
3243 if (REG_P (operands[0]) && REG_P (operands[1]))
3244 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3246 return "vmovsd\t{%1, %0|%0, %1}";
3249 return "movsd\t{%1, %0|%0, %1}";
3253 if (REG_P (operands[0]))
3254 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3256 return "vmovlpd\t{%1, %0|%0, %1}";
3259 return "movlpd\t{%1, %0|%0, %1}";
3263 if (REG_P (operands[0]))
3264 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3266 return "vmovlps\t{%1, %0|%0, %1}";
3269 return "movlps\t{%1, %0|%0, %1}";
3278 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3279 (set (attr "prefix")
3280 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3281 (const_string "orig")
3282 (const_string "maybe_vex")))
3283 (set (attr "prefix_data16")
3284 (if_then_else (eq_attr "mode" "V1DF")
3286 (const_string "*")))
3288 (cond [(eq_attr "alternative" "0,1,2")
3290 (eq_attr "alternative" "3,4")
3293 /* For SSE1, we have many fewer alternatives. */
3294 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3295 (cond [(eq_attr "alternative" "5,6")
3296 (const_string "V4SF")
3298 (const_string "V2SF"))
3300 /* xorps is one byte shorter. */
3301 (eq_attr "alternative" "5")
3302 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3304 (const_string "V4SF")
3305 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3309 (const_string "V2DF"))
3311 /* For architectures resolving dependencies on
3312 whole SSE registers use APD move to break dependency
3313 chains, otherwise use short move to avoid extra work.
3315 movaps encodes one byte shorter. */
3316 (eq_attr "alternative" "6")
3318 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320 (const_string "V4SF")
3321 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3323 (const_string "V2DF")
3325 (const_string "DF"))
3326 /* For architectures resolving dependencies on register
3327 parts we may avoid extra work to zero out upper part
3329 (eq_attr "alternative" "7")
3331 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3333 (const_string "V1DF")
3334 (const_string "DF"))
3336 (const_string "DF")))])
3339 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3340 (match_operand:DF 1 "general_operand" ""))]
3342 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3343 && ! (ANY_FP_REG_P (operands[0]) ||
3344 (GET_CODE (operands[0]) == SUBREG
3345 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3346 && ! (ANY_FP_REG_P (operands[1]) ||
3347 (GET_CODE (operands[1]) == SUBREG
3348 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3350 "ix86_split_long_move (operands); DONE;")
3352 (define_insn "*movsf_internal"
3353 [(set (match_operand:SF 0 "nonimmediate_operand"
3354 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3355 (match_operand:SF 1 "general_operand"
3356 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3357 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3358 && (reload_in_progress || reload_completed
3359 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3360 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3361 && standard_80387_constant_p (operands[1]))
3362 || GET_CODE (operands[1]) != CONST_DOUBLE
3363 || memory_operand (operands[0], SFmode))"
3365 switch (which_alternative)
3369 return output_387_reg_move (insn, operands);
3372 return standard_80387_constant_opcode (operands[1]);
3376 return "mov{l}\t{%1, %0|%0, %1}";
3378 if (get_attr_mode (insn) == MODE_TI)
3379 return "%vpxor\t%0, %d0";
3381 return "%vxorps\t%0, %d0";
3383 if (get_attr_mode (insn) == MODE_V4SF)
3384 return "%vmovaps\t{%1, %0|%0, %1}";
3386 return "%vmovss\t{%1, %d0|%d0, %1}";
3389 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3390 : "vmovss\t{%1, %0|%0, %1}";
3392 return "movss\t{%1, %0|%0, %1}";
3394 return "%vmovss\t{%1, %0|%0, %1}";
3396 case 9: case 10: case 14: case 15:
3397 return "movd\t{%1, %0|%0, %1}";
3399 return "%vmovd\t{%1, %0|%0, %1}";
3402 return "movq\t{%1, %0|%0, %1}";
3408 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3409 (set (attr "prefix")
3410 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3411 (const_string "maybe_vex")
3412 (const_string "orig")))
3414 (cond [(eq_attr "alternative" "3,4,9,10")
3416 (eq_attr "alternative" "5")
3418 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3420 (ne (symbol_ref "TARGET_SSE2")
3422 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3425 (const_string "V4SF"))
3426 /* For architectures resolving dependencies on
3427 whole SSE registers use APS move to break dependency
3428 chains, otherwise use short move to avoid extra work.
3430 Do the same for architectures resolving dependencies on
3431 the parts. While in DF mode it is better to always handle
3432 just register parts, the SF mode is different due to lack
3433 of instructions to load just part of the register. It is
3434 better to maintain the whole registers in single format
3435 to avoid problems on using packed logical operations. */
3436 (eq_attr "alternative" "6")
3438 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3440 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3442 (const_string "V4SF")
3443 (const_string "SF"))
3444 (eq_attr "alternative" "11")
3445 (const_string "DI")]
3446 (const_string "SF")))])
3449 [(set (match_operand 0 "register_operand" "")
3450 (match_operand 1 "memory_operand" ""))]
3452 && MEM_P (operands[1])
3453 && (GET_MODE (operands[0]) == TFmode
3454 || GET_MODE (operands[0]) == XFmode
3455 || GET_MODE (operands[0]) == DFmode
3456 || GET_MODE (operands[0]) == SFmode)
3457 && (operands[2] = find_constant_src (insn))"
3458 [(set (match_dup 0) (match_dup 2))]
3460 rtx c = operands[2];
3461 rtx r = operands[0];
3463 if (GET_CODE (r) == SUBREG)
3468 if (!standard_sse_constant_p (c))
3471 else if (FP_REG_P (r))
3473 if (!standard_80387_constant_p (c))
3476 else if (MMX_REG_P (r))
3481 [(set (match_operand 0 "register_operand" "")
3482 (float_extend (match_operand 1 "memory_operand" "")))]
3484 && MEM_P (operands[1])
3485 && (GET_MODE (operands[0]) == TFmode
3486 || GET_MODE (operands[0]) == XFmode
3487 || GET_MODE (operands[0]) == DFmode
3488 || GET_MODE (operands[0]) == SFmode)
3489 && (operands[2] = find_constant_src (insn))"
3490 [(set (match_dup 0) (match_dup 2))]
3492 rtx c = operands[2];
3493 rtx r = operands[0];
3495 if (GET_CODE (r) == SUBREG)
3500 if (!standard_sse_constant_p (c))
3503 else if (FP_REG_P (r))
3505 if (!standard_80387_constant_p (c))
3508 else if (MMX_REG_P (r))
3512 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3514 [(set (match_operand:X87MODEF 0 "register_operand" "")
3515 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3516 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3517 && (standard_80387_constant_p (operands[1]) == 8
3518 || standard_80387_constant_p (operands[1]) == 9)"
3519 [(set (match_dup 0)(match_dup 1))
3521 (neg:X87MODEF (match_dup 0)))]
3525 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3526 if (real_isnegzero (&r))
3527 operands[1] = CONST0_RTX (<MODE>mode);
3529 operands[1] = CONST1_RTX (<MODE>mode);
3532 (define_insn "swapxf"
3533 [(set (match_operand:XF 0 "register_operand" "+f")
3534 (match_operand:XF 1 "register_operand" "+f"))
3539 if (STACK_TOP_P (operands[0]))
3544 [(set_attr "type" "fxch")
3545 (set_attr "mode" "XF")])
3547 (define_insn "*swap<mode>"
3548 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3549 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3552 "TARGET_80387 || reload_completed"
3554 if (STACK_TOP_P (operands[0]))
3559 [(set_attr "type" "fxch")
3560 (set_attr "mode" "<MODE>")])
3562 ;; Zero extension instructions
3564 (define_expand "zero_extendsidi2"
3565 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3566 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3576 (define_insn "*zero_extendsidi2_rex64"
3577 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3579 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3582 mov\t{%k1, %k0|%k0, %k1}
3584 movd\t{%1, %0|%0, %1}
3585 movd\t{%1, %0|%0, %1}
3586 %vmovd\t{%1, %0|%0, %1}
3587 %vmovd\t{%1, %0|%0, %1}"
3588 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3589 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3590 (set_attr "prefix_0f" "0,*,*,*,*,*")
3591 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3594 [(set (match_operand:DI 0 "memory_operand" "")
3595 (zero_extend:DI (match_dup 0)))]
3597 [(set (match_dup 4) (const_int 0))]
3598 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3600 ;; %%% Kill me once multi-word ops are sane.
3601 (define_insn "zero_extendsidi2_1"
3602 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3604 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3605 (clobber (reg:CC FLAGS_REG))]
3611 movd\t{%1, %0|%0, %1}
3612 movd\t{%1, %0|%0, %1}
3613 %vmovd\t{%1, %0|%0, %1}
3614 %vmovd\t{%1, %0|%0, %1}"
3615 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3616 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3617 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3620 [(set (match_operand:DI 0 "register_operand" "")
3621 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3622 (clobber (reg:CC FLAGS_REG))]
3623 "!TARGET_64BIT && reload_completed
3624 && true_regnum (operands[0]) == true_regnum (operands[1])"
3625 [(set (match_dup 4) (const_int 0))]
3626 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3629 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3630 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3631 (clobber (reg:CC FLAGS_REG))]
3632 "!TARGET_64BIT && reload_completed
3633 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3634 [(set (match_dup 3) (match_dup 1))
3635 (set (match_dup 4) (const_int 0))]
3636 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3638 (define_insn "zero_extend<mode>di2"
3639 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3643 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3644 [(set_attr "type" "imovx")
3645 (set_attr "mode" "SI")])
3647 (define_expand "zero_extendhisi2"
3648 [(set (match_operand:SI 0 "register_operand" "")
3649 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3652 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 operands[1] = force_reg (HImode, operands[1]);
3655 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 (define_insn_and_split "zero_extendhisi2_and"
3661 [(set (match_operand:SI 0 "register_operand" "=r")
3662 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663 (clobber (reg:CC FLAGS_REG))]
3664 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 "&& reload_completed"
3667 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3668 (clobber (reg:CC FLAGS_REG))])]
3670 [(set_attr "type" "alu1")
3671 (set_attr "mode" "SI")])
3673 (define_insn "*zero_extendhisi2_movzwl"
3674 [(set (match_operand:SI 0 "register_operand" "=r")
3675 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3676 "!TARGET_ZERO_EXTEND_WITH_AND
3677 || optimize_function_for_size_p (cfun)"
3678 "movz{wl|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "SI")])
3682 (define_expand "zero_extendqi<mode>2"
3684 [(set (match_operand:SWI24 0 "register_operand" "")
3685 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))])]
3690 (define_insn "*zero_extendqi<mode>2_and"
3691 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3692 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3693 (clobber (reg:CC FLAGS_REG))]
3694 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3696 [(set_attr "type" "alu1")
3697 (set_attr "mode" "<MODE>")])
3699 ;; When source and destination does not overlap, clear destination
3700 ;; first and then do the movb
3702 [(set (match_operand:SWI24 0 "register_operand" "")
3703 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3704 (clobber (reg:CC FLAGS_REG))]
3706 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3707 && ANY_QI_REG_P (operands[0])
3708 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3709 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3710 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3712 operands[2] = gen_lowpart (QImode, operands[0]);
3713 ix86_expand_clear (operands[0]);
3716 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3717 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3718 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3719 (clobber (reg:CC FLAGS_REG))]
3720 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3722 [(set_attr "type" "imovx,alu1")
3723 (set_attr "mode" "<MODE>")])
3725 ;; For the movzbl case strip only the clobber
3727 [(set (match_operand:SWI24 0 "register_operand" "")
3728 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))]
3731 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3732 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734 (zero_extend:SWI24 (match_dup 1)))])
3736 ; zero extend to SImode to avoid partial register stalls
3737 (define_insn "*zero_extendqi<mode>2_movzbl"
3738 [(set (match_operand:SWI24 0 "register_operand" "=r")
3739 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3741 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3742 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3743 [(set_attr "type" "imovx")
3744 (set_attr "mode" "SI")])
3746 ;; Rest is handled by single and.
3748 [(set (match_operand:SWI24 0 "register_operand" "")
3749 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3750 (clobber (reg:CC FLAGS_REG))]
3752 && true_regnum (operands[0]) == true_regnum (operands[1])"
3753 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3754 (clobber (reg:CC FLAGS_REG))])])
3756 ;; Sign extension instructions
3758 (define_expand "extendsidi2"
3759 [(set (match_operand:DI 0 "register_operand" "")
3760 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3765 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3770 (define_insn "*extendsidi2_rex64"
3771 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3772 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3776 movs{lq|x}\t{%1, %0|%0, %1}"
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "DI")
3779 (set_attr "prefix_0f" "0")
3780 (set_attr "modrm" "0,1")])
3782 (define_insn "extendsidi2_1"
3783 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3784 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3785 (clobber (reg:CC FLAGS_REG))
3786 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3790 ;; Extend to memory case when source register does die.
3792 [(set (match_operand:DI 0 "memory_operand" "")
3793 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3794 (clobber (reg:CC FLAGS_REG))
3795 (clobber (match_operand:SI 2 "register_operand" ""))]
3797 && dead_or_set_p (insn, operands[1])
3798 && !reg_mentioned_p (operands[1], operands[0]))"
3799 [(set (match_dup 3) (match_dup 1))
3800 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3801 (clobber (reg:CC FLAGS_REG))])
3802 (set (match_dup 4) (match_dup 1))]
3803 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3805 ;; Extend to memory case when source register does not die.
3807 [(set (match_operand:DI 0 "memory_operand" "")
3808 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3809 (clobber (reg:CC FLAGS_REG))
3810 (clobber (match_operand:SI 2 "register_operand" ""))]
3814 split_di (&operands[0], 1, &operands[3], &operands[4]);
3816 emit_move_insn (operands[3], operands[1]);
3818 /* Generate a cltd if possible and doing so it profitable. */
3819 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3820 && true_regnum (operands[1]) == AX_REG
3821 && true_regnum (operands[2]) == DX_REG)
3823 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3827 emit_move_insn (operands[2], operands[1]);
3828 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3830 emit_move_insn (operands[4], operands[2]);
3834 ;; Extend to register case. Optimize case where source and destination
3835 ;; registers match and cases where we can use cltd.
3837 [(set (match_operand:DI 0 "register_operand" "")
3838 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3839 (clobber (reg:CC FLAGS_REG))
3840 (clobber (match_scratch:SI 2 ""))]
3844 split_di (&operands[0], 1, &operands[3], &operands[4]);
3846 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3847 emit_move_insn (operands[3], operands[1]);
3849 /* Generate a cltd if possible and doing so it profitable. */
3850 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3851 && true_regnum (operands[3]) == AX_REG
3852 && true_regnum (operands[4]) == DX_REG)
3854 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3858 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3859 emit_move_insn (operands[4], operands[1]);
3861 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3865 (define_insn "extend<mode>di2"
3866 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3870 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3871 [(set_attr "type" "imovx")
3872 (set_attr "mode" "DI")])
3874 (define_insn "extendhisi2"
3875 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3876 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3879 switch (get_attr_prefix_0f (insn))
3882 return "{cwtl|cwde}";
3884 return "movs{wl|x}\t{%1, %0|%0, %1}";
3887 [(set_attr "type" "imovx")
3888 (set_attr "mode" "SI")
3889 (set (attr "prefix_0f")
3890 ;; movsx is short decodable while cwtl is vector decoded.
3891 (if_then_else (and (eq_attr "cpu" "!k6")
3892 (eq_attr "alternative" "0"))
3894 (const_string "1")))
3896 (if_then_else (eq_attr "prefix_0f" "0")
3898 (const_string "1")))])
3900 (define_insn "*extendhisi2_zext"
3901 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3904 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3907 switch (get_attr_prefix_0f (insn))
3910 return "{cwtl|cwde}";
3912 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3915 [(set_attr "type" "imovx")
3916 (set_attr "mode" "SI")
3917 (set (attr "prefix_0f")
3918 ;; movsx is short decodable while cwtl is vector decoded.
3919 (if_then_else (and (eq_attr "cpu" "!k6")
3920 (eq_attr "alternative" "0"))
3922 (const_string "1")))
3924 (if_then_else (eq_attr "prefix_0f" "0")
3926 (const_string "1")))])
3928 (define_insn "extendqisi2"
3929 [(set (match_operand:SI 0 "register_operand" "=r")
3930 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3932 "movs{bl|x}\t{%1, %0|%0, %1}"
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "SI")])
3936 (define_insn "*extendqisi2_zext"
3937 [(set (match_operand:DI 0 "register_operand" "=r")
3939 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3941 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3942 [(set_attr "type" "imovx")
3943 (set_attr "mode" "SI")])
3945 (define_insn "extendqihi2"
3946 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3947 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3950 switch (get_attr_prefix_0f (insn))
3953 return "{cbtw|cbw}";
3955 return "movs{bw|x}\t{%1, %0|%0, %1}";
3958 [(set_attr "type" "imovx")
3959 (set_attr "mode" "HI")
3960 (set (attr "prefix_0f")
3961 ;; movsx is short decodable while cwtl is vector decoded.
3962 (if_then_else (and (eq_attr "cpu" "!k6")
3963 (eq_attr "alternative" "0"))
3965 (const_string "1")))
3967 (if_then_else (eq_attr "prefix_0f" "0")
3969 (const_string "1")))])
3971 ;; Conversions between float and double.
3973 ;; These are all no-ops in the model used for the 80387.
3974 ;; So just emit moves.
3976 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3978 [(set (match_operand:DF 0 "push_operand" "")
3979 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3981 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3982 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3985 [(set (match_operand:XF 0 "push_operand" "")
3986 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3988 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3989 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3990 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3992 (define_expand "extendsfdf2"
3993 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3994 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3995 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3997 /* ??? Needed for compress_float_constant since all fp constants
3998 are LEGITIMATE_CONSTANT_P. */
3999 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4001 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4002 && standard_80387_constant_p (operands[1]) > 0)
4004 operands[1] = simplify_const_unary_operation
4005 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4006 emit_move_insn_1 (operands[0], operands[1]);
4009 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4013 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4015 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4017 We do the conversion post reload to avoid producing of 128bit spills
4018 that might lead to ICE on 32bit target. The sequence unlikely combine
4021 [(set (match_operand:DF 0 "register_operand" "")
4023 (match_operand:SF 1 "nonimmediate_operand" "")))]
4024 "TARGET_USE_VECTOR_FP_CONVERTS
4025 && optimize_insn_for_speed_p ()
4026 && reload_completed && SSE_REG_P (operands[0])"
4031 (parallel [(const_int 0) (const_int 1)]))))]
4033 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4034 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4035 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4036 Try to avoid move when unpacking can be done in source. */
4037 if (REG_P (operands[1]))
4039 /* If it is unsafe to overwrite upper half of source, we need
4040 to move to destination and unpack there. */
4041 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4042 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4043 && true_regnum (operands[0]) != true_regnum (operands[1]))
4045 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4046 emit_move_insn (tmp, operands[1]);
4049 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4050 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4054 emit_insn (gen_vec_setv4sf_0 (operands[3],
4055 CONST0_RTX (V4SFmode), operands[1]));
4058 (define_insn "*extendsfdf2_mixed"
4059 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4061 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4062 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4064 switch (which_alternative)
4068 return output_387_reg_move (insn, operands);
4071 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4077 [(set_attr "type" "fmov,fmov,ssecvt")
4078 (set_attr "prefix" "orig,orig,maybe_vex")
4079 (set_attr "mode" "SF,XF,DF")])
4081 (define_insn "*extendsfdf2_sse"
4082 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4083 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4084 "TARGET_SSE2 && TARGET_SSE_MATH"
4085 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4086 [(set_attr "type" "ssecvt")
4087 (set_attr "prefix" "maybe_vex")
4088 (set_attr "mode" "DF")])
4090 (define_insn "*extendsfdf2_i387"
4091 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4092 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4094 "* return output_387_reg_move (insn, operands);"
4095 [(set_attr "type" "fmov")
4096 (set_attr "mode" "SF,XF")])
4098 (define_expand "extend<mode>xf2"
4099 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4100 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4103 /* ??? Needed for compress_float_constant since all fp constants
4104 are LEGITIMATE_CONSTANT_P. */
4105 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4107 if (standard_80387_constant_p (operands[1]) > 0)
4109 operands[1] = simplify_const_unary_operation
4110 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4111 emit_move_insn_1 (operands[0], operands[1]);
4114 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4118 (define_insn "*extend<mode>xf2_i387"
4119 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4121 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4123 "* return output_387_reg_move (insn, operands);"
4124 [(set_attr "type" "fmov")
4125 (set_attr "mode" "<MODE>,XF")])
4127 ;; %%% This seems bad bad news.
4128 ;; This cannot output into an f-reg because there is no way to be sure
4129 ;; of truncating in that case. Otherwise this is just like a simple move
4130 ;; insn. So we pretend we can output to a reg in order to get better
4131 ;; register preferencing, but we really use a stack slot.
4133 ;; Conversion from DFmode to SFmode.
4135 (define_expand "truncdfsf2"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4138 (match_operand:DF 1 "nonimmediate_operand" "")))]
4139 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4141 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4143 else if (flag_unsafe_math_optimizations)
4147 enum ix86_stack_slot slot = (virtuals_instantiated
4150 rtx temp = assign_386_stack_local (SFmode, slot);
4151 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4156 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4158 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4160 We do the conversion post reload to avoid producing of 128bit spills
4161 that might lead to ICE on 32bit target. The sequence unlikely combine
4164 [(set (match_operand:SF 0 "register_operand" "")
4166 (match_operand:DF 1 "nonimmediate_operand" "")))]
4167 "TARGET_USE_VECTOR_FP_CONVERTS
4168 && optimize_insn_for_speed_p ()
4169 && reload_completed && SSE_REG_P (operands[0])"
4172 (float_truncate:V2SF
4176 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177 operands[3] = CONST0_RTX (V2SFmode);
4178 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179 /* Use movsd for loading from memory, unpcklpd for registers.
4180 Try to avoid move when unpacking can be done in source, or SSE3
4181 movddup is available. */
4182 if (REG_P (operands[1]))
4185 && true_regnum (operands[0]) != true_regnum (operands[1])
4186 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4189 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190 emit_move_insn (tmp, operands[1]);
4193 else if (!TARGET_SSE3)
4194 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 emit_insn (gen_sse2_loadlpd (operands[4],
4199 CONST0_RTX (V2DFmode), operands[1]));
4202 (define_expand "truncdfsf2_with_temp"
4203 [(parallel [(set (match_operand:SF 0 "" "")
4204 (float_truncate:SF (match_operand:DF 1 "" "")))
4205 (clobber (match_operand:SF 2 "" ""))])]
4208 (define_insn "*truncdfsf_fast_mixed"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4212 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 switch (which_alternative)
4217 return output_387_reg_move (insn, operands);
4219 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4224 [(set_attr "type" "fmov,ssecvt")
4225 (set_attr "prefix" "orig,maybe_vex")
4226 (set_attr "mode" "SF")])
4228 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4229 ;; because nothing we do here is unsafe.
4230 (define_insn "*truncdfsf_fast_sse"
4231 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4233 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4234 "TARGET_SSE2 && TARGET_SSE_MATH"
4235 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4236 [(set_attr "type" "ssecvt")
4237 (set_attr "prefix" "maybe_vex")
4238 (set_attr "mode" "SF")])
4240 (define_insn "*truncdfsf_fast_i387"
4241 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4243 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4244 "TARGET_80387 && flag_unsafe_math_optimizations"
4245 "* return output_387_reg_move (insn, operands);"
4246 [(set_attr "type" "fmov")
4247 (set_attr "mode" "SF")])
4249 (define_insn "*truncdfsf_mixed"
4250 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4252 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4253 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4254 "TARGET_MIX_SSE_I387"
4256 switch (which_alternative)
4259 return output_387_reg_move (insn, operands);
4261 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4267 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4268 (set_attr "unit" "*,*,i387,i387,i387")
4269 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4270 (set_attr "mode" "SF")])
4272 (define_insn "*truncdfsf_i387"
4273 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4275 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4276 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4279 switch (which_alternative)
4282 return output_387_reg_move (insn, operands);
4288 [(set_attr "type" "fmov,multi,multi,multi")
4289 (set_attr "unit" "*,i387,i387,i387")
4290 (set_attr "mode" "SF")])
4292 (define_insn "*truncdfsf2_i387_1"
4293 [(set (match_operand:SF 0 "memory_operand" "=m")
4295 (match_operand:DF 1 "register_operand" "f")))]
4297 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4298 && !TARGET_MIX_SSE_I387"
4299 "* return output_387_reg_move (insn, operands);"
4300 [(set_attr "type" "fmov")
4301 (set_attr "mode" "SF")])
4304 [(set (match_operand:SF 0 "register_operand" "")
4306 (match_operand:DF 1 "fp_register_operand" "")))
4307 (clobber (match_operand 2 "" ""))]
4309 [(set (match_dup 2) (match_dup 1))
4310 (set (match_dup 0) (match_dup 2))]
4311 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4313 ;; Conversion from XFmode to {SF,DF}mode
4315 (define_expand "truncxf<mode>2"
4316 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4317 (float_truncate:MODEF
4318 (match_operand:XF 1 "register_operand" "")))
4319 (clobber (match_dup 2))])]
4322 if (flag_unsafe_math_optimizations)
4324 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4325 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4326 if (reg != operands[0])
4327 emit_move_insn (operands[0], reg);
4332 enum ix86_stack_slot slot = (virtuals_instantiated
4335 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4339 (define_insn "*truncxfsf2_mixed"
4340 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4342 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4343 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4346 gcc_assert (!which_alternative);
4347 return output_387_reg_move (insn, operands);
4349 [(set_attr "type" "fmov,multi,multi,multi")
4350 (set_attr "unit" "*,i387,i387,i387")
4351 (set_attr "mode" "SF")])
4353 (define_insn "*truncxfdf2_mixed"
4354 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4356 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4357 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4360 gcc_assert (!which_alternative);
4361 return output_387_reg_move (insn, operands);
4363 [(set_attr "type" "fmov,multi,multi,multi")
4364 (set_attr "unit" "*,i387,i387,i387")
4365 (set_attr "mode" "DF")])
4367 (define_insn "truncxf<mode>2_i387_noop"
4368 [(set (match_operand:MODEF 0 "register_operand" "=f")
4369 (float_truncate:MODEF
4370 (match_operand:XF 1 "register_operand" "f")))]
4371 "TARGET_80387 && flag_unsafe_math_optimizations"
4372 "* return output_387_reg_move (insn, operands);"
4373 [(set_attr "type" "fmov")
4374 (set_attr "mode" "<MODE>")])
4376 (define_insn "*truncxf<mode>2_i387"
4377 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4378 (float_truncate:MODEF
4379 (match_operand:XF 1 "register_operand" "f")))]
4381 "* return output_387_reg_move (insn, operands);"
4382 [(set_attr "type" "fmov")
4383 (set_attr "mode" "<MODE>")])
4386 [(set (match_operand:MODEF 0 "register_operand" "")
4387 (float_truncate:MODEF
4388 (match_operand:XF 1 "register_operand" "")))
4389 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4390 "TARGET_80387 && reload_completed"
4391 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4392 (set (match_dup 0) (match_dup 2))])
4395 [(set (match_operand:MODEF 0 "memory_operand" "")
4396 (float_truncate:MODEF
4397 (match_operand:XF 1 "register_operand" "")))
4398 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4400 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4402 ;; Signed conversion to DImode.
4404 (define_expand "fix_truncxfdi2"
4405 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4406 (fix:DI (match_operand:XF 1 "register_operand" "")))
4407 (clobber (reg:CC FLAGS_REG))])]
4412 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4417 (define_expand "fix_trunc<mode>di2"
4418 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4419 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4420 (clobber (reg:CC FLAGS_REG))])]
4421 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4424 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4426 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4429 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4431 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4432 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4433 if (out != operands[0])
4434 emit_move_insn (operands[0], out);
4439 ;; Signed conversion to SImode.
4441 (define_expand "fix_truncxfsi2"
4442 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4443 (fix:SI (match_operand:XF 1 "register_operand" "")))
4444 (clobber (reg:CC FLAGS_REG))])]
4449 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4454 (define_expand "fix_trunc<mode>si2"
4455 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4456 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4457 (clobber (reg:CC FLAGS_REG))])]
4458 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4461 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4463 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4466 if (SSE_FLOAT_MODE_P (<MODE>mode))
4468 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4469 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4470 if (out != operands[0])
4471 emit_move_insn (operands[0], out);
4476 ;; Signed conversion to HImode.
4478 (define_expand "fix_trunc<mode>hi2"
4479 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4480 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4481 (clobber (reg:CC FLAGS_REG))])]
4483 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4492 ;; Unsigned conversion to SImode.
4494 (define_expand "fixuns_trunc<mode>si2"
4496 [(set (match_operand:SI 0 "register_operand" "")
4498 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4500 (clobber (match_scratch:<ssevecmode> 3 ""))
4501 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4502 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4504 enum machine_mode mode = <MODE>mode;
4505 enum machine_mode vecmode = <ssevecmode>mode;
4506 REAL_VALUE_TYPE TWO31r;
4509 if (optimize_insn_for_size_p ())
4512 real_ldexp (&TWO31r, &dconst1, 31);
4513 two31 = const_double_from_real_value (TWO31r, mode);
4514 two31 = ix86_build_const_vector (mode, true, two31);
4515 operands[2] = force_reg (vecmode, two31);
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4523 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4526 && optimize_function_for_speed_p (cfun)"
4528 "&& reload_completed"
4531 ix86_split_convert_uns_si_sse (operands);
4535 ;; Unsigned conversion to HImode.
4536 ;; Without these patterns, we'll try the unsigned SI conversion which
4537 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4539 (define_expand "fixuns_trunc<mode>hi2"
4541 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4542 (set (match_operand:HI 0 "nonimmediate_operand" "")
4543 (subreg:HI (match_dup 2) 0))]
4544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4545 "operands[2] = gen_reg_rtx (SImode);")
4547 ;; When SSE is available, it is always faster to use it!
4548 (define_insn "fix_trunc<mode>di_sse"
4549 [(set (match_operand:DI 0 "register_operand" "=r,r")
4550 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4551 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4552 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4553 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4554 [(set_attr "type" "sseicvt")
4555 (set_attr "prefix" "maybe_vex")
4556 (set_attr "prefix_rex" "1")
4557 (set_attr "mode" "<MODE>")
4558 (set_attr "athlon_decode" "double,vector")
4559 (set_attr "amdfam10_decode" "double,double")])
4561 (define_insn "fix_trunc<mode>si_sse"
4562 [(set (match_operand:SI 0 "register_operand" "=r,r")
4563 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4564 "SSE_FLOAT_MODE_P (<MODE>mode)
4565 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4566 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4567 [(set_attr "type" "sseicvt")
4568 (set_attr "prefix" "maybe_vex")
4569 (set_attr "mode" "<MODE>")
4570 (set_attr "athlon_decode" "double,vector")
4571 (set_attr "amdfam10_decode" "double,double")])
4573 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4575 [(set (match_operand:MODEF 0 "register_operand" "")
4576 (match_operand:MODEF 1 "memory_operand" ""))
4577 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4578 (fix:SSEMODEI24 (match_dup 0)))]
4579 "TARGET_SHORTEN_X87_SSE
4580 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4581 && peep2_reg_dead_p (2, operands[0])"
4582 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4584 ;; Avoid vector decoded forms of the instruction.
4586 [(match_scratch:DF 2 "Y2")
4587 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4588 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4589 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4590 [(set (match_dup 2) (match_dup 1))
4591 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4594 [(match_scratch:SF 2 "x")
4595 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4596 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4597 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4598 [(set (match_dup 2) (match_dup 1))
4599 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4601 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4602 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4603 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4604 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && (TARGET_64BIT || <MODE>mode != DImode))
4609 && can_create_pseudo_p ()"
4614 if (memory_operand (operands[0], VOIDmode))
4615 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4618 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4619 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4625 [(set_attr "type" "fisttp")
4626 (set_attr "mode" "<MODE>")])
4628 (define_insn "fix_trunc<mode>_i387_fisttp"
4629 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4630 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4631 (clobber (match_scratch:XF 2 "=&1f"))]
4632 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4635 && (TARGET_64BIT || <MODE>mode != DImode))
4636 && TARGET_SSE_MATH)"
4637 "* return output_fix_trunc (insn, operands, 1);"
4638 [(set_attr "type" "fisttp")
4639 (set_attr "mode" "<MODE>")])
4641 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4642 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4643 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4644 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4645 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4646 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4649 && (TARGET_64BIT || <MODE>mode != DImode))
4650 && TARGET_SSE_MATH)"
4652 [(set_attr "type" "fisttp")
4653 (set_attr "mode" "<MODE>")])
4656 [(set (match_operand:X87MODEI 0 "register_operand" "")
4657 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4658 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4659 (clobber (match_scratch 3 ""))]
4661 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4662 (clobber (match_dup 3))])
4663 (set (match_dup 0) (match_dup 2))])
4666 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4667 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4668 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4669 (clobber (match_scratch 3 ""))]
4671 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4672 (clobber (match_dup 3))])])
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682 (clobber (reg:CC FLAGS_REG))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && (TARGET_64BIT || <MODE>mode != DImode))
4687 && can_create_pseudo_p ()"
4692 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698 operands[2], operands[3]));
4701 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703 operands[2], operands[3],
4708 [(set_attr "type" "fistp")
4709 (set_attr "i387_cw" "trunc")
4710 (set_attr "mode" "<MODE>")])
4712 (define_insn "fix_truncdi_i387"
4713 [(set (match_operand:DI 0 "memory_operand" "=m")
4714 (fix:DI (match_operand 1 "register_operand" "f")))
4715 (use (match_operand:HI 2 "memory_operand" "m"))
4716 (use (match_operand:HI 3 "memory_operand" "m"))
4717 (clobber (match_scratch:XF 4 "=&1f"))]
4718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721 "* return output_fix_trunc (insn, operands, 0);"
4722 [(set_attr "type" "fistp")
4723 (set_attr "i387_cw" "trunc")
4724 (set_attr "mode" "DI")])
4726 (define_insn "fix_truncdi_i387_with_temp"
4727 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728 (fix:DI (match_operand 1 "register_operand" "f,f")))
4729 (use (match_operand:HI 2 "memory_operand" "m,m"))
4730 (use (match_operand:HI 3 "memory_operand" "m,m"))
4731 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 [(set_attr "type" "fistp")
4738 (set_attr "i387_cw" "trunc")
4739 (set_attr "mode" "DI")])
4742 [(set (match_operand:DI 0 "register_operand" "")
4743 (fix:DI (match_operand 1 "register_operand" "")))
4744 (use (match_operand:HI 2 "memory_operand" ""))
4745 (use (match_operand:HI 3 "memory_operand" ""))
4746 (clobber (match_operand:DI 4 "memory_operand" ""))
4747 (clobber (match_scratch 5 ""))]
4749 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4752 (clobber (match_dup 5))])
4753 (set (match_dup 0) (match_dup 4))])
4756 [(set (match_operand:DI 0 "memory_operand" "")
4757 (fix:DI (match_operand 1 "register_operand" "")))
4758 (use (match_operand:HI 2 "memory_operand" ""))
4759 (use (match_operand:HI 3 "memory_operand" ""))
4760 (clobber (match_operand:DI 4 "memory_operand" ""))
4761 (clobber (match_scratch 5 ""))]
4763 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4766 (clobber (match_dup 5))])])
4768 (define_insn "fix_trunc<mode>_i387"
4769 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4770 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4771 (use (match_operand:HI 2 "memory_operand" "m"))
4772 (use (match_operand:HI 3 "memory_operand" "m"))]
4773 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4775 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4776 "* return output_fix_trunc (insn, operands, 0);"
4777 [(set_attr "type" "fistp")
4778 (set_attr "i387_cw" "trunc")
4779 (set_attr "mode" "<MODE>")])
4781 (define_insn "fix_trunc<mode>_i387_with_temp"
4782 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4783 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4784 (use (match_operand:HI 2 "memory_operand" "m,m"))
4785 (use (match_operand:HI 3 "memory_operand" "m,m"))
4786 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4787 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4791 [(set_attr "type" "fistp")
4792 (set_attr "i387_cw" "trunc")
4793 (set_attr "mode" "<MODE>")])
4796 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4797 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4798 (use (match_operand:HI 2 "memory_operand" ""))
4799 (use (match_operand:HI 3 "memory_operand" ""))
4800 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4802 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4804 (use (match_dup 3))])
4805 (set (match_dup 0) (match_dup 4))])
4808 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4809 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4810 (use (match_operand:HI 2 "memory_operand" ""))
4811 (use (match_operand:HI 3 "memory_operand" ""))
4812 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4814 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4816 (use (match_dup 3))])])
4818 (define_insn "x86_fnstcw_1"
4819 [(set (match_operand:HI 0 "memory_operand" "=m")
4820 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4823 [(set (attr "length")
4824 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4825 (set_attr "mode" "HI")
4826 (set_attr "unit" "i387")])
4828 (define_insn "x86_fldcw_1"
4829 [(set (reg:HI FPCR_REG)
4830 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4833 [(set (attr "length")
4834 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4835 (set_attr "mode" "HI")
4836 (set_attr "unit" "i387")
4837 (set_attr "athlon_decode" "vector")
4838 (set_attr "amdfam10_decode" "vector")])
4840 ;; Conversion between fixed point and floating point.
4842 ;; Even though we only accept memory inputs, the backend _really_
4843 ;; wants to be able to do this between registers.
4845 (define_expand "floathi<mode>2"
4846 [(set (match_operand:X87MODEF 0 "register_operand" "")
4847 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4850 || TARGET_MIX_SSE_I387)"
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*floathi<mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand" "")
4856 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859 || TARGET_MIX_SSE_I387)
4860 && can_create_pseudo_p ()"
4863 [(parallel [(set (match_dup 0)
4864 (float:X87MODEF (match_dup 1)))
4865 (clobber (match_dup 2))])]
4866 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4868 (define_insn "*floathi<mode>2_i387_with_temp"
4869 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874 || TARGET_MIX_SSE_I387)"
4876 [(set_attr "type" "fmov,multi")
4877 (set_attr "mode" "<MODE>")
4878 (set_attr "unit" "*,i387")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floathi<mode>2_i387"
4882 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886 || TARGET_MIX_SSE_I387)"
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "<MODE>")
4890 (set_attr "fp_int_src" "true")])
4893 [(set (match_operand:X87MODEF 0 "register_operand" "")
4894 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895 (clobber (match_operand:HI 2 "memory_operand" ""))]
4897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898 || TARGET_MIX_SSE_I387)
4899 && reload_completed"
4900 [(set (match_dup 2) (match_dup 1))
4901 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4904 [(set (match_operand:X87MODEF 0 "register_operand" "")
4905 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906 (clobber (match_operand:HI 2 "memory_operand" ""))]
4908 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909 || TARGET_MIX_SSE_I387)
4910 && reload_completed"
4911 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4913 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914 [(set (match_operand:X87MODEF 0 "register_operand" "")
4916 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4918 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4921 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4925 rtx reg = gen_reg_rtx (XFmode);
4928 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4930 if (<X87MODEF:MODE>mode == SFmode)
4931 insn = gen_truncxfsf2 (operands[0], reg);
4932 else if (<X87MODEF:MODE>mode == DFmode)
4933 insn = gen_truncxfdf2 (operands[0], reg);
4942 ;; Pre-reload splitter to add memory clobber to the pattern.
4943 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944 [(set (match_operand:X87MODEF 0 "register_operand" "")
4945 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4947 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4948 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950 || TARGET_MIX_SSE_I387))
4951 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953 && ((<SSEMODEI24:MODE>mode == SImode
4954 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955 && optimize_function_for_speed_p (cfun)
4956 && flag_trapping_math)
4957 || !(TARGET_INTER_UNIT_CONVERSIONS
4958 || optimize_function_for_size_p (cfun)))))
4959 && can_create_pseudo_p ()"
4962 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963 (clobber (match_dup 2))])]
4965 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4967 /* Avoid store forwarding (partial memory) stall penalty
4968 by passing DImode value through XMM registers. */
4969 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4971 && optimize_function_for_speed_p (cfun))
4973 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4980 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4983 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4984 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4985 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4986 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4988 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4989 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4990 (set_attr "unit" "*,i387,*,*,*")
4991 (set_attr "athlon_decode" "*,*,double,direct,double")
4992 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4993 (set_attr "fp_int_src" "true")])
4995 (define_insn "*floatsi<mode>2_vector_mixed"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5003 [(set_attr "type" "fmov,sseicvt")
5004 (set_attr "mode" "<MODE>,<ssevecmode>")
5005 (set_attr "unit" "i387,*")
5006 (set_attr "athlon_decode" "*,direct")
5007 (set_attr "amdfam10_decode" "*,double")
5008 (set_attr "fp_int_src" "true")])
5010 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5013 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5014 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5015 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5018 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "unit" "*,i387,*,*")
5021 (set_attr "athlon_decode" "*,*,double,direct")
5022 (set_attr "amdfam10_decode" "*,*,vector,double")
5023 (set_attr "fp_int_src" "true")])
5026 [(set (match_operand:MODEF 0 "register_operand" "")
5027 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031 && TARGET_INTER_UNIT_CONVERSIONS
5033 && (SSE_REG_P (operands[0])
5034 || (GET_CODE (operands[0]) == SUBREG
5035 && SSE_REG_P (operands[0])))"
5036 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5039 [(set (match_operand:MODEF 0 "register_operand" "")
5040 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5046 && (SSE_REG_P (operands[0])
5047 || (GET_CODE (operands[0]) == SUBREG
5048 && SSE_REG_P (operands[0])))"
5049 [(set (match_dup 2) (match_dup 1))
5050 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5052 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5055 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5056 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5058 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5061 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5063 [(set_attr "type" "fmov,sseicvt,sseicvt")
5064 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5065 (set_attr "mode" "<MODEF:MODE>")
5066 (set (attr "prefix_rex")
5068 (and (eq_attr "prefix" "maybe_vex")
5069 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5071 (const_string "*")))
5072 (set_attr "unit" "i387,*,*")
5073 (set_attr "athlon_decode" "*,double,direct")
5074 (set_attr "amdfam10_decode" "*,vector,double")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5080 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5086 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5087 [(set_attr "type" "fmov,sseicvt")
5088 (set_attr "prefix" "orig,maybe_vex")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set (attr "prefix_rex")
5092 (and (eq_attr "prefix" "maybe_vex")
5093 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5095 (const_string "*")))
5096 (set_attr "athlon_decode" "*,direct")
5097 (set_attr "amdfam10_decode" "*,double")
5098 (set_attr "fp_int_src" "true")])
5100 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5103 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5104 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5105 "TARGET_SSE2 && TARGET_SSE_MATH
5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5108 [(set_attr "type" "sseicvt")
5109 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110 (set_attr "athlon_decode" "double,direct,double")
5111 (set_attr "amdfam10_decode" "vector,double,double")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*floatsi<mode>2_vector_sse"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5120 [(set_attr "type" "sseicvt")
5121 (set_attr "mode" "<MODE>")
5122 (set_attr "athlon_decode" "direct")
5123 (set_attr "amdfam10_decode" "double")
5124 (set_attr "fp_int_src" "true")])
5127 [(set (match_operand:MODEF 0 "register_operand" "")
5128 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129 (clobber (match_operand:SI 2 "memory_operand" ""))]
5130 "TARGET_SSE2 && TARGET_SSE_MATH
5131 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5133 && (SSE_REG_P (operands[0])
5134 || (GET_CODE (operands[0]) == SUBREG
5135 && SSE_REG_P (operands[0])))"
5138 rtx op1 = operands[1];
5140 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5142 if (GET_CODE (op1) == SUBREG)
5143 op1 = SUBREG_REG (op1);
5145 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5151 /* We can ignore possible trapping value in the
5152 high part of SSE register for non-trapping math. */
5153 else if (SSE_REG_P (op1) && !flag_trapping_math)
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5157 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158 emit_move_insn (operands[2], operands[1]);
5159 emit_insn (gen_sse2_loadld (operands[4],
5160 CONST0_RTX (V4SImode), operands[2]));
5163 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5168 [(set (match_operand:MODEF 0 "register_operand" "")
5169 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170 (clobber (match_operand:SI 2 "memory_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH
5172 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5174 && (SSE_REG_P (operands[0])
5175 || (GET_CODE (operands[0]) == SUBREG
5176 && SSE_REG_P (operands[0])))"
5179 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[1]));
5186 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5191 [(set (match_operand:MODEF 0 "register_operand" "")
5192 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193 "TARGET_SSE2 && TARGET_SSE_MATH
5194 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5196 && (SSE_REG_P (operands[0])
5197 || (GET_CODE (operands[0]) == SUBREG
5198 && SSE_REG_P (operands[0])))"
5201 rtx op1 = operands[1];
5203 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5205 if (GET_CODE (op1) == SUBREG)
5206 op1 = SUBREG_REG (op1);
5208 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5210 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211 emit_insn (gen_sse2_loadld (operands[4],
5212 CONST0_RTX (V4SImode), operands[1]));
5214 /* We can ignore possible trapping value in the
5215 high part of SSE register for non-trapping math. */
5216 else if (SSE_REG_P (op1) && !flag_trapping_math)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5221 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5226 [(set (match_operand:MODEF 0 "register_operand" "")
5227 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228 "TARGET_SSE2 && TARGET_SSE_MATH
5229 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5236 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5238 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5240 emit_insn (gen_sse2_loadld (operands[4],
5241 CONST0_RTX (V4SImode), operands[1]));
5243 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5247 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5250 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5251 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5252 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5255 [(set_attr "type" "sseicvt")
5256 (set_attr "mode" "<MODEF:MODE>")
5257 (set_attr "athlon_decode" "double,direct")
5258 (set_attr "amdfam10_decode" "vector,double")
5259 (set_attr "fp_int_src" "true")])
5261 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5267 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5268 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5269 [(set_attr "type" "sseicvt")
5270 (set_attr "prefix" "maybe_vex")
5271 (set_attr "mode" "<MODEF:MODE>")
5272 (set (attr "prefix_rex")
5274 (and (eq_attr "prefix" "maybe_vex")
5275 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5277 (const_string "*")))
5278 (set_attr "athlon_decode" "double,direct")
5279 (set_attr "amdfam10_decode" "vector,double")
5280 (set_attr "fp_int_src" "true")])
5283 [(set (match_operand:MODEF 0 "register_operand" "")
5284 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5288 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5290 && (SSE_REG_P (operands[0])
5291 || (GET_CODE (operands[0]) == SUBREG
5292 && SSE_REG_P (operands[0])))"
5293 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296 [(set (match_operand:MODEF 0 "register_operand" "=x")
5298 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303 [(set_attr "type" "sseicvt")
5304 (set_attr "prefix" "maybe_vex")
5305 (set_attr "mode" "<MODEF:MODE>")
5306 (set (attr "prefix_rex")
5308 (and (eq_attr "prefix" "maybe_vex")
5309 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5311 (const_string "*")))
5312 (set_attr "athlon_decode" "direct")
5313 (set_attr "amdfam10_decode" "double")
5314 (set_attr "fp_int_src" "true")])
5317 [(set (match_operand:MODEF 0 "register_operand" "")
5318 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5322 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5324 && (SSE_REG_P (operands[0])
5325 || (GET_CODE (operands[0]) == SUBREG
5326 && SSE_REG_P (operands[0])))"
5327 [(set (match_dup 2) (match_dup 1))
5328 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5331 [(set (match_operand:MODEF 0 "register_operand" "")
5332 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5337 && (SSE_REG_P (operands[0])
5338 || (GET_CODE (operands[0]) == SUBREG
5339 && SSE_REG_P (operands[0])))"
5340 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5342 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5345 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5346 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5348 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5352 [(set_attr "type" "fmov,multi")
5353 (set_attr "mode" "<X87MODEF:MODE>")
5354 (set_attr "unit" "*,i387")
5355 (set_attr "fp_int_src" "true")])
5357 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5360 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5362 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5364 [(set_attr "type" "fmov")
5365 (set_attr "mode" "<X87MODEF:MODE>")
5366 (set_attr "fp_int_src" "true")])
5369 [(set (match_operand:X87MODEF 0 "register_operand" "")
5370 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5373 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5375 && FP_REG_P (operands[0])"
5376 [(set (match_dup 2) (match_dup 1))
5377 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5384 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5386 && FP_REG_P (operands[0])"
5387 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5389 ;; Avoid store forwarding (partial memory) stall penalty
5390 ;; by passing DImode value through XMM registers. */
5392 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5395 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5396 (clobber (match_scratch:V4SI 3 "=X,x"))
5397 (clobber (match_scratch:V4SI 4 "=X,x"))
5398 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5399 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5401 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5403 [(set_attr "type" "multi")
5404 (set_attr "mode" "<X87MODEF:MODE>")
5405 (set_attr "unit" "i387")
5406 (set_attr "fp_int_src" "true")])
5409 [(set (match_operand:X87MODEF 0 "register_operand" "")
5410 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5411 (clobber (match_scratch:V4SI 3 ""))
5412 (clobber (match_scratch:V4SI 4 ""))
5413 (clobber (match_operand:DI 2 "memory_operand" ""))]
5414 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5418 && FP_REG_P (operands[0])"
5419 [(set (match_dup 2) (match_dup 3))
5420 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5422 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423 Assemble the 64-bit DImode value in an xmm register. */
5424 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425 gen_rtx_SUBREG (SImode, operands[1], 0)));
5426 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427 gen_rtx_SUBREG (SImode, operands[1], 4)));
5428 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5431 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5435 [(set (match_operand:X87MODEF 0 "register_operand" "")
5436 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5437 (clobber (match_scratch:V4SI 3 ""))
5438 (clobber (match_scratch:V4SI 4 ""))
5439 (clobber (match_operand:DI 2 "memory_operand" ""))]
5440 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5442 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5444 && FP_REG_P (operands[0])"
5445 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5447 ;; Avoid store forwarding (partial memory) stall penalty by extending
5448 ;; SImode value to DImode through XMM register instead of pushing two
5449 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450 ;; targets benefit from this optimization. Also note that fild
5451 ;; loads from memory only.
5453 (define_insn "*floatunssi<mode>2_1"
5454 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455 (unsigned_float:X87MODEF
5456 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458 (clobber (match_scratch:SI 3 "=X,x"))]
5460 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5463 [(set_attr "type" "multi")
5464 (set_attr "mode" "<MODE>")])
5467 [(set (match_operand:X87MODEF 0 "register_operand" "")
5468 (unsigned_float:X87MODEF
5469 (match_operand:SI 1 "register_operand" "")))
5470 (clobber (match_operand:DI 2 "memory_operand" ""))
5471 (clobber (match_scratch:SI 3 ""))]
5473 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5475 && reload_completed"
5476 [(set (match_dup 2) (match_dup 1))
5478 (float:X87MODEF (match_dup 2)))]
5479 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (unsigned_float:X87MODEF
5484 (match_operand:SI 1 "memory_operand" "")))
5485 (clobber (match_operand:DI 2 "memory_operand" ""))
5486 (clobber (match_scratch:SI 3 ""))]
5488 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5490 && reload_completed"
5491 [(set (match_dup 2) (match_dup 3))
5493 (float:X87MODEF (match_dup 2)))]
5495 emit_move_insn (operands[3], operands[1]);
5496 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5499 (define_expand "floatunssi<mode>2"
5501 [(set (match_operand:X87MODEF 0 "register_operand" "")
5502 (unsigned_float:X87MODEF
5503 (match_operand:SI 1 "nonimmediate_operand" "")))
5504 (clobber (match_dup 2))
5505 (clobber (match_scratch:SI 3 ""))])]
5507 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5509 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5511 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5513 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5518 enum ix86_stack_slot slot = (virtuals_instantiated
5521 operands[2] = assign_386_stack_local (DImode, slot);
5525 (define_expand "floatunsdisf2"
5526 [(use (match_operand:SF 0 "register_operand" ""))
5527 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5528 "TARGET_64BIT && TARGET_SSE_MATH"
5529 "x86_emit_floatuns (operands); DONE;")
5531 (define_expand "floatunsdidf2"
5532 [(use (match_operand:DF 0 "register_operand" ""))
5533 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5534 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535 && TARGET_SSE2 && TARGET_SSE_MATH"
5538 x86_emit_floatuns (operands);
5540 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5546 (define_expand "add<mode>3"
5547 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549 (match_operand:SDWIM 2 "<general_operand>" "")))]
5551 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5553 (define_insn_and_split "*add<dwi>3_doubleword"
5554 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5556 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5562 [(parallel [(set (reg:CC FLAGS_REG)
5563 (unspec:CC [(match_dup 1) (match_dup 2)]
5566 (plus:DWIH (match_dup 1) (match_dup 2)))])
5567 (parallel [(set (match_dup 3)
5571 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5573 (clobber (reg:CC FLAGS_REG))])]
5574 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5576 (define_insn "*add<mode>3_cc"
5577 [(set (reg:CC FLAGS_REG)
5579 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5582 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5586 [(set_attr "type" "alu")
5587 (set_attr "mode" "<MODE>")])
5589 (define_insn "addqi3_cc"
5590 [(set (reg:CC FLAGS_REG)
5592 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:QI 2 "general_operand" "qn,qm")]
5595 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596 (plus:QI (match_dup 1) (match_dup 2)))]
5597 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5598 "add{b}\t{%2, %0|%0, %2}"
5599 [(set_attr "type" "alu")
5600 (set_attr "mode" "QI")])
5602 (define_insn "*lea_1"
5603 [(set (match_operand:P 0 "register_operand" "=r")
5604 (match_operand:P 1 "no_seg_address_operand" "p"))]
5606 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5607 [(set_attr "type" "lea")
5608 (set_attr "mode" "<MODE>")])
5610 (define_insn "*lea_2"
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5614 "lea{l}\t{%a1, %0|%0, %a1}"
5615 [(set_attr "type" "lea")
5616 (set_attr "mode" "SI")])
5618 (define_insn "*lea_2_zext"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5621 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5623 "lea{l}\t{%a1, %k0|%k0, %a1}"
5624 [(set_attr "type" "lea")
5625 (set_attr "mode" "SI")])
5627 (define_insn "*add<mode>_1"
5628 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5630 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5635 switch (get_attr_type (insn))
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return "inc{<imodesuffix>}\t%0";
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return "dec{<imodesuffix>}\t%0";
5651 /* For most processors, ADD is faster than LEA. This alternative
5652 was added to use ADD as much as possible. */
5653 if (which_alternative == 2)
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5663 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5667 (cond [(eq_attr "alternative" "3")
5668 (const_string "lea")
5669 (match_operand:SWI48 2 "incdec_operand" "")
5670 (const_string "incdec")
5672 (const_string "alu")))
5673 (set (attr "length_immediate")
5675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5677 (const_string "*")))
5678 (set_attr "mode" "<MODE>")])
5680 ;; It may seem that nonimmediate operand is proper one for operand 1.
5681 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5682 ;; we take care in ix86_binary_operator_ok to not allow two memory
5683 ;; operands so proper swapping will be done in reload. This allow
5684 ;; patterns constructed from addsi_1 to match.
5686 (define_insn "*addsi_1_zext"
5687 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5689 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690 (match_operand:SI 2 "general_operand" "g,0,li"))))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5694 switch (get_attr_type (insn))
5700 if (operands[2] == const1_rtx)
5701 return "inc{l}\t%k0";
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{l}\t%k0";
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 1)
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717 if (x86_maybe_negate_const_int (&operands[2], SImode))
5718 return "sub{l}\t{%2, %k0|%k0, %2}";
5720 return "add{l}\t{%2, %k0|%k0, %2}";
5724 (cond [(eq_attr "alternative" "2")
5725 (const_string "lea")
5726 (match_operand:SI 2 "incdec_operand" "")
5727 (const_string "incdec")
5729 (const_string "alu")))
5730 (set (attr "length_immediate")
5732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5734 (const_string "*")))
5735 (set_attr "mode" "SI")])
5737 (define_insn "*addhi_1"
5738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740 (match_operand:HI 2 "general_operand" "rn,rm")))
5741 (clobber (reg:CC FLAGS_REG))]
5742 "TARGET_PARTIAL_REG_STALL
5743 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5745 switch (get_attr_type (insn))
5748 if (operands[2] == const1_rtx)
5749 return "inc{w}\t%0";
5752 gcc_assert (operands[2] == constm1_rtx);
5753 return "dec{w}\t%0";
5757 if (x86_maybe_negate_const_int (&operands[2], HImode))
5758 return "sub{w}\t{%2, %0|%0, %2}";
5760 return "add{w}\t{%2, %0|%0, %2}";
5764 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set (attr "length_immediate")
5769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5771 (const_string "*")))
5772 (set_attr "mode" "HI")])
5774 (define_insn "*addhi_1_lea"
5775 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "!TARGET_PARTIAL_REG_STALL
5780 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 switch (get_attr_type (insn))
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 if (operands[2] == const1_rtx)
5790 return "inc{w}\t%0";
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{w}\t%0";
5798 /* For most processors, ADD is faster than LEA. This alternative
5799 was added to use ADD as much as possible. */
5800 if (which_alternative == 2)
5803 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5807 if (x86_maybe_negate_const_int (&operands[2], HImode))
5808 return "sub{w}\t{%2, %0|%0, %2}";
5810 return "add{w}\t{%2, %0|%0, %2}";
5814 (cond [(eq_attr "alternative" "3")
5815 (const_string "lea")
5816 (match_operand:HI 2 "incdec_operand" "")
5817 (const_string "incdec")
5819 (const_string "alu")))
5820 (set (attr "length_immediate")
5822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5824 (const_string "*")))
5825 (set_attr "mode" "HI,HI,HI,SI")])
5827 ;; %%% Potential partial reg stall on alternative 2. What to do?
5828 (define_insn "*addqi_1"
5829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_PARTIAL_REG_STALL
5834 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5836 int widen = (which_alternative == 2);
5837 switch (get_attr_type (insn))
5840 if (operands[2] == const1_rtx)
5841 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5849 if (x86_maybe_negate_const_int (&operands[2], QImode))
5852 return "sub{l}\t{%2, %k0|%k0, %2}";
5854 return "sub{b}\t{%2, %0|%0, %2}";
5857 return "add{l}\t{%k2, %k0|%k0, %k2}";
5859 return "add{b}\t{%2, %0|%0, %2}";
5863 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set (attr "length_immediate")
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5870 (const_string "*")))
5871 (set_attr "mode" "QI,QI,SI")])
5873 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5874 (define_insn "*addqi_1_lea"
5875 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "!TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5882 int widen = (which_alternative == 3 || which_alternative == 4);
5884 switch (get_attr_type (insn))
5890 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5891 if (operands[2] == const1_rtx)
5892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5895 gcc_assert (operands[2] == constm1_rtx);
5896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5900 /* For most processors, ADD is faster than LEA. These alternatives
5901 were added to use ADD as much as possible. */
5902 if (which_alternative == 2 || which_alternative == 4)
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], QImode))
5912 return "sub{l}\t{%2, %k0|%k0, %2}";
5914 return "sub{b}\t{%2, %0|%0, %2}";
5917 return "add{l}\t{%k2, %k0|%k0, %k2}";
5919 return "add{b}\t{%2, %0|%0, %2}";
5923 (cond [(eq_attr "alternative" "5")
5924 (const_string "lea")
5925 (match_operand:QI 2 "incdec_operand" "")
5926 (const_string "incdec")
5928 (const_string "alu")))
5929 (set (attr "length_immediate")
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5933 (const_string "*")))
5934 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5936 (define_insn "*addqi_1_slp"
5937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938 (plus:QI (match_dup 0)
5939 (match_operand:QI 1 "general_operand" "qn,qnm")))
5940 (clobber (reg:CC FLAGS_REG))]
5941 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5944 switch (get_attr_type (insn))
5947 if (operands[1] == const1_rtx)
5948 return "inc{b}\t%0";
5951 gcc_assert (operands[1] == constm1_rtx);
5952 return "dec{b}\t%0";
5956 if (x86_maybe_negate_const_int (&operands[1], QImode))
5957 return "sub{b}\t{%1, %0|%0, %1}";
5959 return "add{b}\t{%1, %0|%0, %1}";
5963 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5964 (const_string "incdec")
5965 (const_string "alu1")))
5966 (set (attr "memory")
5967 (if_then_else (match_operand 1 "memory_operand" "")
5968 (const_string "load")
5969 (const_string "none")))
5970 (set_attr "mode" "QI")])
5972 ;; Convert lea to the lea pattern to avoid flags dependency.
5974 [(set (match_operand 0 "register_operand" "")
5975 (plus (match_operand 1 "register_operand" "")
5976 (match_operand 2 "nonmemory_operand" "")))
5977 (clobber (reg:CC FLAGS_REG))]
5978 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5982 enum machine_mode mode = GET_MODE (operands[0]);
5984 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985 may confuse gen_lowpart. */
5988 operands[1] = gen_lowpart (Pmode, operands[1]);
5989 operands[2] = gen_lowpart (Pmode, operands[2]);
5992 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5994 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995 operands[0] = gen_lowpart (SImode, operands[0]);
5997 if (TARGET_64BIT && mode != Pmode)
5998 pat = gen_rtx_SUBREG (SImode, pat, 0);
6000 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6004 ;; Convert lea to the lea pattern to avoid flags dependency.
6005 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6006 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6008 [(set (match_operand:DI 0 "register_operand" "")
6009 (plus:DI (match_operand:DI 1 "register_operand" "")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011 (clobber (reg:CC FLAGS_REG))]
6012 "TARGET_64BIT && reload_completed
6013 && true_regnum (operands[0]) != true_regnum (operands[1])"
6015 (plus:DI (match_dup 1) (match_dup 2)))])
6017 ;; Convert lea to the lea pattern to avoid flags dependency.
6019 [(set (match_operand:DI 0 "register_operand" "")
6021 (plus:SI (match_operand:SI 1 "register_operand" "")
6022 (match_operand:SI 2 "nonmemory_operand" ""))))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "TARGET_64BIT && reload_completed
6025 && ix86_lea_for_add_ok (insn, operands)"
6027 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6029 operands[1] = gen_lowpart (DImode, operands[1]);
6030 operands[2] = gen_lowpart (DImode, operands[2]);
6033 (define_insn "*add<mode>_2"
6034 [(set (reg FLAGS_REG)
6037 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041 (plus:SWI (match_dup 1) (match_dup 2)))]
6042 "ix86_match_ccmode (insn, CCGOCmode)
6043 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6045 switch (get_attr_type (insn))
6048 if (operands[2] == const1_rtx)
6049 return "inc{<imodesuffix>}\t%0";
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{<imodesuffix>}\t%0";
6057 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6060 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6064 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6065 (const_string "incdec")
6066 (const_string "alu")))
6067 (set (attr "length_immediate")
6069 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6071 (const_string "*")))
6072 (set_attr "mode" "<MODE>")])
6074 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075 (define_insn "*addsi_2_zext"
6076 [(set (reg FLAGS_REG)
6078 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079 (match_operand:SI 2 "general_operand" "g"))
6081 (set (match_operand:DI 0 "register_operand" "=r")
6082 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6084 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6086 switch (get_attr_type (insn))
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6093 gcc_assert (operands[2] == constm1_rtx);
6094 return "dec{l}\t%k0";
6098 if (x86_maybe_negate_const_int (&operands[2], SImode))
6099 return "sub{l}\t{%2, %k0|%k0, %2}";
6101 return "add{l}\t{%2, %k0|%k0, %2}";
6105 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6112 (const_string "*")))
6113 (set_attr "mode" "SI")])
6115 (define_insn "*add<mode>_3"
6116 [(set (reg FLAGS_REG)
6118 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120 (clobber (match_scratch:SWI 0 "=<r>"))]
6121 "ix86_match_ccmode (insn, CCZmode)
6122 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6124 switch (get_attr_type (insn))
6127 if (operands[2] == const1_rtx)
6128 return "inc{<imodesuffix>}\t%0";
6131 gcc_assert (operands[2] == constm1_rtx);
6132 return "dec{<imodesuffix>}\t%0";
6136 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6139 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6143 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6150 (const_string "*")))
6151 (set_attr "mode" "<MODE>")])
6153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154 (define_insn "*addsi_3_zext"
6155 [(set (reg FLAGS_REG)
6157 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159 (set (match_operand:DI 0 "register_operand" "=r")
6160 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6162 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6164 switch (get_attr_type (insn))
6167 if (operands[2] == const1_rtx)
6168 return "inc{l}\t%k0";
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{l}\t%k0";
6176 if (x86_maybe_negate_const_int (&operands[2], SImode))
6177 return "sub{l}\t{%2, %k0|%k0, %2}";
6179 return "add{l}\t{%2, %k0|%k0, %2}";
6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set (attr "length_immediate")
6188 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6190 (const_string "*")))
6191 (set_attr "mode" "SI")])
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6195 ; is matched then. We can't accept general immediate, because for
6196 ; case of overflows, the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6200 (define_insn "*adddi_4"
6201 [(set (reg FLAGS_REG)
6203 (match_operand:DI 1 "nonimmediate_operand" "0")
6204 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205 (clobber (match_scratch:DI 0 "=rm"))]
6207 && ix86_match_ccmode (insn, CCGCmode)"
6209 switch (get_attr_type (insn))
6212 if (operands[2] == constm1_rtx)
6213 return "inc{q}\t%0";
6216 gcc_assert (operands[2] == const1_rtx);
6217 return "dec{q}\t%0";
6221 if (x86_maybe_negate_const_int (&operands[2], DImode))
6222 return "add{q}\t{%2, %0|%0, %2}";
6224 return "sub{q}\t{%2, %0|%0, %2}";
6228 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
6231 (set (attr "length_immediate")
6233 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6235 (const_string "*")))
6236 (set_attr "mode" "DI")])
6238 ; For comparisons against 1, -1 and 128, we may generate better code
6239 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6240 ; is matched then. We can't accept general immediate, because for
6241 ; case of overflows, the result is messed up.
6242 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6243 ; only for comparisons not depending on it.
6245 (define_insn "*add<mode>_4"
6246 [(set (reg FLAGS_REG)
6248 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249 (match_operand:SWI124 2 "const_int_operand" "n")))
6250 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6251 "ix86_match_ccmode (insn, CCGCmode)"
6253 switch (get_attr_type (insn))
6256 if (operands[2] == constm1_rtx)
6257 return "inc{<imodesuffix>}\t%0";
6260 gcc_assert (operands[2] == const1_rtx);
6261 return "dec{<imodesuffix>}\t%0";
6265 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6268 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6272 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set (attr "length_immediate")
6277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6279 (const_string "*")))
6280 (set_attr "mode" "<MODE>")])
6282 (define_insn "*add<mode>_5"
6283 [(set (reg FLAGS_REG)
6286 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287 (match_operand:SWI 2 "<general_operand>" "<g>"))
6289 (clobber (match_scratch:SWI 0 "=<r>"))]
6290 "ix86_match_ccmode (insn, CCGOCmode)
6291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6293 switch (get_attr_type (insn))
6296 if (operands[2] == const1_rtx)
6297 return "inc{<imodesuffix>}\t%0";
6300 gcc_assert (operands[2] == constm1_rtx);
6301 return "dec{<imodesuffix>}\t%0";
6305 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6308 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6312 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set (attr "length_immediate")
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6319 (const_string "*")))
6320 (set_attr "mode" "<MODE>")])
6322 (define_insn "*addqi_ext_1_rex64"
6323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6328 (match_operand 1 "ext_register_operand" "0")
6331 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6332 (clobber (reg:CC FLAGS_REG))]
6335 switch (get_attr_type (insn))
6338 if (operands[2] == const1_rtx)
6339 return "inc{b}\t%h0";
6342 gcc_assert (operands[2] == constm1_rtx);
6343 return "dec{b}\t%h0";
6347 return "add{b}\t{%2, %h0|%h0, %2}";
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "modrm" "1")
6355 (set_attr "mode" "QI")])
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363 (match_operand 1 "ext_register_operand" "0")
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6370 switch (get_attr_type (insn))
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{b}\t%h0";
6382 return "add{b}\t{%2, %h0|%h0, %2}";
6386 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set_attr "modrm" "1")
6390 (set_attr "mode" "QI")])
6392 (define_insn "*addqi_ext_2"
6393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398 (match_operand 1 "ext_register_operand" "%0")
6402 (match_operand 2 "ext_register_operand" "Q")
6405 (clobber (reg:CC FLAGS_REG))]
6407 "add{b}\t{%h2, %h0|%h0, %h2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "QI")])
6411 ;; The lea patterns for non-Pmodes needs to be matched by
6412 ;; several insns converted to real lea by splitters.
6414 (define_insn_and_split "*lea_general_1"
6415 [(set (match_operand 0 "register_operand" "=r")
6416 (plus (plus (match_operand 1 "index_register_operand" "l")
6417 (match_operand 2 "register_operand" "r"))
6418 (match_operand 3 "immediate_operand" "i")))]
6419 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425 || GET_MODE (operands[3]) == VOIDmode)"
6427 "&& reload_completed"
6431 operands[0] = gen_lowpart (SImode, operands[0]);
6432 operands[1] = gen_lowpart (Pmode, operands[1]);
6433 operands[2] = gen_lowpart (Pmode, operands[2]);
6434 operands[3] = gen_lowpart (Pmode, operands[3]);
6435 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6437 if (Pmode != SImode)
6438 pat = gen_rtx_SUBREG (SImode, pat, 0);
6439 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6442 [(set_attr "type" "lea")
6443 (set_attr "mode" "SI")])
6445 (define_insn_and_split "*lea_general_1_zext"
6446 [(set (match_operand:DI 0 "register_operand" "=r")
6449 (match_operand:SI 1 "index_register_operand" "l")
6450 (match_operand:SI 2 "register_operand" "r"))
6451 (match_operand:SI 3 "immediate_operand" "i"))))]
6454 "&& reload_completed"
6456 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6458 (match_dup 3)) 0)))]
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[2] = gen_lowpart (Pmode, operands[2]);
6462 operands[3] = gen_lowpart (Pmode, operands[3]);
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6467 (define_insn_and_split "*lea_general_2"
6468 [(set (match_operand 0 "register_operand" "=r")
6469 (plus (mult (match_operand 1 "index_register_operand" "l")
6470 (match_operand 2 "const248_operand" "i"))
6471 (match_operand 3 "nonmemory_operand" "ri")))]
6472 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477 || GET_MODE (operands[3]) == VOIDmode)"
6479 "&& reload_completed"
6483 operands[0] = gen_lowpart (SImode, operands[0]);
6484 operands[1] = gen_lowpart (Pmode, operands[1]);
6485 operands[3] = gen_lowpart (Pmode, operands[3]);
6486 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6488 if (Pmode != SImode)
6489 pat = gen_rtx_SUBREG (SImode, pat, 0);
6490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6493 [(set_attr "type" "lea")
6494 (set_attr "mode" "SI")])
6496 (define_insn_and_split "*lea_general_2_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6500 (match_operand:SI 1 "index_register_operand" "l")
6501 (match_operand:SI 2 "const248_operand" "n"))
6502 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6505 "&& reload_completed"
6507 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6509 (match_dup 3)) 0)))]
6511 operands[1] = gen_lowpart (Pmode, operands[1]);
6512 operands[3] = gen_lowpart (Pmode, operands[3]);
6514 [(set_attr "type" "lea")
6515 (set_attr "mode" "SI")])
6517 (define_insn_and_split "*lea_general_3"
6518 [(set (match_operand 0 "register_operand" "=r")
6519 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520 (match_operand 2 "const248_operand" "i"))
6521 (match_operand 3 "register_operand" "r"))
6522 (match_operand 4 "immediate_operand" "i")))]
6523 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6529 "&& reload_completed"
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (Pmode, operands[1]);
6535 operands[3] = gen_lowpart (Pmode, operands[3]);
6536 operands[4] = gen_lowpart (Pmode, operands[4]);
6537 pat = gen_rtx_PLUS (Pmode,
6538 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6542 if (Pmode != SImode)
6543 pat = gen_rtx_SUBREG (SImode, pat, 0);
6544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6547 [(set_attr "type" "lea")
6548 (set_attr "mode" "SI")])
6550 (define_insn_and_split "*lea_general_3_zext"
6551 [(set (match_operand:DI 0 "register_operand" "=r")
6555 (match_operand:SI 1 "index_register_operand" "l")
6556 (match_operand:SI 2 "const248_operand" "n"))
6557 (match_operand:SI 3 "register_operand" "r"))
6558 (match_operand:SI 4 "immediate_operand" "i"))))]
6561 "&& reload_completed"
6563 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6566 (match_dup 4)) 0)))]
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 operands[4] = gen_lowpart (Pmode, operands[4]);
6572 [(set_attr "type" "lea")
6573 (set_attr "mode" "SI")])
6575 ;; Subtract instructions
6577 (define_expand "sub<mode>3"
6578 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580 (match_operand:SDWIM 2 "<general_operand>" "")))]
6582 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6584 (define_insn_and_split "*sub<dwi>3_doubleword"
6585 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6587 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6589 (clobber (reg:CC FLAGS_REG))]
6590 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6593 [(parallel [(set (reg:CC FLAGS_REG)
6594 (compare:CC (match_dup 1) (match_dup 2)))
6596 (minus:DWIH (match_dup 1) (match_dup 2)))])
6597 (parallel [(set (match_dup 3)
6601 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6603 (clobber (reg:CC FLAGS_REG))])]
6604 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6606 (define_insn "*sub<mode>_1"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6609 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "mode" "<MODE>")])
6617 (define_insn "*subsi_1_zext"
6618 [(set (match_operand:DI 0 "register_operand" "=r")
6620 (minus:SI (match_operand:SI 1 "register_operand" "0")
6621 (match_operand:SI 2 "general_operand" "g"))))
6622 (clobber (reg:CC FLAGS_REG))]
6623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624 "sub{l}\t{%2, %k0|%k0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "SI")])
6628 (define_insn "*subqi_1_slp"
6629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630 (minus:QI (match_dup 0)
6631 (match_operand:QI 1 "general_operand" "qn,qm")))
6632 (clobber (reg:CC FLAGS_REG))]
6633 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635 "sub{b}\t{%1, %0|%0, %1}"
6636 [(set_attr "type" "alu1")
6637 (set_attr "mode" "QI")])
6639 (define_insn "*sub<mode>_2"
6640 [(set (reg FLAGS_REG)
6643 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6646 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647 (minus:SWI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "g"))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6662 (minus:SI (match_dup 1)
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6670 (define_insn "*sub<mode>_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675 (minus:SWI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "g")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6688 (minus:SI (match_dup 1)
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{l}\t{%2, %1|%1, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "SI")])
6696 ;; Add with carry and subtract with borrow
6698 (define_expand "<plusminus_insn><mode>3_carry"
6700 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6702 (match_operand:SWI 1 "nonimmediate_operand" "")
6703 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704 [(match_operand 3 "flags_reg_operand" "")
6706 (match_operand:SWI 2 "<general_operand>" ""))))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6711 (define_insn "*<plusminus_insn><mode>3_carry"
6712 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6714 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6716 (match_operator 3 "ix86_carry_flag_operator"
6717 [(reg FLAGS_REG) (const_int 0)])
6718 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6719 (clobber (reg:CC FLAGS_REG))]
6720 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6721 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "use_carry" "1")
6724 (set_attr "pent_pair" "pu")
6725 (set_attr "mode" "<MODE>")])
6727 (define_insn "*addsi3_carry_zext"
6728 [(set (match_operand:DI 0 "register_operand" "=r")
6730 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6731 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6732 [(reg FLAGS_REG) (const_int 0)])
6733 (match_operand:SI 2 "general_operand" "g")))))
6734 (clobber (reg:CC FLAGS_REG))]
6735 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6736 "adc{l}\t{%2, %k0|%k0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "use_carry" "1")
6739 (set_attr "pent_pair" "pu")
6740 (set_attr "mode" "SI")])
6742 (define_insn "*subsi3_carry_zext"
6743 [(set (match_operand:DI 0 "register_operand" "=r")
6745 (minus:SI (match_operand:SI 1 "register_operand" "0")
6746 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6747 [(reg FLAGS_REG) (const_int 0)])
6748 (match_operand:SI 2 "general_operand" "g")))))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751 "sbb{l}\t{%2, %k0|%k0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "pent_pair" "pu")
6754 (set_attr "mode" "SI")])
6756 ;; Overflow setting add and subtract instructions
6758 (define_insn "*add<mode>3_cconly_overflow"
6759 [(set (reg:CCC FLAGS_REG)
6762 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6763 (match_operand:SWI 2 "<general_operand>" "<g>"))
6765 (clobber (match_scratch:SWI 0 "=<r>"))]
6766 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6768 [(set_attr "type" "alu")
6769 (set_attr "mode" "<MODE>")])
6771 (define_insn "*sub<mode>3_cconly_overflow"
6772 [(set (reg:CCC FLAGS_REG)
6775 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6776 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6779 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6780 [(set_attr "type" "icmp")
6781 (set_attr "mode" "<MODE>")])
6783 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6784 [(set (reg:CCC FLAGS_REG)
6787 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6788 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6790 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6791 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6792 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6793 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "<MODE>")])
6797 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6798 [(set (reg:CCC FLAGS_REG)
6801 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6802 (match_operand:SI 2 "general_operand" "g"))
6804 (set (match_operand:DI 0 "register_operand" "=r")
6805 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6806 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6807 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6808 [(set_attr "type" "alu")
6809 (set_attr "mode" "SI")])
6811 ;; The patterns that match these are at the end of this file.
6813 (define_expand "<plusminus_insn>xf3"
6814 [(set (match_operand:XF 0 "register_operand" "")
6816 (match_operand:XF 1 "register_operand" "")
6817 (match_operand:XF 2 "register_operand" "")))]
6821 (define_expand "<plusminus_insn><mode>3"
6822 [(set (match_operand:MODEF 0 "register_operand" "")
6824 (match_operand:MODEF 1 "register_operand" "")
6825 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6826 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6827 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6830 ;; Multiply instructions
6832 (define_expand "mul<mode>3"
6833 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6835 (match_operand:SWIM248 1 "register_operand" "")
6836 (match_operand:SWIM248 2 "<general_operand>" "")))
6837 (clobber (reg:CC FLAGS_REG))])]
6841 (define_expand "mulqi3"
6842 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6844 (match_operand:QI 1 "register_operand" "")
6845 (match_operand:QI 2 "nonimmediate_operand" "")))
6846 (clobber (reg:CC FLAGS_REG))])]
6847 "TARGET_QIMODE_MATH"
6851 ;; IMUL reg32/64, reg32/64, imm8 Direct
6852 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6853 ;; IMUL reg32/64, reg32/64, imm32 Direct
6854 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6855 ;; IMUL reg32/64, reg32/64 Direct
6856 ;; IMUL reg32/64, mem32/64 Direct
6858 (define_insn "*mul<mode>3_1"
6859 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6861 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6862 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6863 (clobber (reg:CC FLAGS_REG))]
6864 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6867 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6868 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6869 [(set_attr "type" "imul")
6870 (set_attr "prefix_0f" "0,0,1")
6871 (set (attr "athlon_decode")
6872 (cond [(eq_attr "cpu" "athlon")
6873 (const_string "vector")
6874 (eq_attr "alternative" "1")
6875 (const_string "vector")
6876 (and (eq_attr "alternative" "2")
6877 (match_operand 1 "memory_operand" ""))
6878 (const_string "vector")]
6879 (const_string "direct")))
6880 (set (attr "amdfam10_decode")
6881 (cond [(and (eq_attr "alternative" "0,1")
6882 (match_operand 1 "memory_operand" ""))
6883 (const_string "vector")]
6884 (const_string "direct")))
6885 (set_attr "mode" "<MODE>")])
6887 (define_insn "*mulsi3_1_zext"
6888 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6890 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6892 (clobber (reg:CC FLAGS_REG))]
6894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6896 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6897 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6898 imul{l}\t{%2, %k0|%k0, %2}"
6899 [(set_attr "type" "imul")
6900 (set_attr "prefix_0f" "0,0,1")
6901 (set (attr "athlon_decode")
6902 (cond [(eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (eq_attr "alternative" "1")
6905 (const_string "vector")
6906 (and (eq_attr "alternative" "2")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set (attr "amdfam10_decode")
6911 (cond [(and (eq_attr "alternative" "0,1")
6912 (match_operand 1 "memory_operand" ""))
6913 (const_string "vector")]
6914 (const_string "direct")))
6915 (set_attr "mode" "SI")])
6918 ;; IMUL reg16, reg16, imm8 VectorPath
6919 ;; IMUL reg16, mem16, imm8 VectorPath
6920 ;; IMUL reg16, reg16, imm16 VectorPath
6921 ;; IMUL reg16, mem16, imm16 VectorPath
6922 ;; IMUL reg16, reg16 Direct
6923 ;; IMUL reg16, mem16 Direct
6925 (define_insn "*mulhi3_1"
6926 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6927 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6928 (match_operand:HI 2 "general_operand" "K,n,mr")))
6929 (clobber (reg:CC FLAGS_REG))]
6931 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6933 imul{w}\t{%2, %1, %0|%0, %1, %2}
6934 imul{w}\t{%2, %1, %0|%0, %1, %2}
6935 imul{w}\t{%2, %0|%0, %2}"
6936 [(set_attr "type" "imul")
6937 (set_attr "prefix_0f" "0,0,1")
6938 (set (attr "athlon_decode")
6939 (cond [(eq_attr "cpu" "athlon")
6940 (const_string "vector")
6941 (eq_attr "alternative" "1,2")
6942 (const_string "vector")]
6943 (const_string "direct")))
6944 (set (attr "amdfam10_decode")
6945 (cond [(eq_attr "alternative" "0,1")
6946 (const_string "vector")]
6947 (const_string "direct")))
6948 (set_attr "mode" "HI")])
6954 (define_insn "*mulqi3_1"
6955 [(set (match_operand:QI 0 "register_operand" "=a")
6956 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6957 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6958 (clobber (reg:CC FLAGS_REG))]
6960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 [(set_attr "type" "imul")
6963 (set_attr "length_immediate" "0")
6964 (set (attr "athlon_decode")
6965 (if_then_else (eq_attr "cpu" "athlon")
6966 (const_string "vector")
6967 (const_string "direct")))
6968 (set_attr "amdfam10_decode" "direct")
6969 (set_attr "mode" "QI")])
6971 (define_expand "<u>mul<mode><dwi>3"
6972 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6975 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6977 (match_operand:DWIH 2 "register_operand" ""))))
6978 (clobber (reg:CC FLAGS_REG))])]
6982 (define_expand "<u>mulqihi3"
6983 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6986 (match_operand:QI 1 "nonimmediate_operand" ""))
6988 (match_operand:QI 2 "register_operand" ""))))
6989 (clobber (reg:CC FLAGS_REG))])]
6990 "TARGET_QIMODE_MATH"
6993 (define_insn "*<u>mul<mode><dwi>3_1"
6994 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6997 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6999 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7000 (clobber (reg:CC FLAGS_REG))]
7001 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 "<sgnprefix>mul{<imodesuffix>}\t%2"
7003 [(set_attr "type" "imul")
7004 (set_attr "length_immediate" "0")
7005 (set (attr "athlon_decode")
7006 (if_then_else (eq_attr "cpu" "athlon")
7007 (const_string "vector")
7008 (const_string "double")))
7009 (set_attr "amdfam10_decode" "double")
7010 (set_attr "mode" "<MODE>")])
7012 (define_insn "*<u>mulqihi3_1"
7013 [(set (match_operand:HI 0 "register_operand" "=a")
7016 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7018 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7019 (clobber (reg:CC FLAGS_REG))]
7021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022 "<sgnprefix>mul{b}\t%2"
7023 [(set_attr "type" "imul")
7024 (set_attr "length_immediate" "0")
7025 (set (attr "athlon_decode")
7026 (if_then_else (eq_attr "cpu" "athlon")
7027 (const_string "vector")
7028 (const_string "direct")))
7029 (set_attr "amdfam10_decode" "direct")
7030 (set_attr "mode" "QI")])
7032 (define_expand "<s>mul<mode>3_highpart"
7033 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7038 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7040 (match_operand:SWI48 2 "register_operand" "")))
7042 (clobber (match_scratch:SWI48 3 ""))
7043 (clobber (reg:CC FLAGS_REG))])]
7045 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7047 (define_insn "*<s>muldi3_highpart_1"
7048 [(set (match_operand:DI 0 "register_operand" "=d")
7053 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7055 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7057 (clobber (match_scratch:DI 3 "=1"))
7058 (clobber (reg:CC FLAGS_REG))]
7060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061 "<sgnprefix>mul{q}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "double")))
7068 (set_attr "amdfam10_decode" "double")
7069 (set_attr "mode" "DI")])
7071 (define_insn "*<s>mulsi3_highpart_1"
7072 [(set (match_operand:SI 0 "register_operand" "=d")
7077 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7079 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7081 (clobber (match_scratch:SI 3 "=1"))
7082 (clobber (reg:CC FLAGS_REG))]
7083 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7084 "<sgnprefix>mul{l}\t%2"
7085 [(set_attr "type" "imul")
7086 (set_attr "length_immediate" "0")
7087 (set (attr "athlon_decode")
7088 (if_then_else (eq_attr "cpu" "athlon")
7089 (const_string "vector")
7090 (const_string "double")))
7091 (set_attr "amdfam10_decode" "double")
7092 (set_attr "mode" "SI")])
7094 (define_insn "*<s>mulsi3_highpart_zext"
7095 [(set (match_operand:DI 0 "register_operand" "=d")
7096 (zero_extend:DI (truncate:SI
7098 (mult:DI (any_extend:DI
7099 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7101 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7103 (clobber (match_scratch:SI 3 "=1"))
7104 (clobber (reg:CC FLAGS_REG))]
7106 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7107 "<sgnprefix>mul{l}\t%2"
7108 [(set_attr "type" "imul")
7109 (set_attr "length_immediate" "0")
7110 (set (attr "athlon_decode")
7111 (if_then_else (eq_attr "cpu" "athlon")
7112 (const_string "vector")
7113 (const_string "double")))
7114 (set_attr "amdfam10_decode" "double")
7115 (set_attr "mode" "SI")])
7117 ;; The patterns that match these are at the end of this file.
7119 (define_expand "mulxf3"
7120 [(set (match_operand:XF 0 "register_operand" "")
7121 (mult:XF (match_operand:XF 1 "register_operand" "")
7122 (match_operand:XF 2 "register_operand" "")))]
7126 (define_expand "mul<mode>3"
7127 [(set (match_operand:MODEF 0 "register_operand" "")
7128 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7129 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7130 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7131 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7134 ;; Divide instructions
7136 ;; The patterns that match these are at the end of this file.
7138 (define_expand "divxf3"
7139 [(set (match_operand:XF 0 "register_operand" "")
7140 (div:XF (match_operand:XF 1 "register_operand" "")
7141 (match_operand:XF 2 "register_operand" "")))]
7145 (define_expand "divdf3"
7146 [(set (match_operand:DF 0 "register_operand" "")
7147 (div:DF (match_operand:DF 1 "register_operand" "")
7148 (match_operand:DF 2 "nonimmediate_operand" "")))]
7149 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7150 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7153 (define_expand "divsf3"
7154 [(set (match_operand:SF 0 "register_operand" "")
7155 (div:SF (match_operand:SF 1 "register_operand" "")
7156 (match_operand:SF 2 "nonimmediate_operand" "")))]
7157 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7160 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7161 && flag_finite_math_only && !flag_trapping_math
7162 && flag_unsafe_math_optimizations)
7164 ix86_emit_swdivsf (operands[0], operands[1],
7165 operands[2], SFmode);
7170 ;; Divmod instructions.
7172 (define_expand "divmodqi4"
7173 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7175 (match_operand:QI 1 "register_operand" "")
7176 (match_operand:QI 2 "nonimmediate_operand" "")))
7177 (set (match_operand:QI 3 "register_operand" "")
7178 (mod:QI (match_dup 1) (match_dup 2)))
7179 (clobber (reg:CC FLAGS_REG))])]
7180 "TARGET_QIMODE_MATH"
7185 tmp0 = gen_reg_rtx (HImode);
7186 tmp1 = gen_reg_rtx (HImode);
7188 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7190 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193 /* Extract remainder from AH. */
7194 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195 insn = emit_move_insn (operands[3], tmp1);
7197 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198 set_unique_reg_note (insn, REG_EQUAL, mod);
7200 /* Extract quotient from AL. */
7201 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204 set_unique_reg_note (insn, REG_EQUAL, div);
7209 (define_expand "udivmodqi4"
7210 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7212 (match_operand:QI 1 "register_operand" "")
7213 (match_operand:QI 2 "nonimmediate_operand" "")))
7214 (set (match_operand:QI 3 "register_operand" "")
7215 (umod:QI (match_dup 1) (match_dup 2)))
7216 (clobber (reg:CC FLAGS_REG))])]
7217 "TARGET_QIMODE_MATH"
7222 tmp0 = gen_reg_rtx (HImode);
7223 tmp1 = gen_reg_rtx (HImode);
7225 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7227 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7228 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7230 /* Extract remainder from AH. */
7231 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7232 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7233 insn = emit_move_insn (operands[3], tmp1);
7235 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7236 set_unique_reg_note (insn, REG_EQUAL, mod);
7238 /* Extract quotient from AL. */
7239 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7241 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7242 set_unique_reg_note (insn, REG_EQUAL, div);
7247 ;; Divide AX by r/m8, with result stored in
7250 ;; Change div/mod to HImode and extend the second argument to HImode
7251 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7252 ;; combine may fail.
7253 (define_insn "divmodhiqi3"
7254 [(set (match_operand:HI 0 "register_operand" "=a")
7259 (mod:HI (match_operand:HI 1 "register_operand" "0")
7261 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7265 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7266 (clobber (reg:CC FLAGS_REG))]
7267 "TARGET_QIMODE_MATH"
7269 [(set_attr "type" "idiv")
7270 (set_attr "mode" "QI")])
7272 (define_insn "udivmodhiqi3"
7273 [(set (match_operand:HI 0 "register_operand" "=a")
7278 (mod:HI (match_operand:HI 1 "register_operand" "0")
7280 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7284 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7285 (clobber (reg:CC FLAGS_REG))]
7286 "TARGET_QIMODE_MATH"
7288 [(set_attr "type" "idiv")
7289 (set_attr "mode" "QI")])
7291 (define_expand "divmod<mode>4"
7292 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7294 (match_operand:SWIM248 1 "register_operand" "")
7295 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7296 (set (match_operand:SWIM248 3 "register_operand" "")
7297 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7298 (clobber (reg:CC FLAGS_REG))])]
7302 (define_insn_and_split "*divmod<mode>4"
7303 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7304 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7305 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7306 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7307 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7308 (clobber (reg:CC FLAGS_REG))]
7312 [(parallel [(set (match_dup 1)
7313 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7314 (clobber (reg:CC FLAGS_REG))])
7315 (parallel [(set (match_dup 0)
7316 (div:SWIM248 (match_dup 2) (match_dup 3)))
7318 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7320 (clobber (reg:CC FLAGS_REG))])]
7322 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7324 if (<MODE>mode != HImode
7325 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7326 operands[4] = operands[2];
7329 /* Avoid use of cltd in favor of a mov+shift. */
7330 emit_move_insn (operands[1], operands[2]);
7331 operands[4] = operands[1];
7334 [(set_attr "type" "multi")
7335 (set_attr "mode" "<MODE>")])
7337 (define_insn "*divmod<mode>4_noext"
7338 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7339 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7340 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7341 (set (match_operand:SWIM248 1 "register_operand" "=d")
7342 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7343 (use (match_operand:SWIM248 4 "register_operand" "1"))
7344 (clobber (reg:CC FLAGS_REG))]
7346 "idiv{<imodesuffix>}\t%3"
7347 [(set_attr "type" "idiv")
7348 (set_attr "mode" "<MODE>")])
7350 (define_expand "udivmod<mode>4"
7351 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7353 (match_operand:SWIM248 1 "register_operand" "")
7354 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7355 (set (match_operand:SWIM248 3 "register_operand" "")
7356 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7357 (clobber (reg:CC FLAGS_REG))])]
7361 (define_insn_and_split "*udivmod<mode>4"
7362 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7363 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7364 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7365 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7366 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7367 (clobber (reg:CC FLAGS_REG))]
7371 [(set (match_dup 1) (const_int 0))
7372 (parallel [(set (match_dup 0)
7373 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7375 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))])]
7379 [(set_attr "type" "multi")
7380 (set_attr "mode" "<MODE>")])
7382 (define_insn "*udivmod<mode>4_noext"
7383 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386 (set (match_operand:SWIM248 1 "register_operand" "=d")
7387 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388 (use (match_operand:SWIM248 4 "register_operand" "1"))
7389 (clobber (reg:CC FLAGS_REG))]
7391 "div{<imodesuffix>}\t%3"
7392 [(set_attr "type" "idiv")
7393 (set_attr "mode" "<MODE>")])
7395 ;; We cannot use div/idiv for double division, because it causes
7396 ;; "division by zero" on the overflow and that's not what we expect
7397 ;; from truncate. Because true (non truncating) double division is
7398 ;; never generated, we can't create this insn anyway.
7401 ; [(set (match_operand:SI 0 "register_operand" "=a")
7403 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7405 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7406 ; (set (match_operand:SI 3 "register_operand" "=d")
7408 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7409 ; (clobber (reg:CC FLAGS_REG))]
7411 ; "div{l}\t{%2, %0|%0, %2}"
7412 ; [(set_attr "type" "idiv")])
7414 ;;- Logical AND instructions
7416 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7417 ;; Note that this excludes ah.
7419 (define_expand "testsi_ccno_1"
7420 [(set (reg:CCNO FLAGS_REG)
7422 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7423 (match_operand:SI 1 "nonmemory_operand" ""))
7428 (define_expand "testqi_ccz_1"
7429 [(set (reg:CCZ FLAGS_REG)
7430 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7431 (match_operand:QI 1 "nonmemory_operand" ""))
7436 (define_insn "*testdi_1"
7437 [(set (reg FLAGS_REG)
7440 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7441 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7443 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7446 test{l}\t{%k1, %k0|%k0, %k1}
7447 test{l}\t{%k1, %k0|%k0, %k1}
7448 test{q}\t{%1, %0|%0, %1}
7449 test{q}\t{%1, %0|%0, %1}
7450 test{q}\t{%1, %0|%0, %1}"
7451 [(set_attr "type" "test")
7452 (set_attr "modrm" "0,1,0,1,1")
7453 (set_attr "mode" "SI,SI,DI,DI,DI")])
7455 (define_insn "*testqi_1_maybe_si"
7456 [(set (reg FLAGS_REG)
7459 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7460 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7462 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7463 && ix86_match_ccmode (insn,
7464 CONST_INT_P (operands[1])
7465 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7467 if (which_alternative == 3)
7469 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7470 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7471 return "test{l}\t{%1, %k0|%k0, %1}";
7473 return "test{b}\t{%1, %0|%0, %1}";
7475 [(set_attr "type" "test")
7476 (set_attr "modrm" "0,1,1,1")
7477 (set_attr "mode" "QI,QI,QI,SI")
7478 (set_attr "pent_pair" "uv,np,uv,np")])
7480 (define_insn "*test<mode>_1"
7481 [(set (reg FLAGS_REG)
7484 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7485 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7487 "ix86_match_ccmode (insn, CCNOmode)
7488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7489 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "modrm" "0,1,1")
7492 (set_attr "mode" "<MODE>")
7493 (set_attr "pent_pair" "uv,np,uv")])
7495 (define_expand "testqi_ext_ccno_0"
7496 [(set (reg:CCNO FLAGS_REG)
7500 (match_operand 0 "ext_register_operand" "")
7503 (match_operand 1 "const_int_operand" ""))
7508 (define_insn "*testqi_ext_0"
7509 [(set (reg FLAGS_REG)
7513 (match_operand 0 "ext_register_operand" "Q")
7516 (match_operand 1 "const_int_operand" "n"))
7518 "ix86_match_ccmode (insn, CCNOmode)"
7519 "test{b}\t{%1, %h0|%h0, %1}"
7520 [(set_attr "type" "test")
7521 (set_attr "mode" "QI")
7522 (set_attr "length_immediate" "1")
7523 (set_attr "modrm" "1")
7524 (set_attr "pent_pair" "np")])
7526 (define_insn "*testqi_ext_1_rex64"
7527 [(set (reg FLAGS_REG)
7531 (match_operand 0 "ext_register_operand" "Q")
7535 (match_operand:QI 1 "register_operand" "Q")))
7537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7538 "test{b}\t{%1, %h0|%h0, %1}"
7539 [(set_attr "type" "test")
7540 (set_attr "mode" "QI")])
7542 (define_insn "*testqi_ext_1"
7543 [(set (reg FLAGS_REG)
7547 (match_operand 0 "ext_register_operand" "Q")
7551 (match_operand:QI 1 "general_operand" "Qm")))
7553 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7554 "test{b}\t{%1, %h0|%h0, %1}"
7555 [(set_attr "type" "test")
7556 (set_attr "mode" "QI")])
7558 (define_insn "*testqi_ext_2"
7559 [(set (reg FLAGS_REG)
7563 (match_operand 0 "ext_register_operand" "Q")
7567 (match_operand 1 "ext_register_operand" "Q")
7571 "ix86_match_ccmode (insn, CCNOmode)"
7572 "test{b}\t{%h1, %h0|%h0, %h1}"
7573 [(set_attr "type" "test")
7574 (set_attr "mode" "QI")])
7576 (define_insn "*testqi_ext_3_rex64"
7577 [(set (reg FLAGS_REG)
7578 (compare (zero_extract:DI
7579 (match_operand 0 "nonimmediate_operand" "rm")
7580 (match_operand:DI 1 "const_int_operand" "")
7581 (match_operand:DI 2 "const_int_operand" ""))
7584 && ix86_match_ccmode (insn, CCNOmode)
7585 && INTVAL (operands[1]) > 0
7586 && INTVAL (operands[2]) >= 0
7587 /* Ensure that resulting mask is zero or sign extended operand. */
7588 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7589 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7590 && INTVAL (operands[1]) > 32))
7591 && (GET_MODE (operands[0]) == SImode
7592 || GET_MODE (operands[0]) == DImode
7593 || GET_MODE (operands[0]) == HImode
7594 || GET_MODE (operands[0]) == QImode)"
7597 ;; Combine likes to form bit extractions for some tests. Humor it.
7598 (define_insn "*testqi_ext_3"
7599 [(set (reg FLAGS_REG)
7600 (compare (zero_extract:SI
7601 (match_operand 0 "nonimmediate_operand" "rm")
7602 (match_operand:SI 1 "const_int_operand" "")
7603 (match_operand:SI 2 "const_int_operand" ""))
7605 "ix86_match_ccmode (insn, CCNOmode)
7606 && INTVAL (operands[1]) > 0
7607 && INTVAL (operands[2]) >= 0
7608 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7609 && (GET_MODE (operands[0]) == SImode
7610 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7611 || GET_MODE (operands[0]) == HImode
7612 || GET_MODE (operands[0]) == QImode)"
7616 [(set (match_operand 0 "flags_reg_operand" "")
7617 (match_operator 1 "compare_operator"
7619 (match_operand 2 "nonimmediate_operand" "")
7620 (match_operand 3 "const_int_operand" "")
7621 (match_operand 4 "const_int_operand" ""))
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7626 rtx val = operands[2];
7627 HOST_WIDE_INT len = INTVAL (operands[3]);
7628 HOST_WIDE_INT pos = INTVAL (operands[4]);
7630 enum machine_mode mode, submode;
7632 mode = GET_MODE (val);
7635 /* ??? Combine likes to put non-volatile mem extractions in QImode
7636 no matter the size of the test. So find a mode that works. */
7637 if (! MEM_VOLATILE_P (val))
7639 mode = smallest_mode_for_size (pos + len, MODE_INT);
7640 val = adjust_address (val, mode, 0);
7643 else if (GET_CODE (val) == SUBREG
7644 && (submode = GET_MODE (SUBREG_REG (val)),
7645 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7646 && pos + len <= GET_MODE_BITSIZE (submode)
7647 && GET_MODE_CLASS (submode) == MODE_INT)
7649 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7651 val = SUBREG_REG (val);
7653 else if (mode == HImode && pos + len <= 8)
7655 /* Small HImode tests can be converted to QImode. */
7657 val = gen_lowpart (QImode, val);
7660 if (len == HOST_BITS_PER_WIDE_INT)
7663 mask = ((HOST_WIDE_INT)1 << len) - 1;
7666 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7669 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7670 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7671 ;; this is relatively important trick.
7672 ;; Do the conversion only post-reload to avoid limiting of the register class
7675 [(set (match_operand 0 "flags_reg_operand" "")
7676 (match_operator 1 "compare_operator"
7677 [(and (match_operand 2 "register_operand" "")
7678 (match_operand 3 "const_int_operand" ""))
7681 && QI_REG_P (operands[2])
7682 && GET_MODE (operands[2]) != QImode
7683 && ((ix86_match_ccmode (insn, CCZmode)
7684 && !(INTVAL (operands[3]) & ~(255 << 8)))
7685 || (ix86_match_ccmode (insn, CCNOmode)
7686 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7689 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7692 "operands[2] = gen_lowpart (SImode, operands[2]);
7693 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7696 [(set (match_operand 0 "flags_reg_operand" "")
7697 (match_operator 1 "compare_operator"
7698 [(and (match_operand 2 "nonimmediate_operand" "")
7699 (match_operand 3 "const_int_operand" ""))
7702 && GET_MODE (operands[2]) != QImode
7703 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7704 && ((ix86_match_ccmode (insn, CCZmode)
7705 && !(INTVAL (operands[3]) & ~255))
7706 || (ix86_match_ccmode (insn, CCNOmode)
7707 && !(INTVAL (operands[3]) & ~127)))"
7709 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7711 "operands[2] = gen_lowpart (QImode, operands[2]);
7712 operands[3] = gen_lowpart (QImode, operands[3]);")
7714 ;; %%% This used to optimize known byte-wide and operations to memory,
7715 ;; and sometimes to QImode registers. If this is considered useful,
7716 ;; it should be done with splitters.
7718 (define_expand "and<mode>3"
7719 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7720 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7721 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7723 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7725 (define_insn "*anddi_1"
7726 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7728 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7729 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7730 (clobber (reg:CC FLAGS_REG))]
7731 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7733 switch (get_attr_type (insn))
7737 enum machine_mode mode;
7739 gcc_assert (CONST_INT_P (operands[2]));
7740 if (INTVAL (operands[2]) == 0xff)
7744 gcc_assert (INTVAL (operands[2]) == 0xffff);
7748 operands[1] = gen_lowpart (mode, operands[1]);
7750 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7752 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7757 if (get_attr_mode (insn) == MODE_SI)
7758 return "and{l}\t{%k2, %k0|%k0, %k2}";
7760 return "and{q}\t{%2, %0|%0, %2}";
7763 [(set_attr "type" "alu,alu,alu,imovx")
7764 (set_attr "length_immediate" "*,*,*,0")
7765 (set (attr "prefix_rex")
7767 (and (eq_attr "type" "imovx")
7768 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7769 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7771 (const_string "*")))
7772 (set_attr "mode" "SI,DI,DI,SI")])
7774 (define_insn "*andsi_1"
7775 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7776 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7777 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "ix86_binary_operator_ok (AND, SImode, operands)"
7781 switch (get_attr_type (insn))
7785 enum machine_mode mode;
7787 gcc_assert (CONST_INT_P (operands[2]));
7788 if (INTVAL (operands[2]) == 0xff)
7792 gcc_assert (INTVAL (operands[2]) == 0xffff);
7796 operands[1] = gen_lowpart (mode, operands[1]);
7798 return "movz{bl|x}\t{%1, %0|%0, %1}";
7800 return "movz{wl|x}\t{%1, %0|%0, %1}";
7804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805 return "and{l}\t{%2, %0|%0, %2}";
7808 [(set_attr "type" "alu,alu,imovx")
7809 (set (attr "prefix_rex")
7811 (and (eq_attr "type" "imovx")
7812 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7813 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7815 (const_string "*")))
7816 (set_attr "length_immediate" "*,*,0")
7817 (set_attr "mode" "SI")])
7819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7820 (define_insn "*andsi_1_zext"
7821 [(set (match_operand:DI 0 "register_operand" "=r")
7823 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7824 (match_operand:SI 2 "general_operand" "g"))))
7825 (clobber (reg:CC FLAGS_REG))]
7826 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7827 "and{l}\t{%2, %k0|%k0, %2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "SI")])
7831 (define_insn "*andhi_1"
7832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7833 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7834 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "ix86_binary_operator_ok (AND, HImode, operands)"
7838 switch (get_attr_type (insn))
7841 gcc_assert (CONST_INT_P (operands[2]));
7842 gcc_assert (INTVAL (operands[2]) == 0xff);
7843 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848 return "and{w}\t{%2, %0|%0, %2}";
7851 [(set_attr "type" "alu,alu,imovx")
7852 (set_attr "length_immediate" "*,*,0")
7853 (set (attr "prefix_rex")
7855 (and (eq_attr "type" "imovx")
7856 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7858 (const_string "*")))
7859 (set_attr "mode" "HI,HI,SI")])
7861 ;; %%% Potential partial reg stall on alternative 2. What to do?
7862 (define_insn "*andqi_1"
7863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7864 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7865 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "ix86_binary_operator_ok (AND, QImode, operands)"
7869 and{b}\t{%2, %0|%0, %2}
7870 and{b}\t{%2, %0|%0, %2}
7871 and{l}\t{%k2, %k0|%k0, %k2}"
7872 [(set_attr "type" "alu")
7873 (set_attr "mode" "QI,QI,SI")])
7875 (define_insn "*andqi_1_slp"
7876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7877 (and:QI (match_dup 0)
7878 (match_operand:QI 1 "general_operand" "qn,qmn")))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7882 "and{b}\t{%1, %0|%0, %1}"
7883 [(set_attr "type" "alu1")
7884 (set_attr "mode" "QI")])
7887 [(set (match_operand 0 "register_operand" "")
7889 (const_int -65536)))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7892 || optimize_function_for_size_p (cfun)"
7893 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7894 "operands[1] = gen_lowpart (HImode, operands[0]);")
7897 [(set (match_operand 0 "ext_register_operand" "")
7900 (clobber (reg:CC FLAGS_REG))]
7901 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7902 && reload_completed"
7903 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7904 "operands[1] = gen_lowpart (QImode, operands[0]);")
7907 [(set (match_operand 0 "ext_register_operand" "")
7909 (const_int -65281)))
7910 (clobber (reg:CC FLAGS_REG))]
7911 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7912 && reload_completed"
7913 [(parallel [(set (zero_extract:SI (match_dup 0)
7917 (zero_extract:SI (match_dup 0)
7920 (zero_extract:SI (match_dup 0)
7923 (clobber (reg:CC FLAGS_REG))])]
7924 "operands[0] = gen_lowpart (SImode, operands[0]);")
7926 (define_insn "*anddi_2"
7927 [(set (reg FLAGS_REG)
7930 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7931 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7934 (and:DI (match_dup 1) (match_dup 2)))]
7935 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7936 && ix86_binary_operator_ok (AND, DImode, operands)"
7938 and{l}\t{%k2, %k0|%k0, %k2}
7939 and{q}\t{%2, %0|%0, %2}
7940 and{q}\t{%2, %0|%0, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "SI,DI,DI")])
7944 (define_insn "*andqi_2_maybe_si"
7945 [(set (reg FLAGS_REG)
7947 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7948 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7951 (and:QI (match_dup 1) (match_dup 2)))]
7952 "ix86_binary_operator_ok (AND, QImode, operands)
7953 && ix86_match_ccmode (insn,
7954 CONST_INT_P (operands[2])
7955 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 if (which_alternative == 2)
7959 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7960 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7961 return "and{l}\t{%2, %k0|%k0, %2}";
7963 return "and{b}\t{%2, %0|%0, %2}";
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "QI,QI,SI")])
7968 (define_insn "*and<mode>_2"
7969 [(set (reg FLAGS_REG)
7970 (compare (and:SWI124
7971 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7972 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7974 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7975 (and:SWI124 (match_dup 1) (match_dup 2)))]
7976 "ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7978 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "<MODE>")])
7982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7983 (define_insn "*andsi_2_zext"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:SI 1 "nonimmediate_operand" "%0")
7987 (match_operand:SI 2 "general_operand" "g"))
7989 (set (match_operand:DI 0 "register_operand" "=r")
7990 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7991 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992 && ix86_binary_operator_ok (AND, SImode, operands)"
7993 "and{l}\t{%2, %k0|%k0, %2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "SI")])
7997 (define_insn "*andqi_2_slp"
7998 [(set (reg FLAGS_REG)
8000 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8001 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003 (set (strict_low_part (match_dup 0))
8004 (and:QI (match_dup 0) (match_dup 1)))]
8005 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006 && ix86_match_ccmode (insn, CCNOmode)
8007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008 "and{b}\t{%1, %0|%0, %1}"
8009 [(set_attr "type" "alu1")
8010 (set_attr "mode" "QI")])
8012 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8013 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8014 ;; for a QImode operand, which of course failed.
8015 (define_insn "andqi_ext_0"
8016 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8021 (match_operand 1 "ext_register_operand" "0")
8024 (match_operand 2 "const_int_operand" "n")))
8025 (clobber (reg:CC FLAGS_REG))]
8027 "and{b}\t{%2, %h0|%h0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "length_immediate" "1")
8030 (set_attr "modrm" "1")
8031 (set_attr "mode" "QI")])
8033 ;; Generated by peephole translating test to and. This shows up
8034 ;; often in fp comparisons.
8035 (define_insn "*andqi_ext_0_cc"
8036 [(set (reg FLAGS_REG)
8040 (match_operand 1 "ext_register_operand" "0")
8043 (match_operand 2 "const_int_operand" "n"))
8045 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8054 "ix86_match_ccmode (insn, CCNOmode)"
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8061 (define_insn "*andqi_ext_1_rex64"
8062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8067 (match_operand 1 "ext_register_operand" "0")
8071 (match_operand 2 "ext_register_operand" "Q"))))
8072 (clobber (reg:CC FLAGS_REG))]
8074 "and{b}\t{%2, %h0|%h0, %2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_1"
8080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8085 (match_operand 1 "ext_register_operand" "0")
8089 (match_operand:QI 2 "general_operand" "Qm"))))
8090 (clobber (reg:CC FLAGS_REG))]
8092 "and{b}\t{%2, %h0|%h0, %2}"
8093 [(set_attr "type" "alu")
8094 (set_attr "length_immediate" "0")
8095 (set_attr "mode" "QI")])
8097 (define_insn "*andqi_ext_2"
8098 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8103 (match_operand 1 "ext_register_operand" "%0")
8107 (match_operand 2 "ext_register_operand" "Q")
8110 (clobber (reg:CC FLAGS_REG))]
8112 "and{b}\t{%h2, %h0|%h0, %h2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "length_immediate" "0")
8115 (set_attr "mode" "QI")])
8117 ;; Convert wide AND instructions with immediate operand to shorter QImode
8118 ;; equivalents when possible.
8119 ;; Don't do the splitting with memory operands, since it introduces risk
8120 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8121 ;; for size, but that can (should?) be handled by generic code instead.
8123 [(set (match_operand 0 "register_operand" "")
8124 (and (match_operand 1 "register_operand" "")
8125 (match_operand 2 "const_int_operand" "")))
8126 (clobber (reg:CC FLAGS_REG))]
8128 && QI_REG_P (operands[0])
8129 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8130 && !(~INTVAL (operands[2]) & ~(255 << 8))
8131 && GET_MODE (operands[0]) != QImode"
8132 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8133 (and:SI (zero_extract:SI (match_dup 1)
8134 (const_int 8) (const_int 8))
8136 (clobber (reg:CC FLAGS_REG))])]
8137 "operands[0] = gen_lowpart (SImode, operands[0]);
8138 operands[1] = gen_lowpart (SImode, operands[1]);
8139 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8141 ;; Since AND can be encoded with sign extended immediate, this is only
8142 ;; profitable when 7th bit is not set.
8144 [(set (match_operand 0 "register_operand" "")
8145 (and (match_operand 1 "general_operand" "")
8146 (match_operand 2 "const_int_operand" "")))
8147 (clobber (reg:CC FLAGS_REG))]
8149 && ANY_QI_REG_P (operands[0])
8150 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8151 && !(~INTVAL (operands[2]) & ~255)
8152 && !(INTVAL (operands[2]) & 128)
8153 && GET_MODE (operands[0]) != QImode"
8154 [(parallel [(set (strict_low_part (match_dup 0))
8155 (and:QI (match_dup 1)
8157 (clobber (reg:CC FLAGS_REG))])]
8158 "operands[0] = gen_lowpart (QImode, operands[0]);
8159 operands[1] = gen_lowpart (QImode, operands[1]);
8160 operands[2] = gen_lowpart (QImode, operands[2]);")
8162 ;; Logical inclusive and exclusive OR instructions
8164 ;; %%% This used to optimize known byte-wide and operations to memory.
8165 ;; If this is considered useful, it should be done with splitters.
8167 (define_expand "<code><mode>3"
8168 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8169 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8170 (match_operand:SWIM 2 "<general_operand>" "")))]
8172 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8174 (define_insn "*<code><mode>_1"
8175 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8177 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8178 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8181 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "<MODE>")])
8185 ;; %%% Potential partial reg stall on alternative 2. What to do?
8186 (define_insn "*<code>qi_1"
8187 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8188 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8189 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8193 <logic>{b}\t{%2, %0|%0, %2}
8194 <logic>{b}\t{%2, %0|%0, %2}
8195 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "mode" "QI,QI,SI")])
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*<code>si_1_zext"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8203 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "general_operand" "g"))))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*<code>si_1_zext_imm"
8212 [(set (match_operand:DI 0 "register_operand" "=r")
8214 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8215 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8218 "<logic>{l}\t{%2, %k0|%k0, %2}"
8219 [(set_attr "type" "alu")
8220 (set_attr "mode" "SI")])
8222 (define_insn "*<code>qi_1_slp"
8223 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8224 (any_or:QI (match_dup 0)
8225 (match_operand:QI 1 "general_operand" "qmn,qn")))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8229 "<logic>{b}\t{%1, %0|%0, %1}"
8230 [(set_attr "type" "alu1")
8231 (set_attr "mode" "QI")])
8233 (define_insn "*<code><mode>_2"
8234 [(set (reg FLAGS_REG)
8235 (compare (any_or:SWI
8236 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8237 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8240 (any_or:SWI (match_dup 1) (match_dup 2)))]
8241 "ix86_match_ccmode (insn, CCNOmode)
8242 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8243 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "<MODE>")])
8247 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8248 ;; ??? Special case for immediate operand is missing - it is tricky.
8249 (define_insn "*<code>si_2_zext"
8250 [(set (reg FLAGS_REG)
8251 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8252 (match_operand:SI 2 "general_operand" "g"))
8254 (set (match_operand:DI 0 "register_operand" "=r")
8255 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8256 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8257 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8258 "<logic>{l}\t{%2, %k0|%k0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "SI")])
8262 (define_insn "*<code>si_2_zext_imm"
8263 [(set (reg FLAGS_REG)
8265 (match_operand:SI 1 "nonimmediate_operand" "%0")
8266 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8268 (set (match_operand:DI 0 "register_operand" "=r")
8269 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8270 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8271 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8272 "<logic>{l}\t{%2, %k0|%k0, %2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "SI")])
8276 (define_insn "*<code>qi_2_slp"
8277 [(set (reg FLAGS_REG)
8278 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8279 (match_operand:QI 1 "general_operand" "qmn,qn"))
8281 (set (strict_low_part (match_dup 0))
8282 (any_or:QI (match_dup 0) (match_dup 1)))]
8283 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8284 && ix86_match_ccmode (insn, CCNOmode)
8285 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8286 "<logic>{b}\t{%1, %0|%0, %1}"
8287 [(set_attr "type" "alu1")
8288 (set_attr "mode" "QI")])
8290 (define_insn "*<code><mode>_3"
8291 [(set (reg FLAGS_REG)
8292 (compare (any_or:SWI
8293 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8294 (match_operand:SWI 2 "<general_operand>" "<g>"))
8296 (clobber (match_scratch:SWI 0 "=<r>"))]
8297 "ix86_match_ccmode (insn, CCNOmode)
8298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8300 [(set_attr "type" "alu")
8301 (set_attr "mode" "<MODE>")])
8303 (define_insn "*<code>qi_ext_0"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (match_operand 1 "ext_register_operand" "0")
8312 (match_operand 2 "const_int_operand" "n")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8315 "<logic>{b}\t{%2, %h0|%h0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "length_immediate" "1")
8318 (set_attr "modrm" "1")
8319 (set_attr "mode" "QI")])
8321 (define_insn "*<code>qi_ext_1_rex64"
8322 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327 (match_operand 1 "ext_register_operand" "0")
8331 (match_operand 2 "ext_register_operand" "Q"))))
8332 (clobber (reg:CC FLAGS_REG))]
8334 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8335 "<logic>{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "0")
8338 (set_attr "mode" "QI")])
8340 (define_insn "*<code>qi_ext_1"
8341 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8346 (match_operand 1 "ext_register_operand" "0")
8350 (match_operand:QI 2 "general_operand" "Qm"))))
8351 (clobber (reg:CC FLAGS_REG))]
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8354 "<logic>{b}\t{%2, %h0|%h0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "length_immediate" "0")
8357 (set_attr "mode" "QI")])
8359 (define_insn "*<code>qi_ext_2"
8360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8367 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8370 (clobber (reg:CC FLAGS_REG))]
8371 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8372 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "length_immediate" "0")
8375 (set_attr "mode" "QI")])
8378 [(set (match_operand 0 "register_operand" "")
8379 (any_or (match_operand 1 "register_operand" "")
8380 (match_operand 2 "const_int_operand" "")))
8381 (clobber (reg:CC FLAGS_REG))]
8383 && QI_REG_P (operands[0])
8384 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8385 && !(INTVAL (operands[2]) & ~(255 << 8))
8386 && GET_MODE (operands[0]) != QImode"
8387 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8388 (any_or:SI (zero_extract:SI (match_dup 1)
8389 (const_int 8) (const_int 8))
8391 (clobber (reg:CC FLAGS_REG))])]
8392 "operands[0] = gen_lowpart (SImode, operands[0]);
8393 operands[1] = gen_lowpart (SImode, operands[1]);
8394 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8396 ;; Since OR can be encoded with sign extended immediate, this is only
8397 ;; profitable when 7th bit is set.
8399 [(set (match_operand 0 "register_operand" "")
8400 (any_or (match_operand 1 "general_operand" "")
8401 (match_operand 2 "const_int_operand" "")))
8402 (clobber (reg:CC FLAGS_REG))]
8404 && ANY_QI_REG_P (operands[0])
8405 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8406 && !(INTVAL (operands[2]) & ~255)
8407 && (INTVAL (operands[2]) & 128)
8408 && GET_MODE (operands[0]) != QImode"
8409 [(parallel [(set (strict_low_part (match_dup 0))
8410 (any_or:QI (match_dup 1)
8412 (clobber (reg:CC FLAGS_REG))])]
8413 "operands[0] = gen_lowpart (QImode, operands[0]);
8414 operands[1] = gen_lowpart (QImode, operands[1]);
8415 operands[2] = gen_lowpart (QImode, operands[2]);")
8417 (define_expand "xorqi_cc_ext_1"
8419 (set (reg:CCNO FLAGS_REG)
8423 (match_operand 1 "ext_register_operand" "")
8426 (match_operand:QI 2 "general_operand" ""))
8428 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8440 (define_insn "*xorqi_cc_ext_1_rex64"
8441 [(set (reg FLAGS_REG)
8445 (match_operand 1 "ext_register_operand" "0")
8448 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8450 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8460 "xor{b}\t{%2, %h0|%h0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "modrm" "1")
8463 (set_attr "mode" "QI")])
8465 (define_insn "*xorqi_cc_ext_1"
8466 [(set (reg FLAGS_REG)
8470 (match_operand 1 "ext_register_operand" "0")
8473 (match_operand:QI 2 "general_operand" "qmn"))
8475 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8484 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8485 "xor{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "modrm" "1")
8488 (set_attr "mode" "QI")])
8490 ;; Negation instructions
8492 (define_expand "neg<mode>2"
8493 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8494 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8496 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8498 (define_insn_and_split "*neg<dwi>2_doubleword"
8499 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8500 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8501 (clobber (reg:CC FLAGS_REG))]
8502 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8506 [(set (reg:CCZ FLAGS_REG)
8507 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8508 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8511 (plus:DWIH (match_dup 3)
8512 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8514 (clobber (reg:CC FLAGS_REG))])
8517 (neg:DWIH (match_dup 2)))
8518 (clobber (reg:CC FLAGS_REG))])]
8519 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8521 (define_insn "*neg<mode>2_1"
8522 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8523 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8524 (clobber (reg:CC FLAGS_REG))]
8525 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8526 "neg{<imodesuffix>}\t%0"
8527 [(set_attr "type" "negnot")
8528 (set_attr "mode" "<MODE>")])
8530 ;; Combine is quite creative about this pattern.
8531 (define_insn "*negsi2_1_zext"
8532 [(set (match_operand:DI 0 "register_operand" "=r")
8534 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8537 (clobber (reg:CC FLAGS_REG))]
8538 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8540 [(set_attr "type" "negnot")
8541 (set_attr "mode" "SI")])
8543 ;; The problem with neg is that it does not perform (compare x 0),
8544 ;; it really performs (compare 0 x), which leaves us with the zero
8545 ;; flag being the only useful item.
8547 (define_insn "*neg<mode>2_cmpz"
8548 [(set (reg:CCZ FLAGS_REG)
8550 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8552 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8553 (neg:SWI (match_dup 1)))]
8554 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8555 "neg{<imodesuffix>}\t%0"
8556 [(set_attr "type" "negnot")
8557 (set_attr "mode" "<MODE>")])
8559 (define_insn "*negsi2_cmpz_zext"
8560 [(set (reg:CCZ FLAGS_REG)
8564 (match_operand:DI 1 "register_operand" "0")
8568 (set (match_operand:DI 0 "register_operand" "=r")
8569 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8572 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8574 [(set_attr "type" "negnot")
8575 (set_attr "mode" "SI")])
8577 ;; Changing of sign for FP values is doable using integer unit too.
8579 (define_expand "<code><mode>2"
8580 [(set (match_operand:X87MODEF 0 "register_operand" "")
8581 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8582 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8583 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8585 (define_insn "*absneg<mode>2_mixed"
8586 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8587 (match_operator:MODEF 3 "absneg_operator"
8588 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8589 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8590 (clobber (reg:CC FLAGS_REG))]
8591 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8594 (define_insn "*absneg<mode>2_sse"
8595 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8596 (match_operator:MODEF 3 "absneg_operator"
8597 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8598 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8603 (define_insn "*absneg<mode>2_i387"
8604 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8605 (match_operator:X87MODEF 3 "absneg_operator"
8606 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8607 (use (match_operand 2 "" ""))
8608 (clobber (reg:CC FLAGS_REG))]
8609 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8612 (define_expand "<code>tf2"
8613 [(set (match_operand:TF 0 "register_operand" "")
8614 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8616 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8618 (define_insn "*absnegtf2_sse"
8619 [(set (match_operand:TF 0 "register_operand" "=x,x")
8620 (match_operator:TF 3 "absneg_operator"
8621 [(match_operand:TF 1 "register_operand" "0,x")]))
8622 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8623 (clobber (reg:CC FLAGS_REG))]
8627 ;; Splitters for fp abs and neg.
8630 [(set (match_operand 0 "fp_register_operand" "")
8631 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8632 (use (match_operand 2 "" ""))
8633 (clobber (reg:CC FLAGS_REG))]
8635 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8638 [(set (match_operand 0 "register_operand" "")
8639 (match_operator 3 "absneg_operator"
8640 [(match_operand 1 "register_operand" "")]))
8641 (use (match_operand 2 "nonimmediate_operand" ""))
8642 (clobber (reg:CC FLAGS_REG))]
8643 "reload_completed && SSE_REG_P (operands[0])"
8644 [(set (match_dup 0) (match_dup 3))]
8646 enum machine_mode mode = GET_MODE (operands[0]);
8647 enum machine_mode vmode = GET_MODE (operands[2]);
8650 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8651 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8652 if (operands_match_p (operands[0], operands[2]))
8655 operands[1] = operands[2];
8658 if (GET_CODE (operands[3]) == ABS)
8659 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8661 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8666 [(set (match_operand:SF 0 "register_operand" "")
8667 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8668 (use (match_operand:V4SF 2 "" ""))
8669 (clobber (reg:CC FLAGS_REG))]
8671 [(parallel [(set (match_dup 0) (match_dup 1))
8672 (clobber (reg:CC FLAGS_REG))])]
8675 operands[0] = gen_lowpart (SImode, operands[0]);
8676 if (GET_CODE (operands[1]) == ABS)
8678 tmp = gen_int_mode (0x7fffffff, SImode);
8679 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8683 tmp = gen_int_mode (0x80000000, SImode);
8684 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8690 [(set (match_operand:DF 0 "register_operand" "")
8691 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8692 (use (match_operand 2 "" ""))
8693 (clobber (reg:CC FLAGS_REG))]
8695 [(parallel [(set (match_dup 0) (match_dup 1))
8696 (clobber (reg:CC FLAGS_REG))])]
8701 tmp = gen_lowpart (DImode, operands[0]);
8702 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8705 if (GET_CODE (operands[1]) == ABS)
8708 tmp = gen_rtx_NOT (DImode, tmp);
8712 operands[0] = gen_highpart (SImode, operands[0]);
8713 if (GET_CODE (operands[1]) == ABS)
8715 tmp = gen_int_mode (0x7fffffff, SImode);
8716 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8720 tmp = gen_int_mode (0x80000000, SImode);
8721 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8728 [(set (match_operand:XF 0 "register_operand" "")
8729 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8730 (use (match_operand 2 "" ""))
8731 (clobber (reg:CC FLAGS_REG))]
8733 [(parallel [(set (match_dup 0) (match_dup 1))
8734 (clobber (reg:CC FLAGS_REG))])]
8737 operands[0] = gen_rtx_REG (SImode,
8738 true_regnum (operands[0])
8739 + (TARGET_64BIT ? 1 : 2));
8740 if (GET_CODE (operands[1]) == ABS)
8742 tmp = GEN_INT (0x7fff);
8743 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8747 tmp = GEN_INT (0x8000);
8748 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8753 ;; Conditionalize these after reload. If they match before reload, we
8754 ;; lose the clobber and ability to use integer instructions.
8756 (define_insn "*<code><mode>2_1"
8757 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8758 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8760 && (reload_completed
8761 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8762 "f<absneg_mnemonic>"
8763 [(set_attr "type" "fsgn")
8764 (set_attr "mode" "<MODE>")])
8766 (define_insn "*<code>extendsfdf2"
8767 [(set (match_operand:DF 0 "register_operand" "=f")
8768 (absneg:DF (float_extend:DF
8769 (match_operand:SF 1 "register_operand" "0"))))]
8770 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8771 "f<absneg_mnemonic>"
8772 [(set_attr "type" "fsgn")
8773 (set_attr "mode" "DF")])
8775 (define_insn "*<code>extendsfxf2"
8776 [(set (match_operand:XF 0 "register_operand" "=f")
8777 (absneg:XF (float_extend:XF
8778 (match_operand:SF 1 "register_operand" "0"))))]
8780 "f<absneg_mnemonic>"
8781 [(set_attr "type" "fsgn")
8782 (set_attr "mode" "XF")])
8784 (define_insn "*<code>extenddfxf2"
8785 [(set (match_operand:XF 0 "register_operand" "=f")
8786 (absneg:XF (float_extend:XF
8787 (match_operand:DF 1 "register_operand" "0"))))]
8789 "f<absneg_mnemonic>"
8790 [(set_attr "type" "fsgn")
8791 (set_attr "mode" "XF")])
8793 ;; Copysign instructions
8795 (define_mode_iterator CSGNMODE [SF DF TF])
8796 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8798 (define_expand "copysign<mode>3"
8799 [(match_operand:CSGNMODE 0 "register_operand" "")
8800 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8801 (match_operand:CSGNMODE 2 "register_operand" "")]
8802 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8803 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8804 "ix86_expand_copysign (operands); DONE;")
8806 (define_insn_and_split "copysign<mode>3_const"
8807 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8809 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8810 (match_operand:CSGNMODE 2 "register_operand" "0")
8811 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8813 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8814 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8816 "&& reload_completed"
8818 "ix86_split_copysign_const (operands); DONE;")
8820 (define_insn "copysign<mode>3_var"
8821 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8823 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8824 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8825 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8826 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8828 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8829 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8830 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8834 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8836 [(match_operand:CSGNMODE 2 "register_operand" "")
8837 (match_operand:CSGNMODE 3 "register_operand" "")
8838 (match_operand:<CSGNVMODE> 4 "" "")
8839 (match_operand:<CSGNVMODE> 5 "" "")]
8841 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8842 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8843 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8844 && reload_completed"
8846 "ix86_split_copysign_var (operands); DONE;")
8848 ;; One complement instructions
8850 (define_expand "one_cmpl<mode>2"
8851 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8852 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8854 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8856 (define_insn "*one_cmpl<mode>2_1"
8857 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8858 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8859 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8860 "not{<imodesuffix>}\t%0"
8861 [(set_attr "type" "negnot")
8862 (set_attr "mode" "<MODE>")])
8864 ;; %%% Potential partial reg stall on alternative 1. What to do?
8865 (define_insn "*one_cmplqi2_1"
8866 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8867 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8868 "ix86_unary_operator_ok (NOT, QImode, operands)"
8872 [(set_attr "type" "negnot")
8873 (set_attr "mode" "QI,SI")])
8875 ;; ??? Currently never generated - xor is used instead.
8876 (define_insn "*one_cmplsi2_1_zext"
8877 [(set (match_operand:DI 0 "register_operand" "=r")
8879 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8880 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8882 [(set_attr "type" "negnot")
8883 (set_attr "mode" "SI")])
8885 (define_insn "*one_cmpl<mode>2_2"
8886 [(set (reg FLAGS_REG)
8887 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8889 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8890 (not:SWI (match_dup 1)))]
8891 "ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8894 [(set_attr "type" "alu1")
8895 (set_attr "mode" "<MODE>")])
8898 [(set (match_operand 0 "flags_reg_operand" "")
8899 (match_operator 2 "compare_operator"
8900 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8902 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8903 (not:SWI (match_dup 3)))]
8904 "ix86_match_ccmode (insn, CCNOmode)"
8905 [(parallel [(set (match_dup 0)
8906 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8909 (xor:SWI (match_dup 3) (const_int -1)))])])
8911 ;; ??? Currently never generated - xor is used instead.
8912 (define_insn "*one_cmplsi2_2_zext"
8913 [(set (reg FLAGS_REG)
8914 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8916 (set (match_operand:DI 0 "register_operand" "=r")
8917 (zero_extend:DI (not:SI (match_dup 1))))]
8918 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919 && ix86_unary_operator_ok (NOT, SImode, operands)"
8921 [(set_attr "type" "alu1")
8922 (set_attr "mode" "SI")])
8925 [(set (match_operand 0 "flags_reg_operand" "")
8926 (match_operator 2 "compare_operator"
8927 [(not:SI (match_operand:SI 3 "register_operand" ""))
8929 (set (match_operand:DI 1 "register_operand" "")
8930 (zero_extend:DI (not:SI (match_dup 3))))]
8931 "ix86_match_ccmode (insn, CCNOmode)"
8932 [(parallel [(set (match_dup 0)
8933 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8936 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8938 ;; Shift instructions
8940 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8941 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8942 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8943 ;; from the assembler input.
8945 ;; This instruction shifts the target reg/mem as usual, but instead of
8946 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8947 ;; is a left shift double, bits are taken from the high order bits of
8948 ;; reg, else if the insn is a shift right double, bits are taken from the
8949 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8950 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8952 ;; Since sh[lr]d does not change the `reg' operand, that is done
8953 ;; separately, making all shifts emit pairs of shift double and normal
8954 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8955 ;; support a 63 bit shift, each shift where the count is in a reg expands
8956 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8958 ;; If the shift count is a constant, we need never emit more than one
8959 ;; shift pair, instead using moves and sign extension for counts greater
8962 (define_expand "ashl<mode>3"
8963 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8964 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8965 (match_operand:QI 2 "nonmemory_operand" "")))]
8967 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8969 (define_insn "*ashl<mode>3_doubleword"
8970 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8971 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8972 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8973 (clobber (reg:CC FLAGS_REG))]
8976 [(set_attr "type" "multi")])
8979 [(set (match_operand:DWI 0 "register_operand" "")
8980 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8981 (match_operand:QI 2 "nonmemory_operand" "")))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8985 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8987 ;; By default we don't ask for a scratch register, because when DWImode
8988 ;; values are manipulated, registers are already at a premium. But if
8989 ;; we have one handy, we won't turn it away.
8992 [(match_scratch:DWIH 3 "r")
8993 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8995 (match_operand:<DWI> 1 "nonmemory_operand" "")
8996 (match_operand:QI 2 "nonmemory_operand" "")))
8997 (clobber (reg:CC FLAGS_REG))])
9001 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9003 (define_insn "x86_64_shld"
9004 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9005 (ior:DI (ashift:DI (match_dup 0)
9006 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9007 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9008 (minus:QI (const_int 64) (match_dup 2)))))
9009 (clobber (reg:CC FLAGS_REG))]
9011 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9012 [(set_attr "type" "ishift")
9013 (set_attr "prefix_0f" "1")
9014 (set_attr "mode" "DI")
9015 (set_attr "athlon_decode" "vector")
9016 (set_attr "amdfam10_decode" "vector")])
9018 (define_insn "x86_shld"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9020 (ior:SI (ashift:SI (match_dup 0)
9021 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9023 (minus:QI (const_int 32) (match_dup 2)))))
9024 (clobber (reg:CC FLAGS_REG))]
9026 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9027 [(set_attr "type" "ishift")
9028 (set_attr "prefix_0f" "1")
9029 (set_attr "mode" "SI")
9030 (set_attr "pent_pair" "np")
9031 (set_attr "athlon_decode" "vector")
9032 (set_attr "amdfam10_decode" "vector")])
9034 (define_expand "x86_shift<mode>_adj_1"
9035 [(set (reg:CCZ FLAGS_REG)
9036 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9039 (set (match_operand:SWI48 0 "register_operand" "")
9040 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9041 (match_operand:SWI48 1 "register_operand" "")
9044 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9045 (match_operand:SWI48 3 "register_operand" "r")
9048 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9050 (define_expand "x86_shift<mode>_adj_2"
9051 [(use (match_operand:SWI48 0 "register_operand" ""))
9052 (use (match_operand:SWI48 1 "register_operand" ""))
9053 (use (match_operand:QI 2 "register_operand" ""))]
9056 rtx label = gen_label_rtx ();
9059 emit_insn (gen_testqi_ccz_1 (operands[2],
9060 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9062 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9063 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9064 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9065 gen_rtx_LABEL_REF (VOIDmode, label),
9067 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9068 JUMP_LABEL (tmp) = label;
9070 emit_move_insn (operands[0], operands[1]);
9071 ix86_expand_clear (operands[1]);
9074 LABEL_NUSES (label) = 1;
9079 (define_insn "*ashl<mode>3_1"
9080 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9081 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9082 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9086 switch (get_attr_type (insn))
9092 gcc_assert (operands[2] == const1_rtx);
9093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9094 return "add{<imodesuffix>}\t%0, %0";
9097 if (operands[2] == const1_rtx
9098 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9099 return "sal{<imodesuffix>}\t%0";
9101 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9105 (cond [(eq_attr "alternative" "1")
9106 (const_string "lea")
9107 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9109 (match_operand 0 "register_operand" ""))
9110 (match_operand 2 "const1_operand" ""))
9111 (const_string "alu")
9113 (const_string "ishift")))
9114 (set (attr "length_immediate")
9116 (ior (eq_attr "type" "alu")
9117 (and (eq_attr "type" "ishift")
9118 (and (match_operand 2 "const1_operand" "")
9119 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9122 (const_string "*")))
9123 (set_attr "mode" "<MODE>")])
9125 (define_insn "*ashlsi3_1_zext"
9126 [(set (match_operand:DI 0 "register_operand" "=r,r")
9128 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9129 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9130 (clobber (reg:CC FLAGS_REG))]
9131 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9133 switch (get_attr_type (insn))
9139 gcc_assert (operands[2] == const1_rtx);
9140 return "add{l}\t%k0, %k0";
9143 if (operands[2] == const1_rtx
9144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145 return "sal{l}\t%k0";
9147 return "sal{l}\t{%2, %k0|%k0, %2}";
9151 (cond [(eq_attr "alternative" "1")
9152 (const_string "lea")
9153 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9155 (match_operand 2 "const1_operand" ""))
9156 (const_string "alu")
9158 (const_string "ishift")))
9159 (set (attr "length_immediate")
9161 (ior (eq_attr "type" "alu")
9162 (and (eq_attr "type" "ishift")
9163 (and (match_operand 2 "const1_operand" "")
9164 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9167 (const_string "*")))
9168 (set_attr "mode" "SI")])
9170 (define_insn "*ashlhi3_1"
9171 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9172 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9173 (match_operand:QI 2 "nonmemory_operand" "cI")))
9174 (clobber (reg:CC FLAGS_REG))]
9175 "TARGET_PARTIAL_REG_STALL
9176 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9178 switch (get_attr_type (insn))
9181 gcc_assert (operands[2] == const1_rtx);
9182 return "add{w}\t%0, %0";
9185 if (operands[2] == const1_rtx
9186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9187 return "sal{w}\t%0";
9189 return "sal{w}\t{%2, %0|%0, %2}";
9193 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9195 (match_operand 0 "register_operand" ""))
9196 (match_operand 2 "const1_operand" ""))
9197 (const_string "alu")
9199 (const_string "ishift")))
9200 (set (attr "length_immediate")
9202 (ior (eq_attr "type" "alu")
9203 (and (eq_attr "type" "ishift")
9204 (and (match_operand 2 "const1_operand" "")
9205 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9208 (const_string "*")))
9209 (set_attr "mode" "HI")])
9211 (define_insn "*ashlhi3_1_lea"
9212 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9213 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9214 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9215 (clobber (reg:CC FLAGS_REG))]
9216 "!TARGET_PARTIAL_REG_STALL
9217 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9219 switch (get_attr_type (insn))
9225 gcc_assert (operands[2] == const1_rtx);
9226 return "add{w}\t%0, %0";
9229 if (operands[2] == const1_rtx
9230 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9231 return "sal{w}\t%0";
9233 return "sal{w}\t{%2, %0|%0, %2}";
9237 (cond [(eq_attr "alternative" "1")
9238 (const_string "lea")
9239 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9241 (match_operand 0 "register_operand" ""))
9242 (match_operand 2 "const1_operand" ""))
9243 (const_string "alu")
9245 (const_string "ishift")))
9246 (set (attr "length_immediate")
9248 (ior (eq_attr "type" "alu")
9249 (and (eq_attr "type" "ishift")
9250 (and (match_operand 2 "const1_operand" "")
9251 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9254 (const_string "*")))
9255 (set_attr "mode" "HI,SI")])
9257 (define_insn "*ashlqi3_1"
9258 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9259 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9260 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9261 (clobber (reg:CC FLAGS_REG))]
9262 "TARGET_PARTIAL_REG_STALL
9263 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9265 switch (get_attr_type (insn))
9268 gcc_assert (operands[2] == const1_rtx);
9269 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9270 return "add{l}\t%k0, %k0";
9272 return "add{b}\t%0, %0";
9275 if (operands[2] == const1_rtx
9276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9278 if (get_attr_mode (insn) == MODE_SI)
9279 return "sal{l}\t%k0";
9281 return "sal{b}\t%0";
9285 if (get_attr_mode (insn) == MODE_SI)
9286 return "sal{l}\t{%2, %k0|%k0, %2}";
9288 return "sal{b}\t{%2, %0|%0, %2}";
9293 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9295 (match_operand 0 "register_operand" ""))
9296 (match_operand 2 "const1_operand" ""))
9297 (const_string "alu")
9299 (const_string "ishift")))
9300 (set (attr "length_immediate")
9302 (ior (eq_attr "type" "alu")
9303 (and (eq_attr "type" "ishift")
9304 (and (match_operand 2 "const1_operand" "")
9305 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9308 (const_string "*")))
9309 (set_attr "mode" "QI,SI")])
9311 ;; %%% Potential partial reg stall on alternative 2. What to do?
9312 (define_insn "*ashlqi3_1_lea"
9313 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9314 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9315 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "!TARGET_PARTIAL_REG_STALL
9318 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9320 switch (get_attr_type (insn))
9326 gcc_assert (operands[2] == const1_rtx);
9327 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9328 return "add{l}\t%k0, %k0";
9330 return "add{b}\t%0, %0";
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9336 if (get_attr_mode (insn) == MODE_SI)
9337 return "sal{l}\t%k0";
9339 return "sal{b}\t%0";
9343 if (get_attr_mode (insn) == MODE_SI)
9344 return "sal{l}\t{%2, %k0|%k0, %2}";
9346 return "sal{b}\t{%2, %0|%0, %2}";
9351 (cond [(eq_attr "alternative" "2")
9352 (const_string "lea")
9353 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9355 (match_operand 0 "register_operand" ""))
9356 (match_operand 2 "const1_operand" ""))
9357 (const_string "alu")
9359 (const_string "ishift")))
9360 (set (attr "length_immediate")
9362 (ior (eq_attr "type" "alu")
9363 (and (eq_attr "type" "ishift")
9364 (and (match_operand 2 "const1_operand" "")
9365 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9368 (const_string "*")))
9369 (set_attr "mode" "QI,SI,SI")])
9371 (define_insn "*ashlqi3_1_slp"
9372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9373 (ashift:QI (match_dup 0)
9374 (match_operand:QI 1 "nonmemory_operand" "cI")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "(optimize_function_for_size_p (cfun)
9377 || !TARGET_PARTIAL_FLAG_REG_STALL
9378 || (operands[1] == const1_rtx
9380 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9382 switch (get_attr_type (insn))
9385 gcc_assert (operands[1] == const1_rtx);
9386 return "add{b}\t%0, %0";
9389 if (operands[1] == const1_rtx
9390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9391 return "sal{b}\t%0";
9393 return "sal{b}\t{%1, %0|%0, %1}";
9397 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9399 (match_operand 0 "register_operand" ""))
9400 (match_operand 1 "const1_operand" ""))
9401 (const_string "alu")
9403 (const_string "ishift1")))
9404 (set (attr "length_immediate")
9406 (ior (eq_attr "type" "alu")
9407 (and (eq_attr "type" "ishift1")
9408 (and (match_operand 1 "const1_operand" "")
9409 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9412 (const_string "*")))
9413 (set_attr "mode" "QI")])
9415 ;; Convert lea to the lea pattern to avoid flags dependency.
9417 [(set (match_operand 0 "register_operand" "")
9418 (ashift (match_operand 1 "index_register_operand" "")
9419 (match_operand:QI 2 "const_int_operand" "")))
9420 (clobber (reg:CC FLAGS_REG))]
9422 && true_regnum (operands[0]) != true_regnum (operands[1])"
9426 enum machine_mode mode = GET_MODE (operands[0]);
9429 operands[1] = gen_lowpart (Pmode, operands[1]);
9430 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9432 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9434 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9435 operands[0] = gen_lowpart (SImode, operands[0]);
9437 if (TARGET_64BIT && mode != Pmode)
9438 pat = gen_rtx_SUBREG (SImode, pat, 0);
9440 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9444 ;; Convert lea to the lea pattern to avoid flags dependency.
9446 [(set (match_operand:DI 0 "register_operand" "")
9448 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9449 (match_operand:QI 2 "const_int_operand" ""))))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_64BIT && reload_completed
9452 && true_regnum (operands[0]) != true_regnum (operands[1])"
9454 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9456 operands[1] = gen_lowpart (DImode, operands[1]);
9457 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9460 ;; This pattern can't accept a variable shift count, since shifts by
9461 ;; zero don't affect the flags. We assume that shifts by constant
9462 ;; zero are optimized away.
9463 (define_insn "*ashl<mode>3_cmp"
9464 [(set (reg FLAGS_REG)
9466 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9467 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9469 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9470 (ashift:SWI (match_dup 1) (match_dup 2)))]
9471 "(optimize_function_for_size_p (cfun)
9472 || !TARGET_PARTIAL_FLAG_REG_STALL
9473 || (operands[2] == const1_rtx
9475 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9476 && ix86_match_ccmode (insn, CCGOCmode)
9477 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9479 switch (get_attr_type (insn))
9482 gcc_assert (operands[2] == const1_rtx);
9483 return "add{<imodesuffix>}\t%0, %0";
9486 if (operands[2] == const1_rtx
9487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9488 return "sal{<imodesuffix>}\t%0";
9490 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9494 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9496 (match_operand 0 "register_operand" ""))
9497 (match_operand 2 "const1_operand" ""))
9498 (const_string "alu")
9500 (const_string "ishift")))
9501 (set (attr "length_immediate")
9503 (ior (eq_attr "type" "alu")
9504 (and (eq_attr "type" "ishift")
9505 (and (match_operand 2 "const1_operand" "")
9506 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9509 (const_string "*")))
9510 (set_attr "mode" "<MODE>")])
9512 (define_insn "*ashlsi3_cmp_zext"
9513 [(set (reg FLAGS_REG)
9515 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9516 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9518 (set (match_operand:DI 0 "register_operand" "=r")
9519 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9521 && (optimize_function_for_size_p (cfun)
9522 || !TARGET_PARTIAL_FLAG_REG_STALL
9523 || (operands[2] == const1_rtx
9525 || TARGET_DOUBLE_WITH_ADD)))
9526 && ix86_match_ccmode (insn, CCGOCmode)
9527 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9529 switch (get_attr_type (insn))
9532 gcc_assert (operands[2] == const1_rtx);
9533 return "add{l}\t%k0, %k0";
9536 if (operands[2] == const1_rtx
9537 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9538 return "sal{l}\t%k0";
9540 return "sal{l}\t{%2, %k0|%k0, %2}";
9544 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9546 (match_operand 2 "const1_operand" ""))
9547 (const_string "alu")
9549 (const_string "ishift")))
9550 (set (attr "length_immediate")
9552 (ior (eq_attr "type" "alu")
9553 (and (eq_attr "type" "ishift")
9554 (and (match_operand 2 "const1_operand" "")
9555 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9558 (const_string "*")))
9559 (set_attr "mode" "SI")])
9561 (define_insn "*ashl<mode>3_cconly"
9562 [(set (reg FLAGS_REG)
9564 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9565 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9567 (clobber (match_scratch:SWI 0 "=<r>"))]
9568 "(optimize_function_for_size_p (cfun)
9569 || !TARGET_PARTIAL_FLAG_REG_STALL
9570 || (operands[2] == const1_rtx
9572 || TARGET_DOUBLE_WITH_ADD)))
9573 && ix86_match_ccmode (insn, CCGOCmode)
9574 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9576 switch (get_attr_type (insn))
9579 gcc_assert (operands[2] == const1_rtx);
9580 return "add{<imodesuffix>}\t%0, %0";
9583 if (operands[2] == const1_rtx
9584 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9585 return "sal{<imodesuffix>}\t%0";
9587 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9591 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9593 (match_operand 0 "register_operand" ""))
9594 (match_operand 2 "const1_operand" ""))
9595 (const_string "alu")
9597 (const_string "ishift")))
9598 (set (attr "length_immediate")
9600 (ior (eq_attr "type" "alu")
9601 (and (eq_attr "type" "ishift")
9602 (and (match_operand 2 "const1_operand" "")
9603 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9606 (const_string "*")))
9607 (set_attr "mode" "<MODE>")])
9609 ;; See comment above `ashl<mode>3' about how this works.
9611 (define_expand "<shiftrt_insn><mode>3"
9612 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9613 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9614 (match_operand:QI 2 "nonmemory_operand" "")))]
9616 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9618 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9619 [(set (match_operand:DWI 0 "register_operand" "=r")
9620 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9621 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9622 (clobber (reg:CC FLAGS_REG))]
9625 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9627 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9628 [(set_attr "type" "multi")])
9630 ;; By default we don't ask for a scratch register, because when DWImode
9631 ;; values are manipulated, registers are already at a premium. But if
9632 ;; we have one handy, we won't turn it away.
9635 [(match_scratch:DWIH 3 "r")
9636 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9638 (match_operand:<DWI> 1 "register_operand" "")
9639 (match_operand:QI 2 "nonmemory_operand" "")))
9640 (clobber (reg:CC FLAGS_REG))])
9644 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9646 (define_insn "x86_64_shrd"
9647 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9648 (ior:DI (ashiftrt:DI (match_dup 0)
9649 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9650 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9651 (minus:QI (const_int 64) (match_dup 2)))))
9652 (clobber (reg:CC FLAGS_REG))]
9654 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9655 [(set_attr "type" "ishift")
9656 (set_attr "prefix_0f" "1")
9657 (set_attr "mode" "DI")
9658 (set_attr "athlon_decode" "vector")
9659 (set_attr "amdfam10_decode" "vector")])
9661 (define_insn "x86_shrd"
9662 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9663 (ior:SI (ashiftrt:SI (match_dup 0)
9664 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9665 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9666 (minus:QI (const_int 32) (match_dup 2)))))
9667 (clobber (reg:CC FLAGS_REG))]
9669 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9670 [(set_attr "type" "ishift")
9671 (set_attr "prefix_0f" "1")
9672 (set_attr "mode" "SI")
9673 (set_attr "pent_pair" "np")
9674 (set_attr "athlon_decode" "vector")
9675 (set_attr "amdfam10_decode" "vector")])
9677 (define_insn "ashrdi3_cvt"
9678 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9679 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9680 (match_operand:QI 2 "const_int_operand" "")))
9681 (clobber (reg:CC FLAGS_REG))]
9682 "TARGET_64BIT && INTVAL (operands[2]) == 63
9683 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9684 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9687 sar{q}\t{%2, %0|%0, %2}"
9688 [(set_attr "type" "imovx,ishift")
9689 (set_attr "prefix_0f" "0,*")
9690 (set_attr "length_immediate" "0,*")
9691 (set_attr "modrm" "0,1")
9692 (set_attr "mode" "DI")])
9694 (define_insn "ashrsi3_cvt"
9695 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9696 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9697 (match_operand:QI 2 "const_int_operand" "")))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "INTVAL (operands[2]) == 31
9700 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9704 sar{l}\t{%2, %0|%0, %2}"
9705 [(set_attr "type" "imovx,ishift")
9706 (set_attr "prefix_0f" "0,*")
9707 (set_attr "length_immediate" "0,*")
9708 (set_attr "modrm" "0,1")
9709 (set_attr "mode" "SI")])
9711 (define_insn "*ashrsi3_cvt_zext"
9712 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9714 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9715 (match_operand:QI 2 "const_int_operand" ""))))
9716 (clobber (reg:CC FLAGS_REG))]
9717 "TARGET_64BIT && INTVAL (operands[2]) == 31
9718 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9719 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9722 sar{l}\t{%2, %k0|%k0, %2}"
9723 [(set_attr "type" "imovx,ishift")
9724 (set_attr "prefix_0f" "0,*")
9725 (set_attr "length_immediate" "0,*")
9726 (set_attr "modrm" "0,1")
9727 (set_attr "mode" "SI")])
9729 (define_expand "x86_shift<mode>_adj_3"
9730 [(use (match_operand:SWI48 0 "register_operand" ""))
9731 (use (match_operand:SWI48 1 "register_operand" ""))
9732 (use (match_operand:QI 2 "register_operand" ""))]
9735 rtx label = gen_label_rtx ();
9738 emit_insn (gen_testqi_ccz_1 (operands[2],
9739 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9741 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9742 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9743 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9744 gen_rtx_LABEL_REF (VOIDmode, label),
9746 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9747 JUMP_LABEL (tmp) = label;
9749 emit_move_insn (operands[0], operands[1]);
9750 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9751 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9753 LABEL_NUSES (label) = 1;
9758 (define_insn "*<shiftrt_insn><mode>3_1"
9759 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9760 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9761 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9762 (clobber (reg:CC FLAGS_REG))]
9763 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9765 if (operands[2] == const1_rtx
9766 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9767 return "<shiftrt>{<imodesuffix>}\t%0";
9769 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9771 [(set_attr "type" "ishift")
9772 (set (attr "length_immediate")
9774 (and (match_operand 2 "const1_operand" "")
9775 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9778 (const_string "*")))
9779 (set_attr "mode" "<MODE>")])
9781 (define_insn "*<shiftrt_insn>si3_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9784 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9785 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9789 if (operands[2] == const1_rtx
9790 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9791 return "<shiftrt>{l}\t%k0";
9793 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9795 [(set_attr "type" "ishift")
9796 (set (attr "length_immediate")
9798 (and (match_operand 2 "const1_operand" "")
9799 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9802 (const_string "*")))
9803 (set_attr "mode" "SI")])
9805 (define_insn "*<shiftrt_insn>qi3_1_slp"
9806 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9807 (any_shiftrt:QI (match_dup 0)
9808 (match_operand:QI 1 "nonmemory_operand" "cI")))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "(optimize_function_for_size_p (cfun)
9811 || !TARGET_PARTIAL_REG_STALL
9812 || (operands[1] == const1_rtx
9815 if (operands[1] == const1_rtx
9816 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9817 return "<shiftrt>{b}\t%0";
9819 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9821 [(set_attr "type" "ishift1")
9822 (set (attr "length_immediate")
9824 (and (match_operand 1 "const1_operand" "")
9825 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9828 (const_string "*")))
9829 (set_attr "mode" "QI")])
9831 ;; This pattern can't accept a variable shift count, since shifts by
9832 ;; zero don't affect the flags. We assume that shifts by constant
9833 ;; zero are optimized away.
9834 (define_insn "*<shiftrt_insn><mode>3_cmp"
9835 [(set (reg FLAGS_REG)
9838 (match_operand:SWI 1 "nonimmediate_operand" "0")
9839 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9841 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9842 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9843 "(optimize_function_for_size_p (cfun)
9844 || !TARGET_PARTIAL_FLAG_REG_STALL
9845 || (operands[2] == const1_rtx
9847 && ix86_match_ccmode (insn, CCGOCmode)
9848 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9850 if (operands[2] == const1_rtx
9851 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9852 return "<shiftrt>{<imodesuffix>}\t%0";
9854 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9856 [(set_attr "type" "ishift")
9857 (set (attr "length_immediate")
9859 (and (match_operand 2 "const1_operand" "")
9860 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9863 (const_string "*")))
9864 (set_attr "mode" "<MODE>")])
9866 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9867 [(set (reg FLAGS_REG)
9869 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9870 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9872 (set (match_operand:DI 0 "register_operand" "=r")
9873 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9875 && (optimize_function_for_size_p (cfun)
9876 || !TARGET_PARTIAL_FLAG_REG_STALL
9877 || (operands[2] == const1_rtx
9879 && ix86_match_ccmode (insn, CCGOCmode)
9880 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9882 if (operands[2] == const1_rtx
9883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884 return "<shiftrt>{l}\t%k0";
9886 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9888 [(set_attr "type" "ishift")
9889 (set (attr "length_immediate")
9891 (and (match_operand 2 "const1_operand" "")
9892 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9895 (const_string "*")))
9896 (set_attr "mode" "SI")])
9898 (define_insn "*<shiftrt_insn><mode>3_cconly"
9899 [(set (reg FLAGS_REG)
9902 (match_operand:SWI 1 "nonimmediate_operand" "0")
9903 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9905 (clobber (match_scratch:SWI 0 "=<r>"))]
9906 "(optimize_function_for_size_p (cfun)
9907 || !TARGET_PARTIAL_FLAG_REG_STALL
9908 || (operands[2] == const1_rtx
9910 && ix86_match_ccmode (insn, CCGOCmode)
9911 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9913 if (operands[2] == const1_rtx
9914 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9915 return "<shiftrt>{<imodesuffix>}\t%0";
9917 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9919 [(set_attr "type" "ishift")
9920 (set (attr "length_immediate")
9922 (and (match_operand 2 "const1_operand" "")
9923 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926 (const_string "*")))
9927 (set_attr "mode" "<MODE>")])
9929 ;; Rotate instructions
9931 (define_expand "<rotate_insn>ti3"
9932 [(set (match_operand:TI 0 "register_operand" "")
9933 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9934 (match_operand:QI 2 "nonmemory_operand" "")))]
9937 if (const_1_to_63_operand (operands[2], VOIDmode))
9938 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9939 (operands[0], operands[1], operands[2]));
9946 (define_expand "<rotate_insn>di3"
9947 [(set (match_operand:DI 0 "shiftdi_operand" "")
9948 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9949 (match_operand:QI 2 "nonmemory_operand" "")))]
9953 ix86_expand_binary_operator (<CODE>, DImode, operands);
9954 else if (const_1_to_31_operand (operands[2], VOIDmode))
9955 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9956 (operands[0], operands[1], operands[2]));
9963 (define_expand "<rotate_insn><mode>3"
9964 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9965 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9966 (match_operand:QI 2 "nonmemory_operand" "")))]
9968 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9970 ;; Implement rotation using two double-precision
9971 ;; shift instructions and a scratch register.
9973 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9974 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9975 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9976 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9977 (clobber (reg:CC FLAGS_REG))
9978 (clobber (match_scratch:DWIH 3 "=&r"))]
9982 [(set (match_dup 3) (match_dup 4))
9985 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9986 (lshiftrt:DWIH (match_dup 5)
9987 (minus:QI (match_dup 6) (match_dup 2)))))
9988 (clobber (reg:CC FLAGS_REG))])
9991 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9992 (lshiftrt:DWIH (match_dup 3)
9993 (minus:QI (match_dup 6) (match_dup 2)))))
9994 (clobber (reg:CC FLAGS_REG))])]
9996 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9998 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10001 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10002 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10003 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10004 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10005 (clobber (reg:CC FLAGS_REG))
10006 (clobber (match_scratch:DWIH 3 "=&r"))]
10010 [(set (match_dup 3) (match_dup 4))
10012 [(set (match_dup 4)
10013 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10014 (ashift:DWIH (match_dup 5)
10015 (minus:QI (match_dup 6) (match_dup 2)))))
10016 (clobber (reg:CC FLAGS_REG))])
10018 [(set (match_dup 5)
10019 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10020 (ashift:DWIH (match_dup 3)
10021 (minus:QI (match_dup 6) (match_dup 2)))))
10022 (clobber (reg:CC FLAGS_REG))])]
10024 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10026 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10029 (define_insn "*<rotate_insn><mode>3_1"
10030 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10031 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10032 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10033 (clobber (reg:CC FLAGS_REG))]
10034 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10036 if (operands[2] == const1_rtx
10037 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10038 return "<rotate>{<imodesuffix>}\t%0";
10040 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10042 [(set_attr "type" "rotate")
10043 (set (attr "length_immediate")
10045 (and (match_operand 2 "const1_operand" "")
10046 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10049 (const_string "*")))
10050 (set_attr "mode" "<MODE>")])
10052 (define_insn "*<rotate_insn>si3_1_zext"
10053 [(set (match_operand:DI 0 "register_operand" "=r")
10055 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10056 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10057 (clobber (reg:CC FLAGS_REG))]
10058 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10060 if (operands[2] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<rotate>{l}\t%k0";
10064 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10066 [(set_attr "type" "rotate")
10067 (set (attr "length_immediate")
10069 (and (match_operand 2 "const1_operand" "")
10070 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10073 (const_string "*")))
10074 (set_attr "mode" "SI")])
10076 (define_insn "*<rotate_insn>qi3_1_slp"
10077 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10078 (any_rotate:QI (match_dup 0)
10079 (match_operand:QI 1 "nonmemory_operand" "cI")))
10080 (clobber (reg:CC FLAGS_REG))]
10081 "(optimize_function_for_size_p (cfun)
10082 || !TARGET_PARTIAL_REG_STALL
10083 || (operands[1] == const1_rtx
10084 && TARGET_SHIFT1))"
10086 if (operands[1] == const1_rtx
10087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10088 return "<rotate>{b}\t%0";
10090 return "<rotate>{b}\t{%1, %0|%0, %1}";
10092 [(set_attr "type" "rotate1")
10093 (set (attr "length_immediate")
10095 (and (match_operand 1 "const1_operand" "")
10096 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10099 (const_string "*")))
10100 (set_attr "mode" "QI")])
10103 [(set (match_operand:HI 0 "register_operand" "")
10104 (any_rotate:HI (match_dup 0) (const_int 8)))
10105 (clobber (reg:CC FLAGS_REG))]
10107 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10108 [(parallel [(set (strict_low_part (match_dup 0))
10109 (bswap:HI (match_dup 0)))
10110 (clobber (reg:CC FLAGS_REG))])])
10112 ;; Bit set / bit test instructions
10114 (define_expand "extv"
10115 [(set (match_operand:SI 0 "register_operand" "")
10116 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10117 (match_operand:SI 2 "const8_operand" "")
10118 (match_operand:SI 3 "const8_operand" "")))]
10121 /* Handle extractions from %ah et al. */
10122 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10125 /* From mips.md: extract_bit_field doesn't verify that our source
10126 matches the predicate, so check it again here. */
10127 if (! ext_register_operand (operands[1], VOIDmode))
10131 (define_expand "extzv"
10132 [(set (match_operand:SI 0 "register_operand" "")
10133 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10134 (match_operand:SI 2 "const8_operand" "")
10135 (match_operand:SI 3 "const8_operand" "")))]
10138 /* Handle extractions from %ah et al. */
10139 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10142 /* From mips.md: extract_bit_field doesn't verify that our source
10143 matches the predicate, so check it again here. */
10144 if (! ext_register_operand (operands[1], VOIDmode))
10148 (define_expand "insv"
10149 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10150 (match_operand 1 "const8_operand" "")
10151 (match_operand 2 "const8_operand" ""))
10152 (match_operand 3 "register_operand" ""))]
10155 rtx (*gen_mov_insv_1) (rtx, rtx);
10157 /* Handle insertions to %ah et al. */
10158 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10161 /* From mips.md: insert_bit_field doesn't verify that our source
10162 matches the predicate, so check it again here. */
10163 if (! ext_register_operand (operands[0], VOIDmode))
10166 gen_mov_insv_1 = (TARGET_64BIT
10167 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10169 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10173 ;; %%% bts, btr, btc, bt.
10174 ;; In general these instructions are *slow* when applied to memory,
10175 ;; since they enforce atomic operation. When applied to registers,
10176 ;; it depends on the cpu implementation. They're never faster than
10177 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10178 ;; no point. But in 64-bit, we can't hold the relevant immediates
10179 ;; within the instruction itself, so operating on bits in the high
10180 ;; 32-bits of a register becomes easier.
10182 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10183 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10184 ;; negdf respectively, so they can never be disabled entirely.
10186 (define_insn "*btsq"
10187 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10189 (match_operand:DI 1 "const_0_to_63_operand" ""))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10193 "bts{q}\t{%1, %0|%0, %1}"
10194 [(set_attr "type" "alu1")
10195 (set_attr "prefix_0f" "1")
10196 (set_attr "mode" "DI")])
10198 (define_insn "*btrq"
10199 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10201 (match_operand:DI 1 "const_0_to_63_operand" ""))
10203 (clobber (reg:CC FLAGS_REG))]
10204 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10205 "btr{q}\t{%1, %0|%0, %1}"
10206 [(set_attr "type" "alu1")
10207 (set_attr "prefix_0f" "1")
10208 (set_attr "mode" "DI")])
10210 (define_insn "*btcq"
10211 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10213 (match_operand:DI 1 "const_0_to_63_operand" ""))
10214 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10217 "btc{q}\t{%1, %0|%0, %1}"
10218 [(set_attr "type" "alu1")
10219 (set_attr "prefix_0f" "1")
10220 (set_attr "mode" "DI")])
10222 ;; Allow Nocona to avoid these instructions if a register is available.
10225 [(match_scratch:DI 2 "r")
10226 (parallel [(set (zero_extract:DI
10227 (match_operand:DI 0 "register_operand" "")
10229 (match_operand:DI 1 "const_0_to_63_operand" ""))
10231 (clobber (reg:CC FLAGS_REG))])]
10232 "TARGET_64BIT && !TARGET_USE_BT"
10235 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10238 if (HOST_BITS_PER_WIDE_INT >= 64)
10239 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10240 else if (i < HOST_BITS_PER_WIDE_INT)
10241 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10243 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10245 op1 = immed_double_const (lo, hi, DImode);
10248 emit_move_insn (operands[2], op1);
10252 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10257 [(match_scratch:DI 2 "r")
10258 (parallel [(set (zero_extract:DI
10259 (match_operand:DI 0 "register_operand" "")
10261 (match_operand:DI 1 "const_0_to_63_operand" ""))
10263 (clobber (reg:CC FLAGS_REG))])]
10264 "TARGET_64BIT && !TARGET_USE_BT"
10267 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10270 if (HOST_BITS_PER_WIDE_INT >= 64)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272 else if (i < HOST_BITS_PER_WIDE_INT)
10273 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10275 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10277 op1 = immed_double_const (~lo, ~hi, DImode);
10280 emit_move_insn (operands[2], op1);
10284 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10289 [(match_scratch:DI 2 "r")
10290 (parallel [(set (zero_extract:DI
10291 (match_operand:DI 0 "register_operand" "")
10293 (match_operand:DI 1 "const_0_to_63_operand" ""))
10294 (not:DI (zero_extract:DI
10295 (match_dup 0) (const_int 1) (match_dup 1))))
10296 (clobber (reg:CC FLAGS_REG))])]
10297 "TARGET_64BIT && !TARGET_USE_BT"
10300 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10303 if (HOST_BITS_PER_WIDE_INT >= 64)
10304 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10305 else if (i < HOST_BITS_PER_WIDE_INT)
10306 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10308 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10310 op1 = immed_double_const (lo, hi, DImode);
10313 emit_move_insn (operands[2], op1);
10317 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10321 (define_insn "*bt<mode>"
10322 [(set (reg:CCC FLAGS_REG)
10324 (zero_extract:SWI48
10325 (match_operand:SWI48 0 "register_operand" "r")
10327 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10329 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10330 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10331 [(set_attr "type" "alu1")
10332 (set_attr "prefix_0f" "1")
10333 (set_attr "mode" "<MODE>")])
10335 ;; Store-flag instructions.
10337 ;; For all sCOND expanders, also expand the compare or test insn that
10338 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10340 (define_insn_and_split "*setcc_di_1"
10341 [(set (match_operand:DI 0 "register_operand" "=q")
10342 (match_operator:DI 1 "ix86_comparison_operator"
10343 [(reg FLAGS_REG) (const_int 0)]))]
10344 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10346 "&& reload_completed"
10347 [(set (match_dup 2) (match_dup 1))
10348 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10350 PUT_MODE (operands[1], QImode);
10351 operands[2] = gen_lowpart (QImode, operands[0]);
10354 (define_insn_and_split "*setcc_si_1_and"
10355 [(set (match_operand:SI 0 "register_operand" "=q")
10356 (match_operator:SI 1 "ix86_comparison_operator"
10357 [(reg FLAGS_REG) (const_int 0)]))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "!TARGET_PARTIAL_REG_STALL
10360 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10362 "&& reload_completed"
10363 [(set (match_dup 2) (match_dup 1))
10364 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10365 (clobber (reg:CC FLAGS_REG))])]
10367 PUT_MODE (operands[1], QImode);
10368 operands[2] = gen_lowpart (QImode, operands[0]);
10371 (define_insn_and_split "*setcc_si_1_movzbl"
10372 [(set (match_operand:SI 0 "register_operand" "=q")
10373 (match_operator:SI 1 "ix86_comparison_operator"
10374 [(reg FLAGS_REG) (const_int 0)]))]
10375 "!TARGET_PARTIAL_REG_STALL
10376 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10378 "&& reload_completed"
10379 [(set (match_dup 2) (match_dup 1))
10380 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10382 PUT_MODE (operands[1], QImode);
10383 operands[2] = gen_lowpart (QImode, operands[0]);
10386 (define_insn "*setcc_qi"
10387 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10388 (match_operator:QI 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)]))]
10392 [(set_attr "type" "setcc")
10393 (set_attr "mode" "QI")])
10395 (define_insn "*setcc_qi_slp"
10396 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10397 (match_operator:QI 1 "ix86_comparison_operator"
10398 [(reg FLAGS_REG) (const_int 0)]))]
10401 [(set_attr "type" "setcc")
10402 (set_attr "mode" "QI")])
10404 ;; In general it is not safe to assume too much about CCmode registers,
10405 ;; so simplify-rtx stops when it sees a second one. Under certain
10406 ;; conditions this is safe on x86, so help combine not create
10413 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10414 (ne:QI (match_operator 1 "ix86_comparison_operator"
10415 [(reg FLAGS_REG) (const_int 0)])
10418 [(set (match_dup 0) (match_dup 1))]
10419 "PUT_MODE (operands[1], QImode);")
10422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10423 (ne:QI (match_operator 1 "ix86_comparison_operator"
10424 [(reg FLAGS_REG) (const_int 0)])
10427 [(set (match_dup 0) (match_dup 1))]
10428 "PUT_MODE (operands[1], QImode);")
10431 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10432 (eq:QI (match_operator 1 "ix86_comparison_operator"
10433 [(reg FLAGS_REG) (const_int 0)])
10436 [(set (match_dup 0) (match_dup 1))]
10438 rtx new_op1 = copy_rtx (operands[1]);
10439 operands[1] = new_op1;
10440 PUT_MODE (new_op1, QImode);
10441 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10442 GET_MODE (XEXP (new_op1, 0))));
10444 /* Make sure that (a) the CCmode we have for the flags is strong
10445 enough for the reversed compare or (b) we have a valid FP compare. */
10446 if (! ix86_comparison_operator (new_op1, VOIDmode))
10451 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10452 (eq:QI (match_operator 1 "ix86_comparison_operator"
10453 [(reg FLAGS_REG) (const_int 0)])
10456 [(set (match_dup 0) (match_dup 1))]
10458 rtx new_op1 = copy_rtx (operands[1]);
10459 operands[1] = new_op1;
10460 PUT_MODE (new_op1, QImode);
10461 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10462 GET_MODE (XEXP (new_op1, 0))));
10464 /* Make sure that (a) the CCmode we have for the flags is strong
10465 enough for the reversed compare or (b) we have a valid FP compare. */
10466 if (! ix86_comparison_operator (new_op1, VOIDmode))
10470 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10471 ;; subsequent logical operations are used to imitate conditional moves.
10472 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10475 (define_insn "*avx_setcc<mode>"
10476 [(set (match_operand:MODEF 0 "register_operand" "=x")
10477 (match_operator:MODEF 1 "avx_comparison_float_operator"
10478 [(match_operand:MODEF 2 "register_operand" "x")
10479 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10481 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10482 [(set_attr "type" "ssecmp")
10483 (set_attr "prefix" "vex")
10484 (set_attr "length_immediate" "1")
10485 (set_attr "mode" "<MODE>")])
10487 (define_insn "*sse_setcc<mode>"
10488 [(set (match_operand:MODEF 0 "register_operand" "=x")
10489 (match_operator:MODEF 1 "sse_comparison_operator"
10490 [(match_operand:MODEF 2 "register_operand" "0")
10491 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10492 "SSE_FLOAT_MODE_P (<MODE>mode)"
10493 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10494 [(set_attr "type" "ssecmp")
10495 (set_attr "length_immediate" "1")
10496 (set_attr "mode" "<MODE>")])
10498 ;; Basic conditional jump instructions.
10499 ;; We ignore the overflow flag for signed branch instructions.
10501 (define_insn "*jcc_1"
10503 (if_then_else (match_operator 1 "ix86_comparison_operator"
10504 [(reg FLAGS_REG) (const_int 0)])
10505 (label_ref (match_operand 0 "" ""))
10509 [(set_attr "type" "ibr")
10510 (set_attr "modrm" "0")
10511 (set (attr "length")
10512 (if_then_else (and (ge (minus (match_dup 0) (pc))
10514 (lt (minus (match_dup 0) (pc))
10519 (define_insn "*jcc_2"
10521 (if_then_else (match_operator 1 "ix86_comparison_operator"
10522 [(reg FLAGS_REG) (const_int 0)])
10524 (label_ref (match_operand 0 "" ""))))]
10527 [(set_attr "type" "ibr")
10528 (set_attr "modrm" "0")
10529 (set (attr "length")
10530 (if_then_else (and (ge (minus (match_dup 0) (pc))
10532 (lt (minus (match_dup 0) (pc))
10537 ;; In general it is not safe to assume too much about CCmode registers,
10538 ;; so simplify-rtx stops when it sees a second one. Under certain
10539 ;; conditions this is safe on x86, so help combine not create
10547 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10548 [(reg FLAGS_REG) (const_int 0)])
10550 (label_ref (match_operand 1 "" ""))
10554 (if_then_else (match_dup 0)
10555 (label_ref (match_dup 1))
10557 "PUT_MODE (operands[0], VOIDmode);")
10561 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)])
10564 (label_ref (match_operand 1 "" ""))
10568 (if_then_else (match_dup 0)
10569 (label_ref (match_dup 1))
10572 rtx new_op0 = copy_rtx (operands[0]);
10573 operands[0] = new_op0;
10574 PUT_MODE (new_op0, VOIDmode);
10575 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10576 GET_MODE (XEXP (new_op0, 0))));
10578 /* Make sure that (a) the CCmode we have for the flags is strong
10579 enough for the reversed compare or (b) we have a valid FP compare. */
10580 if (! ix86_comparison_operator (new_op0, VOIDmode))
10584 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10585 ;; pass generates from shift insn with QImode operand. Actually, the mode
10586 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10587 ;; appropriate modulo of the bit offset value.
10589 (define_insn_and_split "*jcc_bt<mode>"
10591 (if_then_else (match_operator 0 "bt_comparison_operator"
10592 [(zero_extract:SWI48
10593 (match_operand:SWI48 1 "register_operand" "r")
10596 (match_operand:QI 2 "register_operand" "r")))
10598 (label_ref (match_operand 3 "" ""))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10604 [(set (reg:CCC FLAGS_REG)
10606 (zero_extract:SWI48
10612 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10613 (label_ref (match_dup 3))
10616 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10618 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10621 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10622 ;; also for DImode, this is what combine produces.
10623 (define_insn_and_split "*jcc_bt<mode>_mask"
10625 (if_then_else (match_operator 0 "bt_comparison_operator"
10626 [(zero_extract:SWI48
10627 (match_operand:SWI48 1 "register_operand" "r")
10630 (match_operand:SI 2 "register_operand" "r")
10631 (match_operand:SI 3 "const_int_operand" "n")))])
10632 (label_ref (match_operand 4 "" ""))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10636 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10637 == GET_MODE_BITSIZE (<MODE>mode)-1"
10640 [(set (reg:CCC FLAGS_REG)
10642 (zero_extract:SWI48
10648 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10649 (label_ref (match_dup 4))
10652 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10654 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10657 (define_insn_and_split "*jcc_btsi_1"
10659 (if_then_else (match_operator 0 "bt_comparison_operator"
10662 (match_operand:SI 1 "register_operand" "r")
10663 (match_operand:QI 2 "register_operand" "r"))
10666 (label_ref (match_operand 3 "" ""))
10668 (clobber (reg:CC FLAGS_REG))]
10669 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10672 [(set (reg:CCC FLAGS_REG)
10680 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10681 (label_ref (match_dup 3))
10684 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10686 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10689 ;; avoid useless masking of bit offset operand
10690 (define_insn_and_split "*jcc_btsi_mask_1"
10693 (match_operator 0 "bt_comparison_operator"
10696 (match_operand:SI 1 "register_operand" "r")
10699 (match_operand:SI 2 "register_operand" "r")
10700 (match_operand:SI 3 "const_int_operand" "n")) 0))
10703 (label_ref (match_operand 4 "" ""))
10705 (clobber (reg:CC FLAGS_REG))]
10706 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10707 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10710 [(set (reg:CCC FLAGS_REG)
10718 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10719 (label_ref (match_dup 4))
10721 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10723 ;; Define combination compare-and-branch fp compare instructions to help
10726 (define_insn "*fp_jcc_1_387"
10728 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10729 [(match_operand 1 "register_operand" "f")
10730 (match_operand 2 "nonimmediate_operand" "fm")])
10731 (label_ref (match_operand 3 "" ""))
10733 (clobber (reg:CCFP FPSR_REG))
10734 (clobber (reg:CCFP FLAGS_REG))
10735 (clobber (match_scratch:HI 4 "=a"))]
10737 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10738 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10739 && SELECT_CC_MODE (GET_CODE (operands[0]),
10740 operands[1], operands[2]) == CCFPmode
10744 (define_insn "*fp_jcc_1r_387"
10746 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10747 [(match_operand 1 "register_operand" "f")
10748 (match_operand 2 "nonimmediate_operand" "fm")])
10750 (label_ref (match_operand 3 "" ""))))
10751 (clobber (reg:CCFP FPSR_REG))
10752 (clobber (reg:CCFP FLAGS_REG))
10753 (clobber (match_scratch:HI 4 "=a"))]
10755 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10756 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10757 && SELECT_CC_MODE (GET_CODE (operands[0]),
10758 operands[1], operands[2]) == CCFPmode
10762 (define_insn "*fp_jcc_2_387"
10764 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10765 [(match_operand 1 "register_operand" "f")
10766 (match_operand 2 "register_operand" "f")])
10767 (label_ref (match_operand 3 "" ""))
10769 (clobber (reg:CCFP FPSR_REG))
10770 (clobber (reg:CCFP FLAGS_REG))
10771 (clobber (match_scratch:HI 4 "=a"))]
10772 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10773 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10777 (define_insn "*fp_jcc_2r_387"
10779 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10780 [(match_operand 1 "register_operand" "f")
10781 (match_operand 2 "register_operand" "f")])
10783 (label_ref (match_operand 3 "" ""))))
10784 (clobber (reg:CCFP FPSR_REG))
10785 (clobber (reg:CCFP FLAGS_REG))
10786 (clobber (match_scratch:HI 4 "=a"))]
10787 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10792 (define_insn "*fp_jcc_3_387"
10794 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10795 [(match_operand 1 "register_operand" "f")
10796 (match_operand 2 "const0_operand" "")])
10797 (label_ref (match_operand 3 "" ""))
10799 (clobber (reg:CCFP FPSR_REG))
10800 (clobber (reg:CCFP FLAGS_REG))
10801 (clobber (match_scratch:HI 4 "=a"))]
10802 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10803 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10804 && SELECT_CC_MODE (GET_CODE (operands[0]),
10805 operands[1], operands[2]) == CCFPmode
10811 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10812 [(match_operand 1 "register_operand" "")
10813 (match_operand 2 "nonimmediate_operand" "")])
10814 (match_operand 3 "" "")
10815 (match_operand 4 "" "")))
10816 (clobber (reg:CCFP FPSR_REG))
10817 (clobber (reg:CCFP FLAGS_REG))]
10821 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10822 operands[3], operands[4], NULL_RTX, NULL_RTX);
10828 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10829 [(match_operand 1 "register_operand" "")
10830 (match_operand 2 "general_operand" "")])
10831 (match_operand 3 "" "")
10832 (match_operand 4 "" "")))
10833 (clobber (reg:CCFP FPSR_REG))
10834 (clobber (reg:CCFP FLAGS_REG))
10835 (clobber (match_scratch:HI 5 "=a"))]
10839 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10840 operands[3], operands[4], operands[5], NULL_RTX);
10844 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10845 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10846 ;; with a precedence over other operators and is always put in the first
10847 ;; place. Swap condition and operands to match ficom instruction.
10849 (define_insn "*fp_jcc_4_<mode>_387"
10852 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10853 [(match_operator 1 "float_operator"
10854 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10855 (match_operand 3 "register_operand" "f,f")])
10856 (label_ref (match_operand 4 "" ""))
10858 (clobber (reg:CCFP FPSR_REG))
10859 (clobber (reg:CCFP FLAGS_REG))
10860 (clobber (match_scratch:HI 5 "=a,a"))]
10861 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10862 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10863 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10864 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10871 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10872 [(match_operator 1 "float_operator"
10873 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10874 (match_operand 3 "register_operand" "")])
10875 (match_operand 4 "" "")
10876 (match_operand 5 "" "")))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 6 "=a"))]
10883 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10885 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10886 operands[3], operands[7],
10887 operands[4], operands[5], operands[6], NULL_RTX);
10891 ;; %%% Kill this when reload knows how to do it.
10895 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896 [(match_operator 1 "float_operator"
10897 [(match_operand:X87MODEI12 2 "register_operand" "")])
10898 (match_operand 3 "register_operand" "")])
10899 (match_operand 4 "" "")
10900 (match_operand 5 "" "")))
10901 (clobber (reg:CCFP FPSR_REG))
10902 (clobber (reg:CCFP FLAGS_REG))
10903 (clobber (match_scratch:HI 6 "=a"))]
10907 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10908 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10910 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10911 operands[3], operands[7],
10912 operands[4], operands[5], operands[6], operands[2]);
10916 ;; Unconditional and other jump instructions
10918 (define_insn "jump"
10920 (label_ref (match_operand 0 "" "")))]
10923 [(set_attr "type" "ibr")
10924 (set (attr "length")
10925 (if_then_else (and (ge (minus (match_dup 0) (pc))
10927 (lt (minus (match_dup 0) (pc))
10931 (set_attr "modrm" "0")])
10933 (define_expand "indirect_jump"
10934 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10938 (define_insn "*indirect_jump"
10939 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10942 [(set_attr "type" "ibr")
10943 (set_attr "length_immediate" "0")])
10945 (define_expand "tablejump"
10946 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10947 (use (label_ref (match_operand 1 "" "")))])]
10950 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10951 relative. Convert the relative address to an absolute address. */
10955 enum rtx_code code;
10957 /* We can't use @GOTOFF for text labels on VxWorks;
10958 see gotoff_operand. */
10959 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10963 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10965 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10969 op1 = pic_offset_table_rtx;
10974 op0 = pic_offset_table_rtx;
10978 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10983 (define_insn "*tablejump_1"
10984 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10985 (use (label_ref (match_operand 1 "" "")))]
10988 [(set_attr "type" "ibr")
10989 (set_attr "length_immediate" "0")])
10991 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10994 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10995 (set (match_operand:QI 1 "register_operand" "")
10996 (match_operator:QI 2 "ix86_comparison_operator"
10997 [(reg FLAGS_REG) (const_int 0)]))
10998 (set (match_operand 3 "q_regs_operand" "")
10999 (zero_extend (match_dup 1)))]
11000 "(peep2_reg_dead_p (3, operands[1])
11001 || operands_match_p (operands[1], operands[3]))
11002 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11003 [(set (match_dup 4) (match_dup 0))
11004 (set (strict_low_part (match_dup 5))
11007 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11008 operands[5] = gen_lowpart (QImode, operands[3]);
11009 ix86_expand_clear (operands[3]);
11012 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11015 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11016 (set (match_operand:QI 1 "register_operand" "")
11017 (match_operator:QI 2 "ix86_comparison_operator"
11018 [(reg FLAGS_REG) (const_int 0)]))
11019 (parallel [(set (match_operand 3 "q_regs_operand" "")
11020 (zero_extend (match_dup 1)))
11021 (clobber (reg:CC FLAGS_REG))])]
11022 "(peep2_reg_dead_p (3, operands[1])
11023 || operands_match_p (operands[1], operands[3]))
11024 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11025 [(set (match_dup 4) (match_dup 0))
11026 (set (strict_low_part (match_dup 5))
11029 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11030 operands[5] = gen_lowpart (QImode, operands[3]);
11031 ix86_expand_clear (operands[3]);
11034 ;; Call instructions.
11036 ;; The predicates normally associated with named expanders are not properly
11037 ;; checked for calls. This is a bug in the generic code, but it isn't that
11038 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11040 ;; P6 processors will jump to the address after the decrement when %esp
11041 ;; is used as a call operand, so they will execute return address as a code.
11042 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11044 ;; Call subroutine returning no value.
11046 (define_expand "call_pop"
11047 [(parallel [(call (match_operand:QI 0 "" "")
11048 (match_operand:SI 1 "" ""))
11049 (set (reg:SI SP_REG)
11050 (plus:SI (reg:SI SP_REG)
11051 (match_operand:SI 3 "" "")))])]
11054 ix86_expand_call (NULL, operands[0], operands[1],
11055 operands[2], operands[3], 0);
11059 (define_insn "*call_pop_0"
11060 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11061 (match_operand:SI 1 "" ""))
11062 (set (reg:SI SP_REG)
11063 (plus:SI (reg:SI SP_REG)
11064 (match_operand:SI 2 "immediate_operand" "")))]
11067 if (SIBLING_CALL_P (insn))
11070 return "call\t%P0";
11072 [(set_attr "type" "call")])
11074 (define_insn "*call_pop_1"
11075 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11076 (match_operand:SI 1 "" ""))
11077 (set (reg:SI SP_REG)
11078 (plus:SI (reg:SI SP_REG)
11079 (match_operand:SI 2 "immediate_operand" "i")))]
11080 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11082 if (constant_call_address_operand (operands[0], Pmode))
11083 return "call\t%P0";
11084 return "call\t%A0";
11086 [(set_attr "type" "call")])
11088 (define_insn "*sibcall_pop_1"
11089 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11090 (match_operand:SI 1 "" ""))
11091 (set (reg:SI SP_REG)
11092 (plus:SI (reg:SI SP_REG)
11093 (match_operand:SI 2 "immediate_operand" "i,i")))]
11094 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11098 [(set_attr "type" "call")])
11100 (define_expand "call"
11101 [(call (match_operand:QI 0 "" "")
11102 (match_operand 1 "" ""))
11103 (use (match_operand 2 "" ""))]
11106 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11110 (define_expand "sibcall"
11111 [(call (match_operand:QI 0 "" "")
11112 (match_operand 1 "" ""))
11113 (use (match_operand 2 "" ""))]
11116 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11120 (define_insn "*call_0"
11121 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11122 (match_operand 1 "" ""))]
11125 if (SIBLING_CALL_P (insn))
11128 return "call\t%P0";
11130 [(set_attr "type" "call")])
11132 (define_insn "*call_1"
11133 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11134 (match_operand 1 "" ""))]
11135 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11137 if (constant_call_address_operand (operands[0], Pmode))
11138 return "call\t%P0";
11139 return "call\t%A0";
11141 [(set_attr "type" "call")])
11143 (define_insn "*sibcall_1"
11144 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11145 (match_operand 1 "" ""))]
11146 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11150 [(set_attr "type" "call")])
11152 (define_insn "*call_1_rex64"
11153 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11154 (match_operand 1 "" ""))]
11155 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11156 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11158 if (constant_call_address_operand (operands[0], Pmode))
11159 return "call\t%P0";
11160 return "call\t%A0";
11162 [(set_attr "type" "call")])
11164 (define_insn "*call_1_rex64_ms_sysv"
11165 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11166 (match_operand 1 "" ""))
11167 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11168 (clobber (reg:TI XMM6_REG))
11169 (clobber (reg:TI XMM7_REG))
11170 (clobber (reg:TI XMM8_REG))
11171 (clobber (reg:TI XMM9_REG))
11172 (clobber (reg:TI XMM10_REG))
11173 (clobber (reg:TI XMM11_REG))
11174 (clobber (reg:TI XMM12_REG))
11175 (clobber (reg:TI XMM13_REG))
11176 (clobber (reg:TI XMM14_REG))
11177 (clobber (reg:TI XMM15_REG))
11178 (clobber (reg:DI SI_REG))
11179 (clobber (reg:DI DI_REG))]
11180 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11182 if (constant_call_address_operand (operands[0], Pmode))
11183 return "call\t%P0";
11184 return "call\t%A0";
11186 [(set_attr "type" "call")])
11188 (define_insn "*call_1_rex64_large"
11189 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11190 (match_operand 1 "" ""))]
11191 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11193 [(set_attr "type" "call")])
11195 (define_insn "*sibcall_1_rex64"
11196 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11197 (match_operand 1 "" ""))]
11198 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11202 [(set_attr "type" "call")])
11204 ;; Call subroutine, returning value in operand 0
11205 (define_expand "call_value_pop"
11206 [(parallel [(set (match_operand 0 "" "")
11207 (call (match_operand:QI 1 "" "")
11208 (match_operand:SI 2 "" "")))
11209 (set (reg:SI SP_REG)
11210 (plus:SI (reg:SI SP_REG)
11211 (match_operand:SI 4 "" "")))])]
11214 ix86_expand_call (operands[0], operands[1], operands[2],
11215 operands[3], operands[4], 0);
11219 (define_expand "call_value"
11220 [(set (match_operand 0 "" "")
11221 (call (match_operand:QI 1 "" "")
11222 (match_operand:SI 2 "" "")))
11223 (use (match_operand:SI 3 "" ""))]
11224 ;; Operand 3 is not used on the i386.
11227 ix86_expand_call (operands[0], operands[1], operands[2],
11228 operands[3], NULL, 0);
11232 (define_expand "sibcall_value"
11233 [(set (match_operand 0 "" "")
11234 (call (match_operand:QI 1 "" "")
11235 (match_operand:SI 2 "" "")))
11236 (use (match_operand:SI 3 "" ""))]
11237 ;; Operand 3 is not used on the i386.
11240 ix86_expand_call (operands[0], operands[1], operands[2],
11241 operands[3], NULL, 1);
11245 ;; Call subroutine returning any type.
11247 (define_expand "untyped_call"
11248 [(parallel [(call (match_operand 0 "" "")
11250 (match_operand 1 "" "")
11251 (match_operand 2 "" "")])]
11256 /* In order to give reg-stack an easier job in validating two
11257 coprocessor registers as containing a possible return value,
11258 simply pretend the untyped call returns a complex long double
11261 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11262 and should have the default ABI. */
11264 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11265 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11266 operands[0], const0_rtx,
11267 GEN_INT ((TARGET_64BIT
11268 ? (ix86_abi == SYSV_ABI
11269 ? X86_64_SSE_REGPARM_MAX
11270 : X86_64_MS_SSE_REGPARM_MAX)
11271 : X86_32_SSE_REGPARM_MAX)
11275 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11277 rtx set = XVECEXP (operands[2], 0, i);
11278 emit_move_insn (SET_DEST (set), SET_SRC (set));
11281 /* The optimizer does not know that the call sets the function value
11282 registers we stored in the result block. We avoid problems by
11283 claiming that all hard registers are used and clobbered at this
11285 emit_insn (gen_blockage ());
11290 ;; Prologue and epilogue instructions
11292 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11293 ;; all of memory. This blocks insns from being moved across this point.
11295 (define_insn "blockage"
11296 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11299 [(set_attr "length" "0")])
11301 ;; Do not schedule instructions accessing memory across this point.
11303 (define_expand "memory_blockage"
11304 [(set (match_dup 0)
11305 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11308 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11309 MEM_VOLATILE_P (operands[0]) = 1;
11312 (define_insn "*memory_blockage"
11313 [(set (match_operand:BLK 0 "" "")
11314 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11317 [(set_attr "length" "0")])
11319 ;; As USE insns aren't meaningful after reload, this is used instead
11320 ;; to prevent deleting instructions setting registers for PIC code
11321 (define_insn "prologue_use"
11322 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11325 [(set_attr "length" "0")])
11327 ;; Insn emitted into the body of a function to return from a function.
11328 ;; This is only done if the function's epilogue is known to be simple.
11329 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11331 (define_expand "return"
11333 "ix86_can_use_return_insn_p ()"
11335 if (crtl->args.pops_args)
11337 rtx popc = GEN_INT (crtl->args.pops_args);
11338 emit_jump_insn (gen_return_pop_internal (popc));
11343 (define_insn "return_internal"
11347 [(set_attr "length" "1")
11348 (set_attr "atom_unit" "jeu")
11349 (set_attr "length_immediate" "0")
11350 (set_attr "modrm" "0")])
11352 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11353 ;; instruction Athlon and K8 have.
11355 (define_insn "return_internal_long"
11357 (unspec [(const_int 0)] UNSPEC_REP)]
11360 [(set_attr "length" "2")
11361 (set_attr "atom_unit" "jeu")
11362 (set_attr "length_immediate" "0")
11363 (set_attr "prefix_rep" "1")
11364 (set_attr "modrm" "0")])
11366 (define_insn "return_pop_internal"
11368 (use (match_operand:SI 0 "const_int_operand" ""))]
11371 [(set_attr "length" "3")
11372 (set_attr "atom_unit" "jeu")
11373 (set_attr "length_immediate" "2")
11374 (set_attr "modrm" "0")])
11376 (define_insn "return_indirect_internal"
11378 (use (match_operand:SI 0 "register_operand" "r"))]
11381 [(set_attr "type" "ibr")
11382 (set_attr "length_immediate" "0")])
11388 [(set_attr "length" "1")
11389 (set_attr "length_immediate" "0")
11390 (set_attr "modrm" "0")])
11392 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11393 ;; branch prediction penalty for the third jump in a 16-byte
11397 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11400 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11401 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11403 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11404 The align insn is used to avoid 3 jump instructions in the row to improve
11405 branch prediction and the benefits hardly outweigh the cost of extra 8
11406 nops on the average inserted by full alignment pseudo operation. */
11410 [(set_attr "length" "16")])
11412 (define_expand "prologue"
11415 "ix86_expand_prologue (); DONE;")
11417 (define_insn "set_got"
11418 [(set (match_operand:SI 0 "register_operand" "=r")
11419 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11420 (clobber (reg:CC FLAGS_REG))]
11422 { return output_set_got (operands[0], NULL_RTX); }
11423 [(set_attr "type" "multi")
11424 (set_attr "length" "12")])
11426 (define_insn "set_got_labelled"
11427 [(set (match_operand:SI 0 "register_operand" "=r")
11428 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11430 (clobber (reg:CC FLAGS_REG))]
11432 { return output_set_got (operands[0], operands[1]); }
11433 [(set_attr "type" "multi")
11434 (set_attr "length" "12")])
11436 (define_insn "set_got_rex64"
11437 [(set (match_operand:DI 0 "register_operand" "=r")
11438 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11440 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11441 [(set_attr "type" "lea")
11442 (set_attr "length_address" "4")
11443 (set_attr "mode" "DI")])
11445 (define_insn "set_rip_rex64"
11446 [(set (match_operand:DI 0 "register_operand" "=r")
11447 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11449 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11450 [(set_attr "type" "lea")
11451 (set_attr "length_address" "4")
11452 (set_attr "mode" "DI")])
11454 (define_insn "set_got_offset_rex64"
11455 [(set (match_operand:DI 0 "register_operand" "=r")
11457 [(label_ref (match_operand 1 "" ""))]
11458 UNSPEC_SET_GOT_OFFSET))]
11460 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11461 [(set_attr "type" "imov")
11462 (set_attr "length_immediate" "0")
11463 (set_attr "length_address" "8")
11464 (set_attr "mode" "DI")])
11466 (define_expand "epilogue"
11469 "ix86_expand_epilogue (1); DONE;")
11471 (define_expand "sibcall_epilogue"
11474 "ix86_expand_epilogue (0); DONE;")
11476 (define_expand "eh_return"
11477 [(use (match_operand 0 "register_operand" ""))]
11480 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11482 /* Tricky bit: we write the address of the handler to which we will
11483 be returning into someone else's stack frame, one word below the
11484 stack address we wish to restore. */
11485 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11486 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11487 tmp = gen_rtx_MEM (Pmode, tmp);
11488 emit_move_insn (tmp, ra);
11490 emit_jump_insn (gen_eh_return_internal ());
11495 (define_insn_and_split "eh_return_internal"
11499 "epilogue_completed"
11501 "ix86_expand_epilogue (2); DONE;")
11503 (define_insn "leave"
11504 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11505 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11506 (clobber (mem:BLK (scratch)))]
11509 [(set_attr "type" "leave")])
11511 (define_insn "leave_rex64"
11512 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11513 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11514 (clobber (mem:BLK (scratch)))]
11517 [(set_attr "type" "leave")])
11519 ;; Bit manipulation instructions.
11521 (define_expand "ffs<mode>2"
11522 [(set (match_dup 2) (const_int -1))
11523 (parallel [(set (reg:CCZ FLAGS_REG)
11525 (match_operand:SWI48 1 "nonimmediate_operand" "")
11527 (set (match_operand:SWI48 0 "register_operand" "")
11528 (ctz:SWI48 (match_dup 1)))])
11529 (set (match_dup 0) (if_then_else:SWI48
11530 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11533 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11534 (clobber (reg:CC FLAGS_REG))])]
11537 if (<MODE>mode == SImode && !TARGET_CMOVE)
11539 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11542 operands[2] = gen_reg_rtx (<MODE>mode);
11545 (define_insn_and_split "ffssi2_no_cmove"
11546 [(set (match_operand:SI 0 "register_operand" "=r")
11547 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11548 (clobber (match_scratch:SI 2 "=&q"))
11549 (clobber (reg:CC FLAGS_REG))]
11552 "&& reload_completed"
11553 [(parallel [(set (reg:CCZ FLAGS_REG)
11554 (compare:CCZ (match_dup 1) (const_int 0)))
11555 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11556 (set (strict_low_part (match_dup 3))
11557 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11558 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11559 (clobber (reg:CC FLAGS_REG))])
11560 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11561 (clobber (reg:CC FLAGS_REG))])
11562 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11563 (clobber (reg:CC FLAGS_REG))])]
11565 operands[3] = gen_lowpart (QImode, operands[2]);
11566 ix86_expand_clear (operands[2]);
11569 (define_insn "*ffs<mode>_1"
11570 [(set (reg:CCZ FLAGS_REG)
11571 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11573 (set (match_operand:SWI48 0 "register_operand" "=r")
11574 (ctz:SWI48 (match_dup 1)))]
11576 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11577 [(set_attr "type" "alu1")
11578 (set_attr "prefix_0f" "1")
11579 (set_attr "mode" "<MODE>")])
11581 (define_insn "ctz<mode>2"
11582 [(set (match_operand:SWI48 0 "register_operand" "=r")
11583 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11584 (clobber (reg:CC FLAGS_REG))]
11586 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11587 [(set_attr "type" "alu1")
11588 (set_attr "prefix_0f" "1")
11589 (set_attr "mode" "<MODE>")])
11591 (define_expand "clz<mode>2"
11593 [(set (match_operand:SWI248 0 "register_operand" "")
11596 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11597 (clobber (reg:CC FLAGS_REG))])
11599 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11600 (clobber (reg:CC FLAGS_REG))])]
11605 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11608 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11611 (define_insn "clz<mode>2_abm"
11612 [(set (match_operand:SWI248 0 "register_operand" "=r")
11613 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11614 (clobber (reg:CC FLAGS_REG))]
11616 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11617 [(set_attr "prefix_rep" "1")
11618 (set_attr "type" "bitmanip")
11619 (set_attr "mode" "<MODE>")])
11621 (define_insn "bsr_rex64"
11622 [(set (match_operand:DI 0 "register_operand" "=r")
11623 (minus:DI (const_int 63)
11624 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11625 (clobber (reg:CC FLAGS_REG))]
11627 "bsr{q}\t{%1, %0|%0, %1}"
11628 [(set_attr "type" "alu1")
11629 (set_attr "prefix_0f" "1")
11630 (set_attr "mode" "DI")])
11633 [(set (match_operand:SI 0 "register_operand" "=r")
11634 (minus:SI (const_int 31)
11635 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11636 (clobber (reg:CC FLAGS_REG))]
11638 "bsr{l}\t{%1, %0|%0, %1}"
11639 [(set_attr "type" "alu1")
11640 (set_attr "prefix_0f" "1")
11641 (set_attr "mode" "SI")])
11643 (define_insn "*bsrhi"
11644 [(set (match_operand:HI 0 "register_operand" "=r")
11645 (minus:HI (const_int 15)
11646 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11647 (clobber (reg:CC FLAGS_REG))]
11649 "bsr{w}\t{%1, %0|%0, %1}"
11650 [(set_attr "type" "alu1")
11651 (set_attr "prefix_0f" "1")
11652 (set_attr "mode" "HI")])
11654 (define_insn "popcount<mode>2"
11655 [(set (match_operand:SWI248 0 "register_operand" "=r")
11657 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11658 (clobber (reg:CC FLAGS_REG))]
11662 return "popcnt\t{%1, %0|%0, %1}";
11664 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11667 [(set_attr "prefix_rep" "1")
11668 (set_attr "type" "bitmanip")
11669 (set_attr "mode" "<MODE>")])
11671 (define_insn "*popcount<mode>2_cmp"
11672 [(set (reg FLAGS_REG)
11675 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11677 (set (match_operand:SWI248 0 "register_operand" "=r")
11678 (popcount:SWI248 (match_dup 1)))]
11679 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11682 return "popcnt\t{%1, %0|%0, %1}";
11684 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11687 [(set_attr "prefix_rep" "1")
11688 (set_attr "type" "bitmanip")
11689 (set_attr "mode" "<MODE>")])
11691 (define_insn "*popcountsi2_cmp_zext"
11692 [(set (reg FLAGS_REG)
11694 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11696 (set (match_operand:DI 0 "register_operand" "=r")
11697 (zero_extend:DI(popcount:SI (match_dup 1))))]
11698 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11701 return "popcnt\t{%1, %0|%0, %1}";
11703 return "popcnt{l}\t{%1, %0|%0, %1}";
11706 [(set_attr "prefix_rep" "1")
11707 (set_attr "type" "bitmanip")
11708 (set_attr "mode" "SI")])
11710 (define_expand "bswap<mode>2"
11711 [(set (match_operand:SWI48 0 "register_operand" "")
11712 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11715 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11717 rtx x = operands[0];
11719 emit_move_insn (x, operands[1]);
11720 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11721 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11722 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11727 (define_insn "*bswap<mode>2_movbe"
11728 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11729 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11731 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11734 movbe\t{%1, %0|%0, %1}
11735 movbe\t{%1, %0|%0, %1}"
11736 [(set_attr "type" "bitmanip,imov,imov")
11737 (set_attr "modrm" "0,1,1")
11738 (set_attr "prefix_0f" "*,1,1")
11739 (set_attr "prefix_extra" "*,1,1")
11740 (set_attr "mode" "<MODE>")])
11742 (define_insn "*bswap<mode>2_1"
11743 [(set (match_operand:SWI48 0 "register_operand" "=r")
11744 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11747 [(set_attr "type" "bitmanip")
11748 (set_attr "modrm" "0")
11749 (set_attr "mode" "<MODE>")])
11751 (define_insn "*bswaphi_lowpart_1"
11752 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11753 (bswap:HI (match_dup 0)))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11757 xchg{b}\t{%h0, %b0|%b0, %h0}
11758 rol{w}\t{$8, %0|%0, 8}"
11759 [(set_attr "length" "2,4")
11760 (set_attr "mode" "QI,HI")])
11762 (define_insn "bswaphi_lowpart"
11763 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11764 (bswap:HI (match_dup 0)))
11765 (clobber (reg:CC FLAGS_REG))]
11767 "rol{w}\t{$8, %0|%0, 8}"
11768 [(set_attr "length" "4")
11769 (set_attr "mode" "HI")])
11771 (define_expand "paritydi2"
11772 [(set (match_operand:DI 0 "register_operand" "")
11773 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11776 rtx scratch = gen_reg_rtx (QImode);
11779 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11780 NULL_RTX, operands[1]));
11782 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11783 gen_rtx_REG (CCmode, FLAGS_REG),
11785 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11788 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11791 rtx tmp = gen_reg_rtx (SImode);
11793 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11794 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11799 (define_expand "paritysi2"
11800 [(set (match_operand:SI 0 "register_operand" "")
11801 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11804 rtx scratch = gen_reg_rtx (QImode);
11807 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11809 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11810 gen_rtx_REG (CCmode, FLAGS_REG),
11812 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11814 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11818 (define_insn_and_split "paritydi2_cmp"
11819 [(set (reg:CC FLAGS_REG)
11820 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11822 (clobber (match_scratch:DI 0 "=r"))
11823 (clobber (match_scratch:SI 1 "=&r"))
11824 (clobber (match_scratch:HI 2 "=Q"))]
11827 "&& reload_completed"
11829 [(set (match_dup 1)
11830 (xor:SI (match_dup 1) (match_dup 4)))
11831 (clobber (reg:CC FLAGS_REG))])
11833 [(set (reg:CC FLAGS_REG)
11834 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11835 (clobber (match_dup 1))
11836 (clobber (match_dup 2))])]
11838 operands[4] = gen_lowpart (SImode, operands[3]);
11842 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11843 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11846 operands[1] = gen_highpart (SImode, operands[3]);
11849 (define_insn_and_split "paritysi2_cmp"
11850 [(set (reg:CC FLAGS_REG)
11851 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11853 (clobber (match_scratch:SI 0 "=r"))
11854 (clobber (match_scratch:HI 1 "=&Q"))]
11857 "&& reload_completed"
11859 [(set (match_dup 1)
11860 (xor:HI (match_dup 1) (match_dup 3)))
11861 (clobber (reg:CC FLAGS_REG))])
11863 [(set (reg:CC FLAGS_REG)
11864 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11865 (clobber (match_dup 1))])]
11867 operands[3] = gen_lowpart (HImode, operands[2]);
11869 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11870 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11873 (define_insn "*parityhi2_cmp"
11874 [(set (reg:CC FLAGS_REG)
11875 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11877 (clobber (match_scratch:HI 0 "=Q"))]
11879 "xor{b}\t{%h0, %b0|%b0, %h0}"
11880 [(set_attr "length" "2")
11881 (set_attr "mode" "HI")])
11883 ;; Thread-local storage patterns for ELF.
11885 ;; Note that these code sequences must appear exactly as shown
11886 ;; in order to allow linker relaxation.
11888 (define_insn "*tls_global_dynamic_32_gnu"
11889 [(set (match_operand:SI 0 "register_operand" "=a")
11890 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11891 (match_operand:SI 2 "tls_symbolic_operand" "")
11892 (match_operand:SI 3 "call_insn_operand" "")]
11894 (clobber (match_scratch:SI 4 "=d"))
11895 (clobber (match_scratch:SI 5 "=c"))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "!TARGET_64BIT && TARGET_GNU_TLS"
11898 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11899 [(set_attr "type" "multi")
11900 (set_attr "length" "12")])
11902 (define_expand "tls_global_dynamic_32"
11903 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11906 (match_operand:SI 1 "tls_symbolic_operand" "")
11909 (clobber (match_scratch:SI 4 ""))
11910 (clobber (match_scratch:SI 5 ""))
11911 (clobber (reg:CC FLAGS_REG))])]
11915 operands[2] = pic_offset_table_rtx;
11918 operands[2] = gen_reg_rtx (Pmode);
11919 emit_insn (gen_set_got (operands[2]));
11921 if (TARGET_GNU2_TLS)
11923 emit_insn (gen_tls_dynamic_gnu2_32
11924 (operands[0], operands[1], operands[2]));
11927 operands[3] = ix86_tls_get_addr ();
11930 (define_insn "*tls_global_dynamic_64"
11931 [(set (match_operand:DI 0 "register_operand" "=a")
11932 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11933 (match_operand:DI 3 "" "")))
11934 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11937 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
11938 [(set_attr "type" "multi")
11939 (set_attr "length" "16")])
11941 (define_expand "tls_global_dynamic_64"
11942 [(parallel [(set (match_operand:DI 0 "register_operand" "")
11943 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11944 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11948 if (TARGET_GNU2_TLS)
11950 emit_insn (gen_tls_dynamic_gnu2_64
11951 (operands[0], operands[1]));
11954 operands[2] = ix86_tls_get_addr ();
11957 (define_insn "*tls_local_dynamic_base_32_gnu"
11958 [(set (match_operand:SI 0 "register_operand" "=a")
11959 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11960 (match_operand:SI 2 "call_insn_operand" "")]
11961 UNSPEC_TLS_LD_BASE))
11962 (clobber (match_scratch:SI 3 "=d"))
11963 (clobber (match_scratch:SI 4 "=c"))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "!TARGET_64BIT && TARGET_GNU_TLS"
11966 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11967 [(set_attr "type" "multi")
11968 (set_attr "length" "11")])
11970 (define_expand "tls_local_dynamic_base_32"
11971 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11972 (unspec:SI [(match_dup 1) (match_dup 2)]
11973 UNSPEC_TLS_LD_BASE))
11974 (clobber (match_scratch:SI 3 ""))
11975 (clobber (match_scratch:SI 4 ""))
11976 (clobber (reg:CC FLAGS_REG))])]
11980 operands[1] = pic_offset_table_rtx;
11983 operands[1] = gen_reg_rtx (Pmode);
11984 emit_insn (gen_set_got (operands[1]));
11986 if (TARGET_GNU2_TLS)
11988 emit_insn (gen_tls_dynamic_gnu2_32
11989 (operands[0], ix86_tls_module_base (), operands[1]));
11992 operands[2] = ix86_tls_get_addr ();
11995 (define_insn "*tls_local_dynamic_base_64"
11996 [(set (match_operand:DI 0 "register_operand" "=a")
11997 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
11998 (match_operand:DI 2 "" "")))
11999 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12001 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12002 [(set_attr "type" "multi")
12003 (set_attr "length" "12")])
12005 (define_expand "tls_local_dynamic_base_64"
12006 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12007 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12008 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12011 if (TARGET_GNU2_TLS)
12013 emit_insn (gen_tls_dynamic_gnu2_64
12014 (operands[0], ix86_tls_module_base ()));
12017 operands[1] = ix86_tls_get_addr ();
12020 ;; Local dynamic of a single variable is a lose. Show combine how
12021 ;; to convert that back to global dynamic.
12023 (define_insn_and_split "*tls_local_dynamic_32_once"
12024 [(set (match_operand:SI 0 "register_operand" "=a")
12025 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12026 (match_operand:SI 2 "call_insn_operand" "")]
12027 UNSPEC_TLS_LD_BASE)
12028 (const:SI (unspec:SI
12029 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12031 (clobber (match_scratch:SI 4 "=d"))
12032 (clobber (match_scratch:SI 5 "=c"))
12033 (clobber (reg:CC FLAGS_REG))]
12037 [(parallel [(set (match_dup 0)
12038 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12040 (clobber (match_dup 4))
12041 (clobber (match_dup 5))
12042 (clobber (reg:CC FLAGS_REG))])]
12045 ;; Load and add the thread base pointer from %gs:0.
12047 (define_insn "*load_tp_si"
12048 [(set (match_operand:SI 0 "register_operand" "=r")
12049 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12051 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12052 [(set_attr "type" "imov")
12053 (set_attr "modrm" "0")
12054 (set_attr "length" "7")
12055 (set_attr "memory" "load")
12056 (set_attr "imm_disp" "false")])
12058 (define_insn "*add_tp_si"
12059 [(set (match_operand:SI 0 "register_operand" "=r")
12060 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12061 (match_operand:SI 1 "register_operand" "0")))
12062 (clobber (reg:CC FLAGS_REG))]
12064 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12065 [(set_attr "type" "alu")
12066 (set_attr "modrm" "0")
12067 (set_attr "length" "7")
12068 (set_attr "memory" "load")
12069 (set_attr "imm_disp" "false")])
12071 (define_insn "*load_tp_di"
12072 [(set (match_operand:DI 0 "register_operand" "=r")
12073 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12075 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12076 [(set_attr "type" "imov")
12077 (set_attr "modrm" "0")
12078 (set_attr "length" "7")
12079 (set_attr "memory" "load")
12080 (set_attr "imm_disp" "false")])
12082 (define_insn "*add_tp_di"
12083 [(set (match_operand:DI 0 "register_operand" "=r")
12084 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12085 (match_operand:DI 1 "register_operand" "0")))
12086 (clobber (reg:CC FLAGS_REG))]
12088 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12089 [(set_attr "type" "alu")
12090 (set_attr "modrm" "0")
12091 (set_attr "length" "7")
12092 (set_attr "memory" "load")
12093 (set_attr "imm_disp" "false")])
12095 ;; GNU2 TLS patterns can be split.
12097 (define_expand "tls_dynamic_gnu2_32"
12098 [(set (match_dup 3)
12099 (plus:SI (match_operand:SI 2 "register_operand" "")
12101 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12104 [(set (match_operand:SI 0 "register_operand" "")
12105 (unspec:SI [(match_dup 1) (match_dup 3)
12106 (match_dup 2) (reg:SI SP_REG)]
12108 (clobber (reg:CC FLAGS_REG))])]
12109 "!TARGET_64BIT && TARGET_GNU2_TLS"
12111 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12112 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12115 (define_insn "*tls_dynamic_lea_32"
12116 [(set (match_operand:SI 0 "register_operand" "=r")
12117 (plus:SI (match_operand:SI 1 "register_operand" "b")
12119 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12120 UNSPEC_TLSDESC))))]
12121 "!TARGET_64BIT && TARGET_GNU2_TLS"
12122 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12123 [(set_attr "type" "lea")
12124 (set_attr "mode" "SI")
12125 (set_attr "length" "6")
12126 (set_attr "length_address" "4")])
12128 (define_insn "*tls_dynamic_call_32"
12129 [(set (match_operand:SI 0 "register_operand" "=a")
12130 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12131 (match_operand:SI 2 "register_operand" "0")
12132 ;; we have to make sure %ebx still points to the GOT
12133 (match_operand:SI 3 "register_operand" "b")
12136 (clobber (reg:CC FLAGS_REG))]
12137 "!TARGET_64BIT && TARGET_GNU2_TLS"
12138 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12139 [(set_attr "type" "call")
12140 (set_attr "length" "2")
12141 (set_attr "length_address" "0")])
12143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12144 [(set (match_operand:SI 0 "register_operand" "=&a")
12146 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12147 (match_operand:SI 4 "" "")
12148 (match_operand:SI 2 "register_operand" "b")
12151 (const:SI (unspec:SI
12152 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12154 (clobber (reg:CC FLAGS_REG))]
12155 "!TARGET_64BIT && TARGET_GNU2_TLS"
12158 [(set (match_dup 0) (match_dup 5))]
12160 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12161 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12164 (define_expand "tls_dynamic_gnu2_64"
12165 [(set (match_dup 2)
12166 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12169 [(set (match_operand:DI 0 "register_operand" "")
12170 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12172 (clobber (reg:CC FLAGS_REG))])]
12173 "TARGET_64BIT && TARGET_GNU2_TLS"
12175 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12176 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12179 (define_insn "*tls_dynamic_lea_64"
12180 [(set (match_operand:DI 0 "register_operand" "=r")
12181 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12183 "TARGET_64BIT && TARGET_GNU2_TLS"
12184 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12185 [(set_attr "type" "lea")
12186 (set_attr "mode" "DI")
12187 (set_attr "length" "7")
12188 (set_attr "length_address" "4")])
12190 (define_insn "*tls_dynamic_call_64"
12191 [(set (match_operand:DI 0 "register_operand" "=a")
12192 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12193 (match_operand:DI 2 "register_operand" "0")
12196 (clobber (reg:CC FLAGS_REG))]
12197 "TARGET_64BIT && TARGET_GNU2_TLS"
12198 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12199 [(set_attr "type" "call")
12200 (set_attr "length" "2")
12201 (set_attr "length_address" "0")])
12203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12204 [(set (match_operand:DI 0 "register_operand" "=&a")
12206 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12207 (match_operand:DI 3 "" "")
12210 (const:DI (unspec:DI
12211 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12213 (clobber (reg:CC FLAGS_REG))]
12214 "TARGET_64BIT && TARGET_GNU2_TLS"
12217 [(set (match_dup 0) (match_dup 4))]
12219 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12220 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12225 ;; These patterns match the binary 387 instructions for addM3, subM3,
12226 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12227 ;; SFmode. The first is the normal insn, the second the same insn but
12228 ;; with one operand a conversion, and the third the same insn but with
12229 ;; the other operand a conversion. The conversion may be SFmode or
12230 ;; SImode if the target mode DFmode, but only SImode if the target mode
12233 ;; Gcc is slightly more smart about handling normal two address instructions
12234 ;; so use special patterns for add and mull.
12236 (define_insn "*fop_<mode>_comm_mixed_avx"
12237 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12238 (match_operator:MODEF 3 "binary_fp_operator"
12239 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12240 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12241 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12242 && COMMUTATIVE_ARITH_P (operands[3])
12243 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12244 "* return output_387_binary_op (insn, operands);"
12245 [(set (attr "type")
12246 (if_then_else (eq_attr "alternative" "1")
12247 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12248 (const_string "ssemul")
12249 (const_string "sseadd"))
12250 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12251 (const_string "fmul")
12252 (const_string "fop"))))
12253 (set_attr "prefix" "orig,maybe_vex")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*fop_<mode>_comm_mixed"
12257 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12258 (match_operator:MODEF 3 "binary_fp_operator"
12259 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12262 && COMMUTATIVE_ARITH_P (operands[3])
12263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12264 "* return output_387_binary_op (insn, operands);"
12265 [(set (attr "type")
12266 (if_then_else (eq_attr "alternative" "1")
12267 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12268 (const_string "ssemul")
12269 (const_string "sseadd"))
12270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12271 (const_string "fmul")
12272 (const_string "fop"))))
12273 (set_attr "mode" "<MODE>")])
12275 (define_insn "*fop_<mode>_comm_avx"
12276 [(set (match_operand:MODEF 0 "register_operand" "=x")
12277 (match_operator:MODEF 3 "binary_fp_operator"
12278 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12279 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12280 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12281 && COMMUTATIVE_ARITH_P (operands[3])
12282 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12283 "* return output_387_binary_op (insn, operands);"
12284 [(set (attr "type")
12285 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12286 (const_string "ssemul")
12287 (const_string "sseadd")))
12288 (set_attr "prefix" "vex")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*fop_<mode>_comm_sse"
12292 [(set (match_operand:MODEF 0 "register_operand" "=x")
12293 (match_operator:MODEF 3 "binary_fp_operator"
12294 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12295 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12297 && COMMUTATIVE_ARITH_P (operands[3])
12298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12299 "* return output_387_binary_op (insn, operands);"
12300 [(set (attr "type")
12301 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12302 (const_string "ssemul")
12303 (const_string "sseadd")))
12304 (set_attr "mode" "<MODE>")])
12306 (define_insn "*fop_<mode>_comm_i387"
12307 [(set (match_operand:MODEF 0 "register_operand" "=f")
12308 (match_operator:MODEF 3 "binary_fp_operator"
12309 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12310 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12311 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12312 && COMMUTATIVE_ARITH_P (operands[3])
12313 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12314 "* return output_387_binary_op (insn, operands);"
12315 [(set (attr "type")
12316 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12317 (const_string "fmul")
12318 (const_string "fop")))
12319 (set_attr "mode" "<MODE>")])
12321 (define_insn "*fop_<mode>_1_mixed_avx"
12322 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12323 (match_operator:MODEF 3 "binary_fp_operator"
12324 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12325 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12326 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12327 && !COMMUTATIVE_ARITH_P (operands[3])
12328 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12329 "* return output_387_binary_op (insn, operands);"
12330 [(set (attr "type")
12331 (cond [(and (eq_attr "alternative" "2")
12332 (match_operand:MODEF 3 "mult_operator" ""))
12333 (const_string "ssemul")
12334 (and (eq_attr "alternative" "2")
12335 (match_operand:MODEF 3 "div_operator" ""))
12336 (const_string "ssediv")
12337 (eq_attr "alternative" "2")
12338 (const_string "sseadd")
12339 (match_operand:MODEF 3 "mult_operator" "")
12340 (const_string "fmul")
12341 (match_operand:MODEF 3 "div_operator" "")
12342 (const_string "fdiv")
12344 (const_string "fop")))
12345 (set_attr "prefix" "orig,orig,maybe_vex")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*fop_<mode>_1_mixed"
12349 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12350 (match_operator:MODEF 3 "binary_fp_operator"
12351 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12352 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12353 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12354 && !COMMUTATIVE_ARITH_P (operands[3])
12355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12356 "* return output_387_binary_op (insn, operands);"
12357 [(set (attr "type")
12358 (cond [(and (eq_attr "alternative" "2")
12359 (match_operand:MODEF 3 "mult_operator" ""))
12360 (const_string "ssemul")
12361 (and (eq_attr "alternative" "2")
12362 (match_operand:MODEF 3 "div_operator" ""))
12363 (const_string "ssediv")
12364 (eq_attr "alternative" "2")
12365 (const_string "sseadd")
12366 (match_operand:MODEF 3 "mult_operator" "")
12367 (const_string "fmul")
12368 (match_operand:MODEF 3 "div_operator" "")
12369 (const_string "fdiv")
12371 (const_string "fop")))
12372 (set_attr "mode" "<MODE>")])
12374 (define_insn "*rcpsf2_sse"
12375 [(set (match_operand:SF 0 "register_operand" "=x")
12376 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12379 "%vrcpss\t{%1, %d0|%d0, %1}"
12380 [(set_attr "type" "sse")
12381 (set_attr "atom_sse_attr" "rcp")
12382 (set_attr "prefix" "maybe_vex")
12383 (set_attr "mode" "SF")])
12385 (define_insn "*fop_<mode>_1_avx"
12386 [(set (match_operand:MODEF 0 "register_operand" "=x")
12387 (match_operator:MODEF 3 "binary_fp_operator"
12388 [(match_operand:MODEF 1 "register_operand" "x")
12389 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12390 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12391 && !COMMUTATIVE_ARITH_P (operands[3])"
12392 "* return output_387_binary_op (insn, operands);"
12393 [(set (attr "type")
12394 (cond [(match_operand:MODEF 3 "mult_operator" "")
12395 (const_string "ssemul")
12396 (match_operand:MODEF 3 "div_operator" "")
12397 (const_string "ssediv")
12399 (const_string "sseadd")))
12400 (set_attr "prefix" "vex")
12401 (set_attr "mode" "<MODE>")])
12403 (define_insn "*fop_<mode>_1_sse"
12404 [(set (match_operand:MODEF 0 "register_operand" "=x")
12405 (match_operator:MODEF 3 "binary_fp_operator"
12406 [(match_operand:MODEF 1 "register_operand" "0")
12407 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12409 && !COMMUTATIVE_ARITH_P (operands[3])"
12410 "* return output_387_binary_op (insn, operands);"
12411 [(set (attr "type")
12412 (cond [(match_operand:MODEF 3 "mult_operator" "")
12413 (const_string "ssemul")
12414 (match_operand:MODEF 3 "div_operator" "")
12415 (const_string "ssediv")
12417 (const_string "sseadd")))
12418 (set_attr "mode" "<MODE>")])
12420 ;; This pattern is not fully shadowed by the pattern above.
12421 (define_insn "*fop_<mode>_1_i387"
12422 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12423 (match_operator:MODEF 3 "binary_fp_operator"
12424 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12425 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12426 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12427 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12428 && !COMMUTATIVE_ARITH_P (operands[3])
12429 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12430 "* return output_387_binary_op (insn, operands);"
12431 [(set (attr "type")
12432 (cond [(match_operand:MODEF 3 "mult_operator" "")
12433 (const_string "fmul")
12434 (match_operand:MODEF 3 "div_operator" "")
12435 (const_string "fdiv")
12437 (const_string "fop")))
12438 (set_attr "mode" "<MODE>")])
12440 ;; ??? Add SSE splitters for these!
12441 (define_insn "*fop_<MODEF:mode>_2_i387"
12442 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12443 (match_operator:MODEF 3 "binary_fp_operator"
12445 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12446 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12447 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12448 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12449 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12450 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12451 [(set (attr "type")
12452 (cond [(match_operand:MODEF 3 "mult_operator" "")
12453 (const_string "fmul")
12454 (match_operand:MODEF 3 "div_operator" "")
12455 (const_string "fdiv")
12457 (const_string "fop")))
12458 (set_attr "fp_int_src" "true")
12459 (set_attr "mode" "<X87MODEI12:MODE>")])
12461 (define_insn "*fop_<MODEF:mode>_3_i387"
12462 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12463 (match_operator:MODEF 3 "binary_fp_operator"
12464 [(match_operand:MODEF 1 "register_operand" "0,0")
12466 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12467 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12468 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12469 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12470 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12471 [(set (attr "type")
12472 (cond [(match_operand:MODEF 3 "mult_operator" "")
12473 (const_string "fmul")
12474 (match_operand:MODEF 3 "div_operator" "")
12475 (const_string "fdiv")
12477 (const_string "fop")))
12478 (set_attr "fp_int_src" "true")
12479 (set_attr "mode" "<MODE>")])
12481 (define_insn "*fop_df_4_i387"
12482 [(set (match_operand:DF 0 "register_operand" "=f,f")
12483 (match_operator:DF 3 "binary_fp_operator"
12485 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12486 (match_operand:DF 2 "register_operand" "0,f")]))]
12487 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12488 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12489 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12490 "* return output_387_binary_op (insn, operands);"
12491 [(set (attr "type")
12492 (cond [(match_operand:DF 3 "mult_operator" "")
12493 (const_string "fmul")
12494 (match_operand:DF 3 "div_operator" "")
12495 (const_string "fdiv")
12497 (const_string "fop")))
12498 (set_attr "mode" "SF")])
12500 (define_insn "*fop_df_5_i387"
12501 [(set (match_operand:DF 0 "register_operand" "=f,f")
12502 (match_operator:DF 3 "binary_fp_operator"
12503 [(match_operand:DF 1 "register_operand" "0,f")
12505 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12506 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12507 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12508 "* return output_387_binary_op (insn, operands);"
12509 [(set (attr "type")
12510 (cond [(match_operand:DF 3 "mult_operator" "")
12511 (const_string "fmul")
12512 (match_operand:DF 3 "div_operator" "")
12513 (const_string "fdiv")
12515 (const_string "fop")))
12516 (set_attr "mode" "SF")])
12518 (define_insn "*fop_df_6_i387"
12519 [(set (match_operand:DF 0 "register_operand" "=f,f")
12520 (match_operator:DF 3 "binary_fp_operator"
12522 (match_operand:SF 1 "register_operand" "0,f"))
12524 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12525 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12526 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12527 "* return output_387_binary_op (insn, operands);"
12528 [(set (attr "type")
12529 (cond [(match_operand:DF 3 "mult_operator" "")
12530 (const_string "fmul")
12531 (match_operand:DF 3 "div_operator" "")
12532 (const_string "fdiv")
12534 (const_string "fop")))
12535 (set_attr "mode" "SF")])
12537 (define_insn "*fop_xf_comm_i387"
12538 [(set (match_operand:XF 0 "register_operand" "=f")
12539 (match_operator:XF 3 "binary_fp_operator"
12540 [(match_operand:XF 1 "register_operand" "%0")
12541 (match_operand:XF 2 "register_operand" "f")]))]
12543 && COMMUTATIVE_ARITH_P (operands[3])"
12544 "* return output_387_binary_op (insn, operands);"
12545 [(set (attr "type")
12546 (if_then_else (match_operand:XF 3 "mult_operator" "")
12547 (const_string "fmul")
12548 (const_string "fop")))
12549 (set_attr "mode" "XF")])
12551 (define_insn "*fop_xf_1_i387"
12552 [(set (match_operand:XF 0 "register_operand" "=f,f")
12553 (match_operator:XF 3 "binary_fp_operator"
12554 [(match_operand:XF 1 "register_operand" "0,f")
12555 (match_operand:XF 2 "register_operand" "f,0")]))]
12557 && !COMMUTATIVE_ARITH_P (operands[3])"
12558 "* return output_387_binary_op (insn, operands);"
12559 [(set (attr "type")
12560 (cond [(match_operand:XF 3 "mult_operator" "")
12561 (const_string "fmul")
12562 (match_operand:XF 3 "div_operator" "")
12563 (const_string "fdiv")
12565 (const_string "fop")))
12566 (set_attr "mode" "XF")])
12568 (define_insn "*fop_xf_2_i387"
12569 [(set (match_operand:XF 0 "register_operand" "=f,f")
12570 (match_operator:XF 3 "binary_fp_operator"
12572 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12573 (match_operand:XF 2 "register_operand" "0,0")]))]
12574 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12575 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12576 [(set (attr "type")
12577 (cond [(match_operand:XF 3 "mult_operator" "")
12578 (const_string "fmul")
12579 (match_operand:XF 3 "div_operator" "")
12580 (const_string "fdiv")
12582 (const_string "fop")))
12583 (set_attr "fp_int_src" "true")
12584 (set_attr "mode" "<MODE>")])
12586 (define_insn "*fop_xf_3_i387"
12587 [(set (match_operand:XF 0 "register_operand" "=f,f")
12588 (match_operator:XF 3 "binary_fp_operator"
12589 [(match_operand:XF 1 "register_operand" "0,0")
12591 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12592 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12593 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12594 [(set (attr "type")
12595 (cond [(match_operand:XF 3 "mult_operator" "")
12596 (const_string "fmul")
12597 (match_operand:XF 3 "div_operator" "")
12598 (const_string "fdiv")
12600 (const_string "fop")))
12601 (set_attr "fp_int_src" "true")
12602 (set_attr "mode" "<MODE>")])
12604 (define_insn "*fop_xf_4_i387"
12605 [(set (match_operand:XF 0 "register_operand" "=f,f")
12606 (match_operator:XF 3 "binary_fp_operator"
12608 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12609 (match_operand:XF 2 "register_operand" "0,f")]))]
12611 "* return output_387_binary_op (insn, operands);"
12612 [(set (attr "type")
12613 (cond [(match_operand:XF 3 "mult_operator" "")
12614 (const_string "fmul")
12615 (match_operand:XF 3 "div_operator" "")
12616 (const_string "fdiv")
12618 (const_string "fop")))
12619 (set_attr "mode" "<MODE>")])
12621 (define_insn "*fop_xf_5_i387"
12622 [(set (match_operand:XF 0 "register_operand" "=f,f")
12623 (match_operator:XF 3 "binary_fp_operator"
12624 [(match_operand:XF 1 "register_operand" "0,f")
12626 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12628 "* return output_387_binary_op (insn, operands);"
12629 [(set (attr "type")
12630 (cond [(match_operand:XF 3 "mult_operator" "")
12631 (const_string "fmul")
12632 (match_operand:XF 3 "div_operator" "")
12633 (const_string "fdiv")
12635 (const_string "fop")))
12636 (set_attr "mode" "<MODE>")])
12638 (define_insn "*fop_xf_6_i387"
12639 [(set (match_operand:XF 0 "register_operand" "=f,f")
12640 (match_operator:XF 3 "binary_fp_operator"
12642 (match_operand:MODEF 1 "register_operand" "0,f"))
12644 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12646 "* return output_387_binary_op (insn, operands);"
12647 [(set (attr "type")
12648 (cond [(match_operand:XF 3 "mult_operator" "")
12649 (const_string "fmul")
12650 (match_operand:XF 3 "div_operator" "")
12651 (const_string "fdiv")
12653 (const_string "fop")))
12654 (set_attr "mode" "<MODE>")])
12657 [(set (match_operand 0 "register_operand" "")
12658 (match_operator 3 "binary_fp_operator"
12659 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12660 (match_operand 2 "register_operand" "")]))]
12662 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12663 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12666 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12667 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12668 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12669 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12670 GET_MODE (operands[3]),
12673 ix86_free_from_memory (GET_MODE (operands[1]));
12678 [(set (match_operand 0 "register_operand" "")
12679 (match_operator 3 "binary_fp_operator"
12680 [(match_operand 1 "register_operand" "")
12681 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12683 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12684 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12687 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12688 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12689 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12690 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12691 GET_MODE (operands[3]),
12694 ix86_free_from_memory (GET_MODE (operands[2]));
12698 ;; FPU special functions.
12700 ;; This pattern implements a no-op XFmode truncation for
12701 ;; all fancy i386 XFmode math functions.
12703 (define_insn "truncxf<mode>2_i387_noop_unspec"
12704 [(set (match_operand:MODEF 0 "register_operand" "=f")
12705 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12706 UNSPEC_TRUNC_NOOP))]
12707 "TARGET_USE_FANCY_MATH_387"
12708 "* return output_387_reg_move (insn, operands);"
12709 [(set_attr "type" "fmov")
12710 (set_attr "mode" "<MODE>")])
12712 (define_insn "sqrtxf2"
12713 [(set (match_operand:XF 0 "register_operand" "=f")
12714 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12715 "TARGET_USE_FANCY_MATH_387"
12717 [(set_attr "type" "fpspc")
12718 (set_attr "mode" "XF")
12719 (set_attr "athlon_decode" "direct")
12720 (set_attr "amdfam10_decode" "direct")])
12722 (define_insn "sqrt_extend<mode>xf2_i387"
12723 [(set (match_operand:XF 0 "register_operand" "=f")
12726 (match_operand:MODEF 1 "register_operand" "0"))))]
12727 "TARGET_USE_FANCY_MATH_387"
12729 [(set_attr "type" "fpspc")
12730 (set_attr "mode" "XF")
12731 (set_attr "athlon_decode" "direct")
12732 (set_attr "amdfam10_decode" "direct")])
12734 (define_insn "*rsqrtsf2_sse"
12735 [(set (match_operand:SF 0 "register_operand" "=x")
12736 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12739 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12740 [(set_attr "type" "sse")
12741 (set_attr "atom_sse_attr" "rcp")
12742 (set_attr "prefix" "maybe_vex")
12743 (set_attr "mode" "SF")])
12745 (define_expand "rsqrtsf2"
12746 [(set (match_operand:SF 0 "register_operand" "")
12747 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12751 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12755 (define_insn "*sqrt<mode>2_sse"
12756 [(set (match_operand:MODEF 0 "register_operand" "=x")
12758 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12759 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12760 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12761 [(set_attr "type" "sse")
12762 (set_attr "atom_sse_attr" "sqrt")
12763 (set_attr "prefix" "maybe_vex")
12764 (set_attr "mode" "<MODE>")
12765 (set_attr "athlon_decode" "*")
12766 (set_attr "amdfam10_decode" "*")])
12768 (define_expand "sqrt<mode>2"
12769 [(set (match_operand:MODEF 0 "register_operand" "")
12771 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12772 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12773 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12775 if (<MODE>mode == SFmode
12776 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12777 && flag_finite_math_only && !flag_trapping_math
12778 && flag_unsafe_math_optimizations)
12780 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12784 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12786 rtx op0 = gen_reg_rtx (XFmode);
12787 rtx op1 = force_reg (<MODE>mode, operands[1]);
12789 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12790 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12795 (define_insn "fpremxf4_i387"
12796 [(set (match_operand:XF 0 "register_operand" "=f")
12797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12798 (match_operand:XF 3 "register_operand" "1")]
12800 (set (match_operand:XF 1 "register_operand" "=u")
12801 (unspec:XF [(match_dup 2) (match_dup 3)]
12803 (set (reg:CCFP FPSR_REG)
12804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12806 "TARGET_USE_FANCY_MATH_387"
12808 [(set_attr "type" "fpspc")
12809 (set_attr "mode" "XF")])
12811 (define_expand "fmodxf3"
12812 [(use (match_operand:XF 0 "register_operand" ""))
12813 (use (match_operand:XF 1 "general_operand" ""))
12814 (use (match_operand:XF 2 "general_operand" ""))]
12815 "TARGET_USE_FANCY_MATH_387"
12817 rtx label = gen_label_rtx ();
12819 rtx op1 = gen_reg_rtx (XFmode);
12820 rtx op2 = gen_reg_rtx (XFmode);
12822 emit_move_insn (op2, operands[2]);
12823 emit_move_insn (op1, operands[1]);
12825 emit_label (label);
12826 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12827 ix86_emit_fp_unordered_jump (label);
12828 LABEL_NUSES (label) = 1;
12830 emit_move_insn (operands[0], op1);
12834 (define_expand "fmod<mode>3"
12835 [(use (match_operand:MODEF 0 "register_operand" ""))
12836 (use (match_operand:MODEF 1 "general_operand" ""))
12837 (use (match_operand:MODEF 2 "general_operand" ""))]
12838 "TARGET_USE_FANCY_MATH_387"
12840 rtx (*gen_truncxf) (rtx, rtx);
12842 rtx label = gen_label_rtx ();
12844 rtx op1 = gen_reg_rtx (XFmode);
12845 rtx op2 = gen_reg_rtx (XFmode);
12847 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12848 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12850 emit_label (label);
12851 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12852 ix86_emit_fp_unordered_jump (label);
12853 LABEL_NUSES (label) = 1;
12855 /* Truncate the result properly for strict SSE math. */
12856 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12857 && !TARGET_MIX_SSE_I387)
12858 gen_truncxf = gen_truncxf<mode>2;
12860 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12862 emit_insn (gen_truncxf (operands[0], op1));
12866 (define_insn "fprem1xf4_i387"
12867 [(set (match_operand:XF 0 "register_operand" "=f")
12868 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12869 (match_operand:XF 3 "register_operand" "1")]
12871 (set (match_operand:XF 1 "register_operand" "=u")
12872 (unspec:XF [(match_dup 2) (match_dup 3)]
12874 (set (reg:CCFP FPSR_REG)
12875 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12877 "TARGET_USE_FANCY_MATH_387"
12879 [(set_attr "type" "fpspc")
12880 (set_attr "mode" "XF")])
12882 (define_expand "remainderxf3"
12883 [(use (match_operand:XF 0 "register_operand" ""))
12884 (use (match_operand:XF 1 "general_operand" ""))
12885 (use (match_operand:XF 2 "general_operand" ""))]
12886 "TARGET_USE_FANCY_MATH_387"
12888 rtx label = gen_label_rtx ();
12890 rtx op1 = gen_reg_rtx (XFmode);
12891 rtx op2 = gen_reg_rtx (XFmode);
12893 emit_move_insn (op2, operands[2]);
12894 emit_move_insn (op1, operands[1]);
12896 emit_label (label);
12897 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12898 ix86_emit_fp_unordered_jump (label);
12899 LABEL_NUSES (label) = 1;
12901 emit_move_insn (operands[0], op1);
12905 (define_expand "remainder<mode>3"
12906 [(use (match_operand:MODEF 0 "register_operand" ""))
12907 (use (match_operand:MODEF 1 "general_operand" ""))
12908 (use (match_operand:MODEF 2 "general_operand" ""))]
12909 "TARGET_USE_FANCY_MATH_387"
12911 rtx (*gen_truncxf) (rtx, rtx);
12913 rtx label = gen_label_rtx ();
12915 rtx op1 = gen_reg_rtx (XFmode);
12916 rtx op2 = gen_reg_rtx (XFmode);
12918 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12921 emit_label (label);
12923 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12924 ix86_emit_fp_unordered_jump (label);
12925 LABEL_NUSES (label) = 1;
12927 /* Truncate the result properly for strict SSE math. */
12928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12929 && !TARGET_MIX_SSE_I387)
12930 gen_truncxf = gen_truncxf<mode>2;
12932 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12934 emit_insn (gen_truncxf (operands[0], op1));
12938 (define_insn "*sinxf2_i387"
12939 [(set (match_operand:XF 0 "register_operand" "=f")
12940 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12941 "TARGET_USE_FANCY_MATH_387
12942 && flag_unsafe_math_optimizations"
12944 [(set_attr "type" "fpspc")
12945 (set_attr "mode" "XF")])
12947 (define_insn "*sin_extend<mode>xf2_i387"
12948 [(set (match_operand:XF 0 "register_operand" "=f")
12949 (unspec:XF [(float_extend:XF
12950 (match_operand:MODEF 1 "register_operand" "0"))]
12952 "TARGET_USE_FANCY_MATH_387
12953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12954 || TARGET_MIX_SSE_I387)
12955 && flag_unsafe_math_optimizations"
12957 [(set_attr "type" "fpspc")
12958 (set_attr "mode" "XF")])
12960 (define_insn "*cosxf2_i387"
12961 [(set (match_operand:XF 0 "register_operand" "=f")
12962 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12963 "TARGET_USE_FANCY_MATH_387
12964 && flag_unsafe_math_optimizations"
12966 [(set_attr "type" "fpspc")
12967 (set_attr "mode" "XF")])
12969 (define_insn "*cos_extend<mode>xf2_i387"
12970 [(set (match_operand:XF 0 "register_operand" "=f")
12971 (unspec:XF [(float_extend:XF
12972 (match_operand:MODEF 1 "register_operand" "0"))]
12974 "TARGET_USE_FANCY_MATH_387
12975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12976 || TARGET_MIX_SSE_I387)
12977 && flag_unsafe_math_optimizations"
12979 [(set_attr "type" "fpspc")
12980 (set_attr "mode" "XF")])
12982 ;; When sincos pattern is defined, sin and cos builtin functions will be
12983 ;; expanded to sincos pattern with one of its outputs left unused.
12984 ;; CSE pass will figure out if two sincos patterns can be combined,
12985 ;; otherwise sincos pattern will be split back to sin or cos pattern,
12986 ;; depending on the unused output.
12988 (define_insn "sincosxf3"
12989 [(set (match_operand:XF 0 "register_operand" "=f")
12990 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
12991 UNSPEC_SINCOS_COS))
12992 (set (match_operand:XF 1 "register_operand" "=u")
12993 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12994 "TARGET_USE_FANCY_MATH_387
12995 && flag_unsafe_math_optimizations"
12997 [(set_attr "type" "fpspc")
12998 (set_attr "mode" "XF")])
13001 [(set (match_operand:XF 0 "register_operand" "")
13002 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13003 UNSPEC_SINCOS_COS))
13004 (set (match_operand:XF 1 "register_operand" "")
13005 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13006 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13007 && !(reload_completed || reload_in_progress)"
13008 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13011 [(set (match_operand:XF 0 "register_operand" "")
13012 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13013 UNSPEC_SINCOS_COS))
13014 (set (match_operand:XF 1 "register_operand" "")
13015 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13016 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13017 && !(reload_completed || reload_in_progress)"
13018 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13020 (define_insn "sincos_extend<mode>xf3_i387"
13021 [(set (match_operand:XF 0 "register_operand" "=f")
13022 (unspec:XF [(float_extend:XF
13023 (match_operand:MODEF 2 "register_operand" "0"))]
13024 UNSPEC_SINCOS_COS))
13025 (set (match_operand:XF 1 "register_operand" "=u")
13026 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13027 "TARGET_USE_FANCY_MATH_387
13028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13029 || TARGET_MIX_SSE_I387)
13030 && flag_unsafe_math_optimizations"
13032 [(set_attr "type" "fpspc")
13033 (set_attr "mode" "XF")])
13036 [(set (match_operand:XF 0 "register_operand" "")
13037 (unspec:XF [(float_extend:XF
13038 (match_operand:MODEF 2 "register_operand" ""))]
13039 UNSPEC_SINCOS_COS))
13040 (set (match_operand:XF 1 "register_operand" "")
13041 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13042 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13043 && !(reload_completed || reload_in_progress)"
13044 [(set (match_dup 1)
13045 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13048 [(set (match_operand:XF 0 "register_operand" "")
13049 (unspec:XF [(float_extend:XF
13050 (match_operand:MODEF 2 "register_operand" ""))]
13051 UNSPEC_SINCOS_COS))
13052 (set (match_operand:XF 1 "register_operand" "")
13053 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13054 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13055 && !(reload_completed || reload_in_progress)"
13056 [(set (match_dup 0)
13057 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13059 (define_expand "sincos<mode>3"
13060 [(use (match_operand:MODEF 0 "register_operand" ""))
13061 (use (match_operand:MODEF 1 "register_operand" ""))
13062 (use (match_operand:MODEF 2 "register_operand" ""))]
13063 "TARGET_USE_FANCY_MATH_387
13064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13065 || TARGET_MIX_SSE_I387)
13066 && flag_unsafe_math_optimizations"
13068 rtx op0 = gen_reg_rtx (XFmode);
13069 rtx op1 = gen_reg_rtx (XFmode);
13071 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13077 (define_insn "fptanxf4_i387"
13078 [(set (match_operand:XF 0 "register_operand" "=f")
13079 (match_operand:XF 3 "const_double_operand" "F"))
13080 (set (match_operand:XF 1 "register_operand" "=u")
13081 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13083 "TARGET_USE_FANCY_MATH_387
13084 && flag_unsafe_math_optimizations
13085 && standard_80387_constant_p (operands[3]) == 2"
13087 [(set_attr "type" "fpspc")
13088 (set_attr "mode" "XF")])
13090 (define_insn "fptan_extend<mode>xf4_i387"
13091 [(set (match_operand:MODEF 0 "register_operand" "=f")
13092 (match_operand:MODEF 3 "const_double_operand" "F"))
13093 (set (match_operand:XF 1 "register_operand" "=u")
13094 (unspec:XF [(float_extend:XF
13095 (match_operand:MODEF 2 "register_operand" "0"))]
13097 "TARGET_USE_FANCY_MATH_387
13098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13099 || TARGET_MIX_SSE_I387)
13100 && flag_unsafe_math_optimizations
13101 && standard_80387_constant_p (operands[3]) == 2"
13103 [(set_attr "type" "fpspc")
13104 (set_attr "mode" "XF")])
13106 (define_expand "tanxf2"
13107 [(use (match_operand:XF 0 "register_operand" ""))
13108 (use (match_operand:XF 1 "register_operand" ""))]
13109 "TARGET_USE_FANCY_MATH_387
13110 && flag_unsafe_math_optimizations"
13112 rtx one = gen_reg_rtx (XFmode);
13113 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13115 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13119 (define_expand "tan<mode>2"
13120 [(use (match_operand:MODEF 0 "register_operand" ""))
13121 (use (match_operand:MODEF 1 "register_operand" ""))]
13122 "TARGET_USE_FANCY_MATH_387
13123 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13124 || TARGET_MIX_SSE_I387)
13125 && flag_unsafe_math_optimizations"
13127 rtx op0 = gen_reg_rtx (XFmode);
13129 rtx one = gen_reg_rtx (<MODE>mode);
13130 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13132 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13133 operands[1], op2));
13134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13138 (define_insn "*fpatanxf3_i387"
13139 [(set (match_operand:XF 0 "register_operand" "=f")
13140 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13141 (match_operand:XF 2 "register_operand" "u")]
13143 (clobber (match_scratch:XF 3 "=2"))]
13144 "TARGET_USE_FANCY_MATH_387
13145 && flag_unsafe_math_optimizations"
13147 [(set_attr "type" "fpspc")
13148 (set_attr "mode" "XF")])
13150 (define_insn "fpatan_extend<mode>xf3_i387"
13151 [(set (match_operand:XF 0 "register_operand" "=f")
13152 (unspec:XF [(float_extend:XF
13153 (match_operand:MODEF 1 "register_operand" "0"))
13155 (match_operand:MODEF 2 "register_operand" "u"))]
13157 (clobber (match_scratch:XF 3 "=2"))]
13158 "TARGET_USE_FANCY_MATH_387
13159 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13160 || TARGET_MIX_SSE_I387)
13161 && flag_unsafe_math_optimizations"
13163 [(set_attr "type" "fpspc")
13164 (set_attr "mode" "XF")])
13166 (define_expand "atan2xf3"
13167 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13168 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13169 (match_operand:XF 1 "register_operand" "")]
13171 (clobber (match_scratch:XF 3 ""))])]
13172 "TARGET_USE_FANCY_MATH_387
13173 && flag_unsafe_math_optimizations"
13176 (define_expand "atan2<mode>3"
13177 [(use (match_operand:MODEF 0 "register_operand" ""))
13178 (use (match_operand:MODEF 1 "register_operand" ""))
13179 (use (match_operand:MODEF 2 "register_operand" ""))]
13180 "TARGET_USE_FANCY_MATH_387
13181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13182 || TARGET_MIX_SSE_I387)
13183 && flag_unsafe_math_optimizations"
13185 rtx op0 = gen_reg_rtx (XFmode);
13187 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13188 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13192 (define_expand "atanxf2"
13193 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13194 (unspec:XF [(match_dup 2)
13195 (match_operand:XF 1 "register_operand" "")]
13197 (clobber (match_scratch:XF 3 ""))])]
13198 "TARGET_USE_FANCY_MATH_387
13199 && flag_unsafe_math_optimizations"
13201 operands[2] = gen_reg_rtx (XFmode);
13202 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13205 (define_expand "atan<mode>2"
13206 [(use (match_operand:MODEF 0 "register_operand" ""))
13207 (use (match_operand:MODEF 1 "register_operand" ""))]
13208 "TARGET_USE_FANCY_MATH_387
13209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13210 || TARGET_MIX_SSE_I387)
13211 && flag_unsafe_math_optimizations"
13213 rtx op0 = gen_reg_rtx (XFmode);
13215 rtx op2 = gen_reg_rtx (<MODE>mode);
13216 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13218 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13219 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13223 (define_expand "asinxf2"
13224 [(set (match_dup 2)
13225 (mult:XF (match_operand:XF 1 "register_operand" "")
13227 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13228 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13229 (parallel [(set (match_operand:XF 0 "register_operand" "")
13230 (unspec:XF [(match_dup 5) (match_dup 1)]
13232 (clobber (match_scratch:XF 6 ""))])]
13233 "TARGET_USE_FANCY_MATH_387
13234 && flag_unsafe_math_optimizations"
13238 if (optimize_insn_for_size_p ())
13241 for (i = 2; i < 6; i++)
13242 operands[i] = gen_reg_rtx (XFmode);
13244 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13247 (define_expand "asin<mode>2"
13248 [(use (match_operand:MODEF 0 "register_operand" ""))
13249 (use (match_operand:MODEF 1 "general_operand" ""))]
13250 "TARGET_USE_FANCY_MATH_387
13251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13252 || TARGET_MIX_SSE_I387)
13253 && flag_unsafe_math_optimizations"
13255 rtx op0 = gen_reg_rtx (XFmode);
13256 rtx op1 = gen_reg_rtx (XFmode);
13258 if (optimize_insn_for_size_p ())
13261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13262 emit_insn (gen_asinxf2 (op0, op1));
13263 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13267 (define_expand "acosxf2"
13268 [(set (match_dup 2)
13269 (mult:XF (match_operand:XF 1 "register_operand" "")
13271 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13272 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13273 (parallel [(set (match_operand:XF 0 "register_operand" "")
13274 (unspec:XF [(match_dup 1) (match_dup 5)]
13276 (clobber (match_scratch:XF 6 ""))])]
13277 "TARGET_USE_FANCY_MATH_387
13278 && flag_unsafe_math_optimizations"
13282 if (optimize_insn_for_size_p ())
13285 for (i = 2; i < 6; i++)
13286 operands[i] = gen_reg_rtx (XFmode);
13288 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13291 (define_expand "acos<mode>2"
13292 [(use (match_operand:MODEF 0 "register_operand" ""))
13293 (use (match_operand:MODEF 1 "general_operand" ""))]
13294 "TARGET_USE_FANCY_MATH_387
13295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13296 || TARGET_MIX_SSE_I387)
13297 && flag_unsafe_math_optimizations"
13299 rtx op0 = gen_reg_rtx (XFmode);
13300 rtx op1 = gen_reg_rtx (XFmode);
13302 if (optimize_insn_for_size_p ())
13305 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13306 emit_insn (gen_acosxf2 (op0, op1));
13307 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13311 (define_insn "fyl2xxf3_i387"
13312 [(set (match_operand:XF 0 "register_operand" "=f")
13313 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13314 (match_operand:XF 2 "register_operand" "u")]
13316 (clobber (match_scratch:XF 3 "=2"))]
13317 "TARGET_USE_FANCY_MATH_387
13318 && flag_unsafe_math_optimizations"
13320 [(set_attr "type" "fpspc")
13321 (set_attr "mode" "XF")])
13323 (define_insn "fyl2x_extend<mode>xf3_i387"
13324 [(set (match_operand:XF 0 "register_operand" "=f")
13325 (unspec:XF [(float_extend:XF
13326 (match_operand:MODEF 1 "register_operand" "0"))
13327 (match_operand:XF 2 "register_operand" "u")]
13329 (clobber (match_scratch:XF 3 "=2"))]
13330 "TARGET_USE_FANCY_MATH_387
13331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13332 || TARGET_MIX_SSE_I387)
13333 && flag_unsafe_math_optimizations"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")])
13338 (define_expand "logxf2"
13339 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13340 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13341 (match_dup 2)] UNSPEC_FYL2X))
13342 (clobber (match_scratch:XF 3 ""))])]
13343 "TARGET_USE_FANCY_MATH_387
13344 && flag_unsafe_math_optimizations"
13346 operands[2] = gen_reg_rtx (XFmode);
13347 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13350 (define_expand "log<mode>2"
13351 [(use (match_operand:MODEF 0 "register_operand" ""))
13352 (use (match_operand:MODEF 1 "register_operand" ""))]
13353 "TARGET_USE_FANCY_MATH_387
13354 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13355 || TARGET_MIX_SSE_I387)
13356 && flag_unsafe_math_optimizations"
13358 rtx op0 = gen_reg_rtx (XFmode);
13360 rtx op2 = gen_reg_rtx (XFmode);
13361 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13363 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13364 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13368 (define_expand "log10xf2"
13369 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13370 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13371 (match_dup 2)] UNSPEC_FYL2X))
13372 (clobber (match_scratch:XF 3 ""))])]
13373 "TARGET_USE_FANCY_MATH_387
13374 && flag_unsafe_math_optimizations"
13376 operands[2] = gen_reg_rtx (XFmode);
13377 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13380 (define_expand "log10<mode>2"
13381 [(use (match_operand:MODEF 0 "register_operand" ""))
13382 (use (match_operand:MODEF 1 "register_operand" ""))]
13383 "TARGET_USE_FANCY_MATH_387
13384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13385 || TARGET_MIX_SSE_I387)
13386 && flag_unsafe_math_optimizations"
13388 rtx op0 = gen_reg_rtx (XFmode);
13390 rtx op2 = gen_reg_rtx (XFmode);
13391 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13393 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13394 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13398 (define_expand "log2xf2"
13399 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13400 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13401 (match_dup 2)] UNSPEC_FYL2X))
13402 (clobber (match_scratch:XF 3 ""))])]
13403 "TARGET_USE_FANCY_MATH_387
13404 && flag_unsafe_math_optimizations"
13406 operands[2] = gen_reg_rtx (XFmode);
13407 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13410 (define_expand "log2<mode>2"
13411 [(use (match_operand:MODEF 0 "register_operand" ""))
13412 (use (match_operand:MODEF 1 "register_operand" ""))]
13413 "TARGET_USE_FANCY_MATH_387
13414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13415 || TARGET_MIX_SSE_I387)
13416 && flag_unsafe_math_optimizations"
13418 rtx op0 = gen_reg_rtx (XFmode);
13420 rtx op2 = gen_reg_rtx (XFmode);
13421 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13423 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13428 (define_insn "fyl2xp1xf3_i387"
13429 [(set (match_operand:XF 0 "register_operand" "=f")
13430 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13431 (match_operand:XF 2 "register_operand" "u")]
13433 (clobber (match_scratch:XF 3 "=2"))]
13434 "TARGET_USE_FANCY_MATH_387
13435 && flag_unsafe_math_optimizations"
13437 [(set_attr "type" "fpspc")
13438 (set_attr "mode" "XF")])
13440 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13441 [(set (match_operand:XF 0 "register_operand" "=f")
13442 (unspec:XF [(float_extend:XF
13443 (match_operand:MODEF 1 "register_operand" "0"))
13444 (match_operand:XF 2 "register_operand" "u")]
13446 (clobber (match_scratch:XF 3 "=2"))]
13447 "TARGET_USE_FANCY_MATH_387
13448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13449 || TARGET_MIX_SSE_I387)
13450 && flag_unsafe_math_optimizations"
13452 [(set_attr "type" "fpspc")
13453 (set_attr "mode" "XF")])
13455 (define_expand "log1pxf2"
13456 [(use (match_operand:XF 0 "register_operand" ""))
13457 (use (match_operand:XF 1 "register_operand" ""))]
13458 "TARGET_USE_FANCY_MATH_387
13459 && flag_unsafe_math_optimizations"
13461 if (optimize_insn_for_size_p ())
13464 ix86_emit_i387_log1p (operands[0], operands[1]);
13468 (define_expand "log1p<mode>2"
13469 [(use (match_operand:MODEF 0 "register_operand" ""))
13470 (use (match_operand:MODEF 1 "register_operand" ""))]
13471 "TARGET_USE_FANCY_MATH_387
13472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13473 || TARGET_MIX_SSE_I387)
13474 && flag_unsafe_math_optimizations"
13478 if (optimize_insn_for_size_p ())
13481 op0 = gen_reg_rtx (XFmode);
13483 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13485 ix86_emit_i387_log1p (op0, operands[1]);
13486 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13490 (define_insn "fxtractxf3_i387"
13491 [(set (match_operand:XF 0 "register_operand" "=f")
13492 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13493 UNSPEC_XTRACT_FRACT))
13494 (set (match_operand:XF 1 "register_operand" "=u")
13495 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13496 "TARGET_USE_FANCY_MATH_387
13497 && flag_unsafe_math_optimizations"
13499 [(set_attr "type" "fpspc")
13500 (set_attr "mode" "XF")])
13502 (define_insn "fxtract_extend<mode>xf3_i387"
13503 [(set (match_operand:XF 0 "register_operand" "=f")
13504 (unspec:XF [(float_extend:XF
13505 (match_operand:MODEF 2 "register_operand" "0"))]
13506 UNSPEC_XTRACT_FRACT))
13507 (set (match_operand:XF 1 "register_operand" "=u")
13508 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511 || TARGET_MIX_SSE_I387)
13512 && flag_unsafe_math_optimizations"
13514 [(set_attr "type" "fpspc")
13515 (set_attr "mode" "XF")])
13517 (define_expand "logbxf2"
13518 [(parallel [(set (match_dup 2)
13519 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13520 UNSPEC_XTRACT_FRACT))
13521 (set (match_operand:XF 0 "register_operand" "")
13522 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13523 "TARGET_USE_FANCY_MATH_387
13524 && flag_unsafe_math_optimizations"
13526 operands[2] = gen_reg_rtx (XFmode);
13529 (define_expand "logb<mode>2"
13530 [(use (match_operand:MODEF 0 "register_operand" ""))
13531 (use (match_operand:MODEF 1 "register_operand" ""))]
13532 "TARGET_USE_FANCY_MATH_387
13533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13534 || TARGET_MIX_SSE_I387)
13535 && flag_unsafe_math_optimizations"
13537 rtx op0 = gen_reg_rtx (XFmode);
13538 rtx op1 = gen_reg_rtx (XFmode);
13540 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13545 (define_expand "ilogbxf2"
13546 [(use (match_operand:SI 0 "register_operand" ""))
13547 (use (match_operand:XF 1 "register_operand" ""))]
13548 "TARGET_USE_FANCY_MATH_387
13549 && flag_unsafe_math_optimizations"
13553 if (optimize_insn_for_size_p ())
13556 op0 = gen_reg_rtx (XFmode);
13557 op1 = gen_reg_rtx (XFmode);
13559 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13560 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13564 (define_expand "ilogb<mode>2"
13565 [(use (match_operand:SI 0 "register_operand" ""))
13566 (use (match_operand:MODEF 1 "register_operand" ""))]
13567 "TARGET_USE_FANCY_MATH_387
13568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13569 || TARGET_MIX_SSE_I387)
13570 && flag_unsafe_math_optimizations"
13574 if (optimize_insn_for_size_p ())
13577 op0 = gen_reg_rtx (XFmode);
13578 op1 = gen_reg_rtx (XFmode);
13580 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13581 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13585 (define_insn "*f2xm1xf2_i387"
13586 [(set (match_operand:XF 0 "register_operand" "=f")
13587 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13589 "TARGET_USE_FANCY_MATH_387
13590 && flag_unsafe_math_optimizations"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")])
13595 (define_insn "*fscalexf4_i387"
13596 [(set (match_operand:XF 0 "register_operand" "=f")
13597 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13598 (match_operand:XF 3 "register_operand" "1")]
13599 UNSPEC_FSCALE_FRACT))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_dup 2) (match_dup 3)]
13602 UNSPEC_FSCALE_EXP))]
13603 "TARGET_USE_FANCY_MATH_387
13604 && flag_unsafe_math_optimizations"
13606 [(set_attr "type" "fpspc")
13607 (set_attr "mode" "XF")])
13609 (define_expand "expNcorexf3"
13610 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13611 (match_operand:XF 2 "register_operand" "")))
13612 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13613 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13614 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13615 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13616 (parallel [(set (match_operand:XF 0 "register_operand" "")
13617 (unspec:XF [(match_dup 8) (match_dup 4)]
13618 UNSPEC_FSCALE_FRACT))
13620 (unspec:XF [(match_dup 8) (match_dup 4)]
13621 UNSPEC_FSCALE_EXP))])]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13627 if (optimize_insn_for_size_p ())
13630 for (i = 3; i < 10; i++)
13631 operands[i] = gen_reg_rtx (XFmode);
13633 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13636 (define_expand "expxf2"
13637 [(use (match_operand:XF 0 "register_operand" ""))
13638 (use (match_operand:XF 1 "register_operand" ""))]
13639 "TARGET_USE_FANCY_MATH_387
13640 && flag_unsafe_math_optimizations"
13644 if (optimize_insn_for_size_p ())
13647 op2 = gen_reg_rtx (XFmode);
13648 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13650 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13654 (define_expand "exp<mode>2"
13655 [(use (match_operand:MODEF 0 "register_operand" ""))
13656 (use (match_operand:MODEF 1 "general_operand" ""))]
13657 "TARGET_USE_FANCY_MATH_387
13658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13659 || TARGET_MIX_SSE_I387)
13660 && flag_unsafe_math_optimizations"
13664 if (optimize_insn_for_size_p ())
13667 op0 = gen_reg_rtx (XFmode);
13668 op1 = gen_reg_rtx (XFmode);
13670 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13671 emit_insn (gen_expxf2 (op0, op1));
13672 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13676 (define_expand "exp10xf2"
13677 [(use (match_operand:XF 0 "register_operand" ""))
13678 (use (match_operand:XF 1 "register_operand" ""))]
13679 "TARGET_USE_FANCY_MATH_387
13680 && flag_unsafe_math_optimizations"
13684 if (optimize_insn_for_size_p ())
13687 op2 = gen_reg_rtx (XFmode);
13688 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13690 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13694 (define_expand "exp10<mode>2"
13695 [(use (match_operand:MODEF 0 "register_operand" ""))
13696 (use (match_operand:MODEF 1 "general_operand" ""))]
13697 "TARGET_USE_FANCY_MATH_387
13698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13699 || TARGET_MIX_SSE_I387)
13700 && flag_unsafe_math_optimizations"
13704 if (optimize_insn_for_size_p ())
13707 op0 = gen_reg_rtx (XFmode);
13708 op1 = gen_reg_rtx (XFmode);
13710 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13711 emit_insn (gen_exp10xf2 (op0, op1));
13712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13716 (define_expand "exp2xf2"
13717 [(use (match_operand:XF 0 "register_operand" ""))
13718 (use (match_operand:XF 1 "register_operand" ""))]
13719 "TARGET_USE_FANCY_MATH_387
13720 && flag_unsafe_math_optimizations"
13724 if (optimize_insn_for_size_p ())
13727 op2 = gen_reg_rtx (XFmode);
13728 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13730 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13734 (define_expand "exp2<mode>2"
13735 [(use (match_operand:MODEF 0 "register_operand" ""))
13736 (use (match_operand:MODEF 1 "general_operand" ""))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739 || TARGET_MIX_SSE_I387)
13740 && flag_unsafe_math_optimizations"
13744 if (optimize_insn_for_size_p ())
13747 op0 = gen_reg_rtx (XFmode);
13748 op1 = gen_reg_rtx (XFmode);
13750 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13751 emit_insn (gen_exp2xf2 (op0, op1));
13752 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13756 (define_expand "expm1xf2"
13757 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13759 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13760 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13761 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13762 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13763 (parallel [(set (match_dup 7)
13764 (unspec:XF [(match_dup 6) (match_dup 4)]
13765 UNSPEC_FSCALE_FRACT))
13767 (unspec:XF [(match_dup 6) (match_dup 4)]
13768 UNSPEC_FSCALE_EXP))])
13769 (parallel [(set (match_dup 10)
13770 (unspec:XF [(match_dup 9) (match_dup 8)]
13771 UNSPEC_FSCALE_FRACT))
13772 (set (match_dup 11)
13773 (unspec:XF [(match_dup 9) (match_dup 8)]
13774 UNSPEC_FSCALE_EXP))])
13775 (set (match_dup 12) (minus:XF (match_dup 10)
13776 (float_extend:XF (match_dup 13))))
13777 (set (match_operand:XF 0 "register_operand" "")
13778 (plus:XF (match_dup 12) (match_dup 7)))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && flag_unsafe_math_optimizations"
13784 if (optimize_insn_for_size_p ())
13787 for (i = 2; i < 13; i++)
13788 operands[i] = gen_reg_rtx (XFmode);
13791 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13793 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13796 (define_expand "expm1<mode>2"
13797 [(use (match_operand:MODEF 0 "register_operand" ""))
13798 (use (match_operand:MODEF 1 "general_operand" ""))]
13799 "TARGET_USE_FANCY_MATH_387
13800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13801 || TARGET_MIX_SSE_I387)
13802 && flag_unsafe_math_optimizations"
13806 if (optimize_insn_for_size_p ())
13809 op0 = gen_reg_rtx (XFmode);
13810 op1 = gen_reg_rtx (XFmode);
13812 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13813 emit_insn (gen_expm1xf2 (op0, op1));
13814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13818 (define_expand "ldexpxf3"
13819 [(set (match_dup 3)
13820 (float:XF (match_operand:SI 2 "register_operand" "")))
13821 (parallel [(set (match_operand:XF 0 " register_operand" "")
13822 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13824 UNSPEC_FSCALE_FRACT))
13826 (unspec:XF [(match_dup 1) (match_dup 3)]
13827 UNSPEC_FSCALE_EXP))])]
13828 "TARGET_USE_FANCY_MATH_387
13829 && flag_unsafe_math_optimizations"
13831 if (optimize_insn_for_size_p ())
13834 operands[3] = gen_reg_rtx (XFmode);
13835 operands[4] = gen_reg_rtx (XFmode);
13838 (define_expand "ldexp<mode>3"
13839 [(use (match_operand:MODEF 0 "register_operand" ""))
13840 (use (match_operand:MODEF 1 "general_operand" ""))
13841 (use (match_operand:SI 2 "register_operand" ""))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844 || TARGET_MIX_SSE_I387)
13845 && flag_unsafe_math_optimizations"
13849 if (optimize_insn_for_size_p ())
13852 op0 = gen_reg_rtx (XFmode);
13853 op1 = gen_reg_rtx (XFmode);
13855 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13856 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13857 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13861 (define_expand "scalbxf3"
13862 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13863 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13864 (match_operand:XF 2 "register_operand" "")]
13865 UNSPEC_FSCALE_FRACT))
13867 (unspec:XF [(match_dup 1) (match_dup 2)]
13868 UNSPEC_FSCALE_EXP))])]
13869 "TARGET_USE_FANCY_MATH_387
13870 && flag_unsafe_math_optimizations"
13872 if (optimize_insn_for_size_p ())
13875 operands[3] = gen_reg_rtx (XFmode);
13878 (define_expand "scalb<mode>3"
13879 [(use (match_operand:MODEF 0 "register_operand" ""))
13880 (use (match_operand:MODEF 1 "general_operand" ""))
13881 (use (match_operand:MODEF 2 "general_operand" ""))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884 || TARGET_MIX_SSE_I387)
13885 && flag_unsafe_math_optimizations"
13889 if (optimize_insn_for_size_p ())
13892 op0 = gen_reg_rtx (XFmode);
13893 op1 = gen_reg_rtx (XFmode);
13894 op2 = gen_reg_rtx (XFmode);
13896 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13897 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13898 emit_insn (gen_scalbxf3 (op0, op1, op2));
13899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13903 (define_expand "significandxf2"
13904 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13905 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13906 UNSPEC_XTRACT_FRACT))
13908 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13912 operands[2] = gen_reg_rtx (XFmode);
13915 (define_expand "significand<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand" ""))
13917 (use (match_operand:MODEF 1 "register_operand" ""))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13924 rtx op1 = gen_reg_rtx (XFmode);
13926 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13927 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13932 (define_insn "sse4_1_round<mode>2"
13933 [(set (match_operand:MODEF 0 "register_operand" "=x")
13934 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13935 (match_operand:SI 2 "const_0_to_15_operand" "n")]
13938 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13939 [(set_attr "type" "ssecvt")
13940 (set_attr "prefix_extra" "1")
13941 (set_attr "prefix" "maybe_vex")
13942 (set_attr "mode" "<MODE>")])
13944 (define_insn "rintxf2"
13945 [(set (match_operand:XF 0 "register_operand" "=f")
13946 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_unsafe_math_optimizations"
13951 [(set_attr "type" "fpspc")
13952 (set_attr "mode" "XF")])
13954 (define_expand "rint<mode>2"
13955 [(use (match_operand:MODEF 0 "register_operand" ""))
13956 (use (match_operand:MODEF 1 "register_operand" ""))]
13957 "(TARGET_USE_FANCY_MATH_387
13958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959 || TARGET_MIX_SSE_I387)
13960 && flag_unsafe_math_optimizations)
13961 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13962 && !flag_trapping_math)"
13964 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13965 && !flag_trapping_math)
13967 if (!TARGET_ROUND && optimize_insn_for_size_p ())
13970 emit_insn (gen_sse4_1_round<mode>2
13971 (operands[0], operands[1], GEN_INT (0x04)));
13973 ix86_expand_rint (operand0, operand1);
13977 rtx op0 = gen_reg_rtx (XFmode);
13978 rtx op1 = gen_reg_rtx (XFmode);
13980 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13981 emit_insn (gen_rintxf2 (op0, op1));
13983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13988 (define_expand "round<mode>2"
13989 [(match_operand:MODEF 0 "register_operand" "")
13990 (match_operand:MODEF 1 "nonimmediate_operand" "")]
13991 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13992 && !flag_trapping_math && !flag_rounding_math"
13994 if (optimize_insn_for_size_p ())
13996 if (TARGET_64BIT || (<MODE>mode != DFmode))
13997 ix86_expand_round (operand0, operand1);
13999 ix86_expand_rounddf_32 (operand0, operand1);
14003 (define_insn_and_split "*fistdi2_1"
14004 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14005 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14007 "TARGET_USE_FANCY_MATH_387
14008 && can_create_pseudo_p ()"
14013 if (memory_operand (operands[0], VOIDmode))
14014 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14017 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14018 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14023 [(set_attr "type" "fpspc")
14024 (set_attr "mode" "DI")])
14026 (define_insn "fistdi2"
14027 [(set (match_operand:DI 0 "memory_operand" "=m")
14028 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14030 (clobber (match_scratch:XF 2 "=&1f"))]
14031 "TARGET_USE_FANCY_MATH_387"
14032 "* return output_fix_trunc (insn, operands, 0);"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "DI")])
14036 (define_insn "fistdi2_with_temp"
14037 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14038 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14040 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14041 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14042 "TARGET_USE_FANCY_MATH_387"
14044 [(set_attr "type" "fpspc")
14045 (set_attr "mode" "DI")])
14048 [(set (match_operand:DI 0 "register_operand" "")
14049 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14051 (clobber (match_operand:DI 2 "memory_operand" ""))
14052 (clobber (match_scratch 3 ""))]
14054 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14055 (clobber (match_dup 3))])
14056 (set (match_dup 0) (match_dup 2))])
14059 [(set (match_operand:DI 0 "memory_operand" "")
14060 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14062 (clobber (match_operand:DI 2 "memory_operand" ""))
14063 (clobber (match_scratch 3 ""))]
14065 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14066 (clobber (match_dup 3))])])
14068 (define_insn_and_split "*fist<mode>2_1"
14069 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14070 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14072 "TARGET_USE_FANCY_MATH_387
14073 && can_create_pseudo_p ()"
14078 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14079 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14083 [(set_attr "type" "fpspc")
14084 (set_attr "mode" "<MODE>")])
14086 (define_insn "fist<mode>2"
14087 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14088 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14090 "TARGET_USE_FANCY_MATH_387"
14091 "* return output_fix_trunc (insn, operands, 0);"
14092 [(set_attr "type" "fpspc")
14093 (set_attr "mode" "<MODE>")])
14095 (define_insn "fist<mode>2_with_temp"
14096 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14097 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14099 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14100 "TARGET_USE_FANCY_MATH_387"
14102 [(set_attr "type" "fpspc")
14103 (set_attr "mode" "<MODE>")])
14106 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14107 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14109 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14111 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14112 (set (match_dup 0) (match_dup 2))])
14115 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14116 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14118 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14120 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14122 (define_expand "lrintxf<mode>2"
14123 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14124 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14126 "TARGET_USE_FANCY_MATH_387"
14129 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14130 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14131 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14132 UNSPEC_FIX_NOTRUNC))]
14133 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14134 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14137 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14138 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14139 (match_operand:MODEF 1 "register_operand" "")]
14140 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14141 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14142 && !flag_trapping_math && !flag_rounding_math"
14144 if (optimize_insn_for_size_p ())
14146 ix86_expand_lround (operand0, operand1);
14150 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14151 (define_insn_and_split "frndintxf2_floor"
14152 [(set (match_operand:XF 0 "register_operand" "")
14153 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14154 UNSPEC_FRNDINT_FLOOR))
14155 (clobber (reg:CC FLAGS_REG))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_unsafe_math_optimizations
14158 && can_create_pseudo_p ()"
14163 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14165 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14166 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14168 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14169 operands[2], operands[3]));
14172 [(set_attr "type" "frndint")
14173 (set_attr "i387_cw" "floor")
14174 (set_attr "mode" "XF")])
14176 (define_insn "frndintxf2_floor_i387"
14177 [(set (match_operand:XF 0 "register_operand" "=f")
14178 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14179 UNSPEC_FRNDINT_FLOOR))
14180 (use (match_operand:HI 2 "memory_operand" "m"))
14181 (use (match_operand:HI 3 "memory_operand" "m"))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && flag_unsafe_math_optimizations"
14184 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14185 [(set_attr "type" "frndint")
14186 (set_attr "i387_cw" "floor")
14187 (set_attr "mode" "XF")])
14189 (define_expand "floorxf2"
14190 [(use (match_operand:XF 0 "register_operand" ""))
14191 (use (match_operand:XF 1 "register_operand" ""))]
14192 "TARGET_USE_FANCY_MATH_387
14193 && flag_unsafe_math_optimizations"
14195 if (optimize_insn_for_size_p ())
14197 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14201 (define_expand "floor<mode>2"
14202 [(use (match_operand:MODEF 0 "register_operand" ""))
14203 (use (match_operand:MODEF 1 "register_operand" ""))]
14204 "(TARGET_USE_FANCY_MATH_387
14205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14206 || TARGET_MIX_SSE_I387)
14207 && flag_unsafe_math_optimizations)
14208 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14209 && !flag_trapping_math)"
14211 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14212 && !flag_trapping_math
14213 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14215 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14218 emit_insn (gen_sse4_1_round<mode>2
14219 (operands[0], operands[1], GEN_INT (0x01)));
14220 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14221 ix86_expand_floorceil (operand0, operand1, true);
14223 ix86_expand_floorceildf_32 (operand0, operand1, true);
14229 if (optimize_insn_for_size_p ())
14232 op0 = gen_reg_rtx (XFmode);
14233 op1 = gen_reg_rtx (XFmode);
14234 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14235 emit_insn (gen_frndintxf2_floor (op0, op1));
14237 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14242 (define_insn_and_split "*fist<mode>2_floor_1"
14243 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14244 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14245 UNSPEC_FIST_FLOOR))
14246 (clobber (reg:CC FLAGS_REG))]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations
14249 && can_create_pseudo_p ()"
14254 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14256 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14257 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14258 if (memory_operand (operands[0], VOIDmode))
14259 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14260 operands[2], operands[3]));
14263 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14264 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14265 operands[2], operands[3],
14270 [(set_attr "type" "fistp")
14271 (set_attr "i387_cw" "floor")
14272 (set_attr "mode" "<MODE>")])
14274 (define_insn "fistdi2_floor"
14275 [(set (match_operand:DI 0 "memory_operand" "=m")
14276 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14277 UNSPEC_FIST_FLOOR))
14278 (use (match_operand:HI 2 "memory_operand" "m"))
14279 (use (match_operand:HI 3 "memory_operand" "m"))
14280 (clobber (match_scratch:XF 4 "=&1f"))]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14283 "* return output_fix_trunc (insn, operands, 0);"
14284 [(set_attr "type" "fistp")
14285 (set_attr "i387_cw" "floor")
14286 (set_attr "mode" "DI")])
14288 (define_insn "fistdi2_floor_with_temp"
14289 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14290 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14291 UNSPEC_FIST_FLOOR))
14292 (use (match_operand:HI 2 "memory_operand" "m,m"))
14293 (use (match_operand:HI 3 "memory_operand" "m,m"))
14294 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14295 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14296 "TARGET_USE_FANCY_MATH_387
14297 && flag_unsafe_math_optimizations"
14299 [(set_attr "type" "fistp")
14300 (set_attr "i387_cw" "floor")
14301 (set_attr "mode" "DI")])
14304 [(set (match_operand:DI 0 "register_operand" "")
14305 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14306 UNSPEC_FIST_FLOOR))
14307 (use (match_operand:HI 2 "memory_operand" ""))
14308 (use (match_operand:HI 3 "memory_operand" ""))
14309 (clobber (match_operand:DI 4 "memory_operand" ""))
14310 (clobber (match_scratch 5 ""))]
14312 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14313 (use (match_dup 2))
14314 (use (match_dup 3))
14315 (clobber (match_dup 5))])
14316 (set (match_dup 0) (match_dup 4))])
14319 [(set (match_operand:DI 0 "memory_operand" "")
14320 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14321 UNSPEC_FIST_FLOOR))
14322 (use (match_operand:HI 2 "memory_operand" ""))
14323 (use (match_operand:HI 3 "memory_operand" ""))
14324 (clobber (match_operand:DI 4 "memory_operand" ""))
14325 (clobber (match_scratch 5 ""))]
14327 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14328 (use (match_dup 2))
14329 (use (match_dup 3))
14330 (clobber (match_dup 5))])])
14332 (define_insn "fist<mode>2_floor"
14333 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14334 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14335 UNSPEC_FIST_FLOOR))
14336 (use (match_operand:HI 2 "memory_operand" "m"))
14337 (use (match_operand:HI 3 "memory_operand" "m"))]
14338 "TARGET_USE_FANCY_MATH_387
14339 && flag_unsafe_math_optimizations"
14340 "* return output_fix_trunc (insn, operands, 0);"
14341 [(set_attr "type" "fistp")
14342 (set_attr "i387_cw" "floor")
14343 (set_attr "mode" "<MODE>")])
14345 (define_insn "fist<mode>2_floor_with_temp"
14346 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14347 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14348 UNSPEC_FIST_FLOOR))
14349 (use (match_operand:HI 2 "memory_operand" "m,m"))
14350 (use (match_operand:HI 3 "memory_operand" "m,m"))
14351 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14352 "TARGET_USE_FANCY_MATH_387
14353 && flag_unsafe_math_optimizations"
14355 [(set_attr "type" "fistp")
14356 (set_attr "i387_cw" "floor")
14357 (set_attr "mode" "<MODE>")])
14360 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14361 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14362 UNSPEC_FIST_FLOOR))
14363 (use (match_operand:HI 2 "memory_operand" ""))
14364 (use (match_operand:HI 3 "memory_operand" ""))
14365 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14367 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14368 UNSPEC_FIST_FLOOR))
14369 (use (match_dup 2))
14370 (use (match_dup 3))])
14371 (set (match_dup 0) (match_dup 4))])
14374 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14375 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14376 UNSPEC_FIST_FLOOR))
14377 (use (match_operand:HI 2 "memory_operand" ""))
14378 (use (match_operand:HI 3 "memory_operand" ""))
14379 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14381 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14382 UNSPEC_FIST_FLOOR))
14383 (use (match_dup 2))
14384 (use (match_dup 3))])])
14386 (define_expand "lfloorxf<mode>2"
14387 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14388 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14389 UNSPEC_FIST_FLOOR))
14390 (clobber (reg:CC FLAGS_REG))])]
14391 "TARGET_USE_FANCY_MATH_387
14392 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14393 && flag_unsafe_math_optimizations"
14396 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14397 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14398 (match_operand:MODEF 1 "register_operand" "")]
14399 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14400 && !flag_trapping_math"
14402 if (TARGET_64BIT && optimize_insn_for_size_p ())
14404 ix86_expand_lfloorceil (operand0, operand1, true);
14408 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14409 (define_insn_and_split "frndintxf2_ceil"
14410 [(set (match_operand:XF 0 "register_operand" "")
14411 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14412 UNSPEC_FRNDINT_CEIL))
14413 (clobber (reg:CC FLAGS_REG))]
14414 "TARGET_USE_FANCY_MATH_387
14415 && flag_unsafe_math_optimizations
14416 && can_create_pseudo_p ()"
14421 ix86_optimize_mode_switching[I387_CEIL] = 1;
14423 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14424 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14426 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14427 operands[2], operands[3]));
14430 [(set_attr "type" "frndint")
14431 (set_attr "i387_cw" "ceil")
14432 (set_attr "mode" "XF")])
14434 (define_insn "frndintxf2_ceil_i387"
14435 [(set (match_operand:XF 0 "register_operand" "=f")
14436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14437 UNSPEC_FRNDINT_CEIL))
14438 (use (match_operand:HI 2 "memory_operand" "m"))
14439 (use (match_operand:HI 3 "memory_operand" "m"))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && flag_unsafe_math_optimizations"
14442 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14443 [(set_attr "type" "frndint")
14444 (set_attr "i387_cw" "ceil")
14445 (set_attr "mode" "XF")])
14447 (define_expand "ceilxf2"
14448 [(use (match_operand:XF 0 "register_operand" ""))
14449 (use (match_operand:XF 1 "register_operand" ""))]
14450 "TARGET_USE_FANCY_MATH_387
14451 && flag_unsafe_math_optimizations"
14453 if (optimize_insn_for_size_p ())
14455 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14459 (define_expand "ceil<mode>2"
14460 [(use (match_operand:MODEF 0 "register_operand" ""))
14461 (use (match_operand:MODEF 1 "register_operand" ""))]
14462 "(TARGET_USE_FANCY_MATH_387
14463 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14464 || TARGET_MIX_SSE_I387)
14465 && flag_unsafe_math_optimizations)
14466 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14467 && !flag_trapping_math)"
14469 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14470 && !flag_trapping_math
14471 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14474 emit_insn (gen_sse4_1_round<mode>2
14475 (operands[0], operands[1], GEN_INT (0x02)));
14476 else if (optimize_insn_for_size_p ())
14478 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14479 ix86_expand_floorceil (operand0, operand1, false);
14481 ix86_expand_floorceildf_32 (operand0, operand1, false);
14487 if (optimize_insn_for_size_p ())
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14493 emit_insn (gen_frndintxf2_ceil (op0, op1));
14495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14500 (define_insn_and_split "*fist<mode>2_ceil_1"
14501 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14502 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14504 (clobber (reg:CC FLAGS_REG))]
14505 "TARGET_USE_FANCY_MATH_387
14506 && flag_unsafe_math_optimizations
14507 && can_create_pseudo_p ()"
14512 ix86_optimize_mode_switching[I387_CEIL] = 1;
14514 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14515 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14516 if (memory_operand (operands[0], VOIDmode))
14517 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14518 operands[2], operands[3]));
14521 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14522 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14523 operands[2], operands[3],
14528 [(set_attr "type" "fistp")
14529 (set_attr "i387_cw" "ceil")
14530 (set_attr "mode" "<MODE>")])
14532 (define_insn "fistdi2_ceil"
14533 [(set (match_operand:DI 0 "memory_operand" "=m")
14534 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14536 (use (match_operand:HI 2 "memory_operand" "m"))
14537 (use (match_operand:HI 3 "memory_operand" "m"))
14538 (clobber (match_scratch:XF 4 "=&1f"))]
14539 "TARGET_USE_FANCY_MATH_387
14540 && flag_unsafe_math_optimizations"
14541 "* return output_fix_trunc (insn, operands, 0);"
14542 [(set_attr "type" "fistp")
14543 (set_attr "i387_cw" "ceil")
14544 (set_attr "mode" "DI")])
14546 (define_insn "fistdi2_ceil_with_temp"
14547 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14548 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14550 (use (match_operand:HI 2 "memory_operand" "m,m"))
14551 (use (match_operand:HI 3 "memory_operand" "m,m"))
14552 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14553 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14557 [(set_attr "type" "fistp")
14558 (set_attr "i387_cw" "ceil")
14559 (set_attr "mode" "DI")])
14562 [(set (match_operand:DI 0 "register_operand" "")
14563 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14565 (use (match_operand:HI 2 "memory_operand" ""))
14566 (use (match_operand:HI 3 "memory_operand" ""))
14567 (clobber (match_operand:DI 4 "memory_operand" ""))
14568 (clobber (match_scratch 5 ""))]
14570 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14571 (use (match_dup 2))
14572 (use (match_dup 3))
14573 (clobber (match_dup 5))])
14574 (set (match_dup 0) (match_dup 4))])
14577 [(set (match_operand:DI 0 "memory_operand" "")
14578 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14580 (use (match_operand:HI 2 "memory_operand" ""))
14581 (use (match_operand:HI 3 "memory_operand" ""))
14582 (clobber (match_operand:DI 4 "memory_operand" ""))
14583 (clobber (match_scratch 5 ""))]
14585 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14586 (use (match_dup 2))
14587 (use (match_dup 3))
14588 (clobber (match_dup 5))])])
14590 (define_insn "fist<mode>2_ceil"
14591 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14592 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14594 (use (match_operand:HI 2 "memory_operand" "m"))
14595 (use (match_operand:HI 3 "memory_operand" "m"))]
14596 "TARGET_USE_FANCY_MATH_387
14597 && flag_unsafe_math_optimizations"
14598 "* return output_fix_trunc (insn, operands, 0);"
14599 [(set_attr "type" "fistp")
14600 (set_attr "i387_cw" "ceil")
14601 (set_attr "mode" "<MODE>")])
14603 (define_insn "fist<mode>2_ceil_with_temp"
14604 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14605 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14607 (use (match_operand:HI 2 "memory_operand" "m,m"))
14608 (use (match_operand:HI 3 "memory_operand" "m,m"))
14609 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && flag_unsafe_math_optimizations"
14613 [(set_attr "type" "fistp")
14614 (set_attr "i387_cw" "ceil")
14615 (set_attr "mode" "<MODE>")])
14618 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14619 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14621 (use (match_operand:HI 2 "memory_operand" ""))
14622 (use (match_operand:HI 3 "memory_operand" ""))
14623 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14625 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14627 (use (match_dup 2))
14628 (use (match_dup 3))])
14629 (set (match_dup 0) (match_dup 4))])
14632 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14635 (use (match_operand:HI 2 "memory_operand" ""))
14636 (use (match_operand:HI 3 "memory_operand" ""))
14637 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14639 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14641 (use (match_dup 2))
14642 (use (match_dup 3))])])
14644 (define_expand "lceilxf<mode>2"
14645 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14646 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14648 (clobber (reg:CC FLAGS_REG))])]
14649 "TARGET_USE_FANCY_MATH_387
14650 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14651 && flag_unsafe_math_optimizations"
14654 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14655 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14656 (match_operand:MODEF 1 "register_operand" "")]
14657 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14658 && !flag_trapping_math"
14660 ix86_expand_lfloorceil (operand0, operand1, false);
14664 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14665 (define_insn_and_split "frndintxf2_trunc"
14666 [(set (match_operand:XF 0 "register_operand" "")
14667 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14668 UNSPEC_FRNDINT_TRUNC))
14669 (clobber (reg:CC FLAGS_REG))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations
14672 && can_create_pseudo_p ()"
14677 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14679 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14680 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14682 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14683 operands[2], operands[3]));
14686 [(set_attr "type" "frndint")
14687 (set_attr "i387_cw" "trunc")
14688 (set_attr "mode" "XF")])
14690 (define_insn "frndintxf2_trunc_i387"
14691 [(set (match_operand:XF 0 "register_operand" "=f")
14692 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14693 UNSPEC_FRNDINT_TRUNC))
14694 (use (match_operand:HI 2 "memory_operand" "m"))
14695 (use (match_operand:HI 3 "memory_operand" "m"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_unsafe_math_optimizations"
14698 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14699 [(set_attr "type" "frndint")
14700 (set_attr "i387_cw" "trunc")
14701 (set_attr "mode" "XF")])
14703 (define_expand "btruncxf2"
14704 [(use (match_operand:XF 0 "register_operand" ""))
14705 (use (match_operand:XF 1 "register_operand" ""))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && flag_unsafe_math_optimizations"
14709 if (optimize_insn_for_size_p ())
14711 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14715 (define_expand "btrunc<mode>2"
14716 [(use (match_operand:MODEF 0 "register_operand" ""))
14717 (use (match_operand:MODEF 1 "register_operand" ""))]
14718 "(TARGET_USE_FANCY_MATH_387
14719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14720 || TARGET_MIX_SSE_I387)
14721 && flag_unsafe_math_optimizations)
14722 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14723 && !flag_trapping_math)"
14725 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14726 && !flag_trapping_math
14727 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14730 emit_insn (gen_sse4_1_round<mode>2
14731 (operands[0], operands[1], GEN_INT (0x03)));
14732 else if (optimize_insn_for_size_p ())
14734 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14735 ix86_expand_trunc (operand0, operand1);
14737 ix86_expand_truncdf_32 (operand0, operand1);
14743 if (optimize_insn_for_size_p ())
14746 op0 = gen_reg_rtx (XFmode);
14747 op1 = gen_reg_rtx (XFmode);
14748 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14749 emit_insn (gen_frndintxf2_trunc (op0, op1));
14751 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14756 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14757 (define_insn_and_split "frndintxf2_mask_pm"
14758 [(set (match_operand:XF 0 "register_operand" "")
14759 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14760 UNSPEC_FRNDINT_MASK_PM))
14761 (clobber (reg:CC FLAGS_REG))]
14762 "TARGET_USE_FANCY_MATH_387
14763 && flag_unsafe_math_optimizations
14764 && can_create_pseudo_p ()"
14769 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14771 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14772 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14774 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14775 operands[2], operands[3]));
14778 [(set_attr "type" "frndint")
14779 (set_attr "i387_cw" "mask_pm")
14780 (set_attr "mode" "XF")])
14782 (define_insn "frndintxf2_mask_pm_i387"
14783 [(set (match_operand:XF 0 "register_operand" "=f")
14784 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14785 UNSPEC_FRNDINT_MASK_PM))
14786 (use (match_operand:HI 2 "memory_operand" "m"))
14787 (use (match_operand:HI 3 "memory_operand" "m"))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations"
14790 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14791 [(set_attr "type" "frndint")
14792 (set_attr "i387_cw" "mask_pm")
14793 (set_attr "mode" "XF")])
14795 (define_expand "nearbyintxf2"
14796 [(use (match_operand:XF 0 "register_operand" ""))
14797 (use (match_operand:XF 1 "register_operand" ""))]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14801 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14806 (define_expand "nearbyint<mode>2"
14807 [(use (match_operand:MODEF 0 "register_operand" ""))
14808 (use (match_operand:MODEF 1 "register_operand" ""))]
14809 "TARGET_USE_FANCY_MATH_387
14810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14811 || TARGET_MIX_SSE_I387)
14812 && flag_unsafe_math_optimizations"
14814 rtx op0 = gen_reg_rtx (XFmode);
14815 rtx op1 = gen_reg_rtx (XFmode);
14817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14820 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14824 (define_insn "fxam<mode>2_i387"
14825 [(set (match_operand:HI 0 "register_operand" "=a")
14827 [(match_operand:X87MODEF 1 "register_operand" "f")]
14829 "TARGET_USE_FANCY_MATH_387"
14830 "fxam\n\tfnstsw\t%0"
14831 [(set_attr "type" "multi")
14832 (set_attr "length" "4")
14833 (set_attr "unit" "i387")
14834 (set_attr "mode" "<MODE>")])
14836 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14837 [(set (match_operand:HI 0 "register_operand" "")
14839 [(match_operand:MODEF 1 "memory_operand" "")]
14841 "TARGET_USE_FANCY_MATH_387
14842 && can_create_pseudo_p ()"
14845 [(set (match_dup 2)(match_dup 1))
14847 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14849 operands[2] = gen_reg_rtx (<MODE>mode);
14851 MEM_VOLATILE_P (operands[1]) = 1;
14853 [(set_attr "type" "multi")
14854 (set_attr "unit" "i387")
14855 (set_attr "mode" "<MODE>")])
14857 (define_expand "isinfxf2"
14858 [(use (match_operand:SI 0 "register_operand" ""))
14859 (use (match_operand:XF 1 "register_operand" ""))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && TARGET_C99_FUNCTIONS"
14863 rtx mask = GEN_INT (0x45);
14864 rtx val = GEN_INT (0x05);
14868 rtx scratch = gen_reg_rtx (HImode);
14869 rtx res = gen_reg_rtx (QImode);
14871 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14873 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14874 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14875 cond = gen_rtx_fmt_ee (EQ, QImode,
14876 gen_rtx_REG (CCmode, FLAGS_REG),
14878 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14879 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14883 (define_expand "isinf<mode>2"
14884 [(use (match_operand:SI 0 "register_operand" ""))
14885 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14886 "TARGET_USE_FANCY_MATH_387
14887 && TARGET_C99_FUNCTIONS
14888 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14890 rtx mask = GEN_INT (0x45);
14891 rtx val = GEN_INT (0x05);
14895 rtx scratch = gen_reg_rtx (HImode);
14896 rtx res = gen_reg_rtx (QImode);
14898 /* Remove excess precision by forcing value through memory. */
14899 if (memory_operand (operands[1], VOIDmode))
14900 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14903 enum ix86_stack_slot slot = (virtuals_instantiated
14906 rtx temp = assign_386_stack_local (<MODE>mode, slot);
14908 emit_move_insn (temp, operands[1]);
14909 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14912 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14913 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14914 cond = gen_rtx_fmt_ee (EQ, QImode,
14915 gen_rtx_REG (CCmode, FLAGS_REG),
14917 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14918 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14922 (define_expand "signbit<mode>2"
14923 [(use (match_operand:SI 0 "register_operand" ""))
14924 (use (match_operand:X87MODEF 1 "register_operand" ""))]
14925 "TARGET_USE_FANCY_MATH_387
14926 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14928 rtx mask = GEN_INT (0x0200);
14930 rtx scratch = gen_reg_rtx (HImode);
14932 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14933 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14937 ;; Block operation instructions
14940 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14943 [(set_attr "length" "1")
14944 (set_attr "length_immediate" "0")
14945 (set_attr "modrm" "0")])
14947 (define_expand "movmemsi"
14948 [(use (match_operand:BLK 0 "memory_operand" ""))
14949 (use (match_operand:BLK 1 "memory_operand" ""))
14950 (use (match_operand:SI 2 "nonmemory_operand" ""))
14951 (use (match_operand:SI 3 "const_int_operand" ""))
14952 (use (match_operand:SI 4 "const_int_operand" ""))
14953 (use (match_operand:SI 5 "const_int_operand" ""))]
14956 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14957 operands[4], operands[5]))
14963 (define_expand "movmemdi"
14964 [(use (match_operand:BLK 0 "memory_operand" ""))
14965 (use (match_operand:BLK 1 "memory_operand" ""))
14966 (use (match_operand:DI 2 "nonmemory_operand" ""))
14967 (use (match_operand:DI 3 "const_int_operand" ""))
14968 (use (match_operand:SI 4 "const_int_operand" ""))
14969 (use (match_operand:SI 5 "const_int_operand" ""))]
14972 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14973 operands[4], operands[5]))
14979 ;; Most CPUs don't like single string operations
14980 ;; Handle this case here to simplify previous expander.
14982 (define_expand "strmov"
14983 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
14984 (set (match_operand 1 "memory_operand" "") (match_dup 4))
14985 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
14986 (clobber (reg:CC FLAGS_REG))])
14987 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
14988 (clobber (reg:CC FLAGS_REG))])]
14991 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14993 /* If .md ever supports :P for Pmode, these can be directly
14994 in the pattern above. */
14995 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14996 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14998 /* Can't use this if the user has appropriated esi or edi. */
14999 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15000 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15002 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15003 operands[2], operands[3],
15004 operands[5], operands[6]));
15008 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15011 (define_expand "strmov_singleop"
15012 [(parallel [(set (match_operand 1 "memory_operand" "")
15013 (match_operand 3 "memory_operand" ""))
15014 (set (match_operand 0 "register_operand" "")
15015 (match_operand 4 "" ""))
15016 (set (match_operand 2 "register_operand" "")
15017 (match_operand 5 "" ""))])]
15019 "ix86_current_function_needs_cld = 1;")
15021 (define_insn "*strmovdi_rex_1"
15022 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15023 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15024 (set (match_operand:DI 0 "register_operand" "=D")
15025 (plus:DI (match_dup 2)
15027 (set (match_operand:DI 1 "register_operand" "=S")
15028 (plus:DI (match_dup 3)
15032 [(set_attr "type" "str")
15033 (set_attr "mode" "DI")
15034 (set_attr "memory" "both")])
15036 (define_insn "*strmovsi_1"
15037 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15038 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15039 (set (match_operand:SI 0 "register_operand" "=D")
15040 (plus:SI (match_dup 2)
15042 (set (match_operand:SI 1 "register_operand" "=S")
15043 (plus:SI (match_dup 3)
15047 [(set_attr "type" "str")
15048 (set_attr "mode" "SI")
15049 (set_attr "memory" "both")])
15051 (define_insn "*strmovsi_rex_1"
15052 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15053 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15054 (set (match_operand:DI 0 "register_operand" "=D")
15055 (plus:DI (match_dup 2)
15057 (set (match_operand:DI 1 "register_operand" "=S")
15058 (plus:DI (match_dup 3)
15062 [(set_attr "type" "str")
15063 (set_attr "mode" "SI")
15064 (set_attr "memory" "both")])
15066 (define_insn "*strmovhi_1"
15067 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15068 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15069 (set (match_operand:SI 0 "register_operand" "=D")
15070 (plus:SI (match_dup 2)
15072 (set (match_operand:SI 1 "register_operand" "=S")
15073 (plus:SI (match_dup 3)
15077 [(set_attr "type" "str")
15078 (set_attr "memory" "both")
15079 (set_attr "mode" "HI")])
15081 (define_insn "*strmovhi_rex_1"
15082 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15083 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15084 (set (match_operand:DI 0 "register_operand" "=D")
15085 (plus:DI (match_dup 2)
15087 (set (match_operand:DI 1 "register_operand" "=S")
15088 (plus:DI (match_dup 3)
15092 [(set_attr "type" "str")
15093 (set_attr "memory" "both")
15094 (set_attr "mode" "HI")])
15096 (define_insn "*strmovqi_1"
15097 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15098 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15099 (set (match_operand:SI 0 "register_operand" "=D")
15100 (plus:SI (match_dup 2)
15102 (set (match_operand:SI 1 "register_operand" "=S")
15103 (plus:SI (match_dup 3)
15107 [(set_attr "type" "str")
15108 (set_attr "memory" "both")
15109 (set_attr "mode" "QI")])
15111 (define_insn "*strmovqi_rex_1"
15112 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15113 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15114 (set (match_operand:DI 0 "register_operand" "=D")
15115 (plus:DI (match_dup 2)
15117 (set (match_operand:DI 1 "register_operand" "=S")
15118 (plus:DI (match_dup 3)
15122 [(set_attr "type" "str")
15123 (set_attr "memory" "both")
15124 (set_attr "prefix_rex" "0")
15125 (set_attr "mode" "QI")])
15127 (define_expand "rep_mov"
15128 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15129 (set (match_operand 0 "register_operand" "")
15130 (match_operand 5 "" ""))
15131 (set (match_operand 2 "register_operand" "")
15132 (match_operand 6 "" ""))
15133 (set (match_operand 1 "memory_operand" "")
15134 (match_operand 3 "memory_operand" ""))
15135 (use (match_dup 4))])]
15137 "ix86_current_function_needs_cld = 1;")
15139 (define_insn "*rep_movdi_rex64"
15140 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15141 (set (match_operand:DI 0 "register_operand" "=D")
15142 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15144 (match_operand:DI 3 "register_operand" "0")))
15145 (set (match_operand:DI 1 "register_operand" "=S")
15146 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15147 (match_operand:DI 4 "register_operand" "1")))
15148 (set (mem:BLK (match_dup 3))
15149 (mem:BLK (match_dup 4)))
15150 (use (match_dup 5))]
15153 [(set_attr "type" "str")
15154 (set_attr "prefix_rep" "1")
15155 (set_attr "memory" "both")
15156 (set_attr "mode" "DI")])
15158 (define_insn "*rep_movsi"
15159 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15160 (set (match_operand:SI 0 "register_operand" "=D")
15161 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15163 (match_operand:SI 3 "register_operand" "0")))
15164 (set (match_operand:SI 1 "register_operand" "=S")
15165 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15166 (match_operand:SI 4 "register_operand" "1")))
15167 (set (mem:BLK (match_dup 3))
15168 (mem:BLK (match_dup 4)))
15169 (use (match_dup 5))]
15171 "rep{%;} movs{l|d}"
15172 [(set_attr "type" "str")
15173 (set_attr "prefix_rep" "1")
15174 (set_attr "memory" "both")
15175 (set_attr "mode" "SI")])
15177 (define_insn "*rep_movsi_rex64"
15178 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15179 (set (match_operand:DI 0 "register_operand" "=D")
15180 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15182 (match_operand:DI 3 "register_operand" "0")))
15183 (set (match_operand:DI 1 "register_operand" "=S")
15184 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15185 (match_operand:DI 4 "register_operand" "1")))
15186 (set (mem:BLK (match_dup 3))
15187 (mem:BLK (match_dup 4)))
15188 (use (match_dup 5))]
15190 "rep{%;} movs{l|d}"
15191 [(set_attr "type" "str")
15192 (set_attr "prefix_rep" "1")
15193 (set_attr "memory" "both")
15194 (set_attr "mode" "SI")])
15196 (define_insn "*rep_movqi"
15197 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15198 (set (match_operand:SI 0 "register_operand" "=D")
15199 (plus:SI (match_operand:SI 3 "register_operand" "0")
15200 (match_operand:SI 5 "register_operand" "2")))
15201 (set (match_operand:SI 1 "register_operand" "=S")
15202 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15203 (set (mem:BLK (match_dup 3))
15204 (mem:BLK (match_dup 4)))
15205 (use (match_dup 5))]
15208 [(set_attr "type" "str")
15209 (set_attr "prefix_rep" "1")
15210 (set_attr "memory" "both")
15211 (set_attr "mode" "SI")])
15213 (define_insn "*rep_movqi_rex64"
15214 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15215 (set (match_operand:DI 0 "register_operand" "=D")
15216 (plus:DI (match_operand:DI 3 "register_operand" "0")
15217 (match_operand:DI 5 "register_operand" "2")))
15218 (set (match_operand:DI 1 "register_operand" "=S")
15219 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15220 (set (mem:BLK (match_dup 3))
15221 (mem:BLK (match_dup 4)))
15222 (use (match_dup 5))]
15225 [(set_attr "type" "str")
15226 (set_attr "prefix_rep" "1")
15227 (set_attr "memory" "both")
15228 (set_attr "mode" "SI")])
15230 (define_expand "setmemsi"
15231 [(use (match_operand:BLK 0 "memory_operand" ""))
15232 (use (match_operand:SI 1 "nonmemory_operand" ""))
15233 (use (match_operand 2 "const_int_operand" ""))
15234 (use (match_operand 3 "const_int_operand" ""))
15235 (use (match_operand:SI 4 "const_int_operand" ""))
15236 (use (match_operand:SI 5 "const_int_operand" ""))]
15239 if (ix86_expand_setmem (operands[0], operands[1],
15240 operands[2], operands[3],
15241 operands[4], operands[5]))
15247 (define_expand "setmemdi"
15248 [(use (match_operand:BLK 0 "memory_operand" ""))
15249 (use (match_operand:DI 1 "nonmemory_operand" ""))
15250 (use (match_operand 2 "const_int_operand" ""))
15251 (use (match_operand 3 "const_int_operand" ""))
15252 (use (match_operand 4 "const_int_operand" ""))
15253 (use (match_operand 5 "const_int_operand" ""))]
15256 if (ix86_expand_setmem (operands[0], operands[1],
15257 operands[2], operands[3],
15258 operands[4], operands[5]))
15264 ;; Most CPUs don't like single string operations
15265 ;; Handle this case here to simplify previous expander.
15267 (define_expand "strset"
15268 [(set (match_operand 1 "memory_operand" "")
15269 (match_operand 2 "register_operand" ""))
15270 (parallel [(set (match_operand 0 "register_operand" "")
15272 (clobber (reg:CC FLAGS_REG))])]
15275 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15276 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15278 /* If .md ever supports :P for Pmode, this can be directly
15279 in the pattern above. */
15280 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15281 GEN_INT (GET_MODE_SIZE (GET_MODE
15283 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15285 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15291 (define_expand "strset_singleop"
15292 [(parallel [(set (match_operand 1 "memory_operand" "")
15293 (match_operand 2 "register_operand" ""))
15294 (set (match_operand 0 "register_operand" "")
15295 (match_operand 3 "" ""))])]
15297 "ix86_current_function_needs_cld = 1;")
15299 (define_insn "*strsetdi_rex_1"
15300 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15301 (match_operand:DI 2 "register_operand" "a"))
15302 (set (match_operand:DI 0 "register_operand" "=D")
15303 (plus:DI (match_dup 1)
15307 [(set_attr "type" "str")
15308 (set_attr "memory" "store")
15309 (set_attr "mode" "DI")])
15311 (define_insn "*strsetsi_1"
15312 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15313 (match_operand:SI 2 "register_operand" "a"))
15314 (set (match_operand:SI 0 "register_operand" "=D")
15315 (plus:SI (match_dup 1)
15319 [(set_attr "type" "str")
15320 (set_attr "memory" "store")
15321 (set_attr "mode" "SI")])
15323 (define_insn "*strsetsi_rex_1"
15324 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15325 (match_operand:SI 2 "register_operand" "a"))
15326 (set (match_operand:DI 0 "register_operand" "=D")
15327 (plus:DI (match_dup 1)
15331 [(set_attr "type" "str")
15332 (set_attr "memory" "store")
15333 (set_attr "mode" "SI")])
15335 (define_insn "*strsethi_1"
15336 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15337 (match_operand:HI 2 "register_operand" "a"))
15338 (set (match_operand:SI 0 "register_operand" "=D")
15339 (plus:SI (match_dup 1)
15343 [(set_attr "type" "str")
15344 (set_attr "memory" "store")
15345 (set_attr "mode" "HI")])
15347 (define_insn "*strsethi_rex_1"
15348 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15349 (match_operand:HI 2 "register_operand" "a"))
15350 (set (match_operand:DI 0 "register_operand" "=D")
15351 (plus:DI (match_dup 1)
15355 [(set_attr "type" "str")
15356 (set_attr "memory" "store")
15357 (set_attr "mode" "HI")])
15359 (define_insn "*strsetqi_1"
15360 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15361 (match_operand:QI 2 "register_operand" "a"))
15362 (set (match_operand:SI 0 "register_operand" "=D")
15363 (plus:SI (match_dup 1)
15367 [(set_attr "type" "str")
15368 (set_attr "memory" "store")
15369 (set_attr "mode" "QI")])
15371 (define_insn "*strsetqi_rex_1"
15372 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15373 (match_operand:QI 2 "register_operand" "a"))
15374 (set (match_operand:DI 0 "register_operand" "=D")
15375 (plus:DI (match_dup 1)
15379 [(set_attr "type" "str")
15380 (set_attr "memory" "store")
15381 (set_attr "prefix_rex" "0")
15382 (set_attr "mode" "QI")])
15384 (define_expand "rep_stos"
15385 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15386 (set (match_operand 0 "register_operand" "")
15387 (match_operand 4 "" ""))
15388 (set (match_operand 2 "memory_operand" "") (const_int 0))
15389 (use (match_operand 3 "register_operand" ""))
15390 (use (match_dup 1))])]
15392 "ix86_current_function_needs_cld = 1;")
15394 (define_insn "*rep_stosdi_rex64"
15395 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15396 (set (match_operand:DI 0 "register_operand" "=D")
15397 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15399 (match_operand:DI 3 "register_operand" "0")))
15400 (set (mem:BLK (match_dup 3))
15402 (use (match_operand:DI 2 "register_operand" "a"))
15403 (use (match_dup 4))]
15406 [(set_attr "type" "str")
15407 (set_attr "prefix_rep" "1")
15408 (set_attr "memory" "store")
15409 (set_attr "mode" "DI")])
15411 (define_insn "*rep_stossi"
15412 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15413 (set (match_operand:SI 0 "register_operand" "=D")
15414 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15416 (match_operand:SI 3 "register_operand" "0")))
15417 (set (mem:BLK (match_dup 3))
15419 (use (match_operand:SI 2 "register_operand" "a"))
15420 (use (match_dup 4))]
15422 "rep{%;} stos{l|d}"
15423 [(set_attr "type" "str")
15424 (set_attr "prefix_rep" "1")
15425 (set_attr "memory" "store")
15426 (set_attr "mode" "SI")])
15428 (define_insn "*rep_stossi_rex64"
15429 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15430 (set (match_operand:DI 0 "register_operand" "=D")
15431 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15433 (match_operand:DI 3 "register_operand" "0")))
15434 (set (mem:BLK (match_dup 3))
15436 (use (match_operand:SI 2 "register_operand" "a"))
15437 (use (match_dup 4))]
15439 "rep{%;} stos{l|d}"
15440 [(set_attr "type" "str")
15441 (set_attr "prefix_rep" "1")
15442 (set_attr "memory" "store")
15443 (set_attr "mode" "SI")])
15445 (define_insn "*rep_stosqi"
15446 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15447 (set (match_operand:SI 0 "register_operand" "=D")
15448 (plus:SI (match_operand:SI 3 "register_operand" "0")
15449 (match_operand:SI 4 "register_operand" "1")))
15450 (set (mem:BLK (match_dup 3))
15452 (use (match_operand:QI 2 "register_operand" "a"))
15453 (use (match_dup 4))]
15456 [(set_attr "type" "str")
15457 (set_attr "prefix_rep" "1")
15458 (set_attr "memory" "store")
15459 (set_attr "mode" "QI")])
15461 (define_insn "*rep_stosqi_rex64"
15462 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15463 (set (match_operand:DI 0 "register_operand" "=D")
15464 (plus:DI (match_operand:DI 3 "register_operand" "0")
15465 (match_operand:DI 4 "register_operand" "1")))
15466 (set (mem:BLK (match_dup 3))
15468 (use (match_operand:QI 2 "register_operand" "a"))
15469 (use (match_dup 4))]
15472 [(set_attr "type" "str")
15473 (set_attr "prefix_rep" "1")
15474 (set_attr "memory" "store")
15475 (set_attr "prefix_rex" "0")
15476 (set_attr "mode" "QI")])
15478 (define_expand "cmpstrnsi"
15479 [(set (match_operand:SI 0 "register_operand" "")
15480 (compare:SI (match_operand:BLK 1 "general_operand" "")
15481 (match_operand:BLK 2 "general_operand" "")))
15482 (use (match_operand 3 "general_operand" ""))
15483 (use (match_operand 4 "immediate_operand" ""))]
15486 rtx addr1, addr2, out, outlow, count, countreg, align;
15488 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15491 /* Can't use this if the user has appropriated esi or edi. */
15492 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15497 out = gen_reg_rtx (SImode);
15499 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15500 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15501 if (addr1 != XEXP (operands[1], 0))
15502 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15503 if (addr2 != XEXP (operands[2], 0))
15504 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15506 count = operands[3];
15507 countreg = ix86_zero_extend_to_Pmode (count);
15509 /* %%% Iff we are testing strict equality, we can use known alignment
15510 to good advantage. This may be possible with combine, particularly
15511 once cc0 is dead. */
15512 align = operands[4];
15514 if (CONST_INT_P (count))
15516 if (INTVAL (count) == 0)
15518 emit_move_insn (operands[0], const0_rtx);
15521 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15522 operands[1], operands[2]));
15526 rtx (*gen_cmp) (rtx, rtx);
15528 gen_cmp = (TARGET_64BIT
15529 ? gen_cmpdi_1 : gen_cmpsi_1);
15531 emit_insn (gen_cmp (countreg, countreg));
15532 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15533 operands[1], operands[2]));
15536 outlow = gen_lowpart (QImode, out);
15537 emit_insn (gen_cmpintqi (outlow));
15538 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15540 if (operands[0] != out)
15541 emit_move_insn (operands[0], out);
15546 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15548 (define_expand "cmpintqi"
15549 [(set (match_dup 1)
15550 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15552 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15553 (parallel [(set (match_operand:QI 0 "register_operand" "")
15554 (minus:QI (match_dup 1)
15556 (clobber (reg:CC FLAGS_REG))])]
15558 "operands[1] = gen_reg_rtx (QImode);
15559 operands[2] = gen_reg_rtx (QImode);")
15561 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15562 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15564 (define_expand "cmpstrnqi_nz_1"
15565 [(parallel [(set (reg:CC FLAGS_REG)
15566 (compare:CC (match_operand 4 "memory_operand" "")
15567 (match_operand 5 "memory_operand" "")))
15568 (use (match_operand 2 "register_operand" ""))
15569 (use (match_operand:SI 3 "immediate_operand" ""))
15570 (clobber (match_operand 0 "register_operand" ""))
15571 (clobber (match_operand 1 "register_operand" ""))
15572 (clobber (match_dup 2))])]
15574 "ix86_current_function_needs_cld = 1;")
15576 (define_insn "*cmpstrnqi_nz_1"
15577 [(set (reg:CC FLAGS_REG)
15578 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15579 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15580 (use (match_operand:SI 6 "register_operand" "2"))
15581 (use (match_operand:SI 3 "immediate_operand" "i"))
15582 (clobber (match_operand:SI 0 "register_operand" "=S"))
15583 (clobber (match_operand:SI 1 "register_operand" "=D"))
15584 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15587 [(set_attr "type" "str")
15588 (set_attr "mode" "QI")
15589 (set_attr "prefix_rep" "1")])
15591 (define_insn "*cmpstrnqi_nz_rex_1"
15592 [(set (reg:CC FLAGS_REG)
15593 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15594 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15595 (use (match_operand:DI 6 "register_operand" "2"))
15596 (use (match_operand:SI 3 "immediate_operand" "i"))
15597 (clobber (match_operand:DI 0 "register_operand" "=S"))
15598 (clobber (match_operand:DI 1 "register_operand" "=D"))
15599 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15602 [(set_attr "type" "str")
15603 (set_attr "mode" "QI")
15604 (set_attr "prefix_rex" "0")
15605 (set_attr "prefix_rep" "1")])
15607 ;; The same, but the count is not known to not be zero.
15609 (define_expand "cmpstrnqi_1"
15610 [(parallel [(set (reg:CC FLAGS_REG)
15611 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15613 (compare:CC (match_operand 4 "memory_operand" "")
15614 (match_operand 5 "memory_operand" ""))
15616 (use (match_operand:SI 3 "immediate_operand" ""))
15617 (use (reg:CC FLAGS_REG))
15618 (clobber (match_operand 0 "register_operand" ""))
15619 (clobber (match_operand 1 "register_operand" ""))
15620 (clobber (match_dup 2))])]
15622 "ix86_current_function_needs_cld = 1;")
15624 (define_insn "*cmpstrnqi_1"
15625 [(set (reg:CC FLAGS_REG)
15626 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15628 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15629 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15631 (use (match_operand:SI 3 "immediate_operand" "i"))
15632 (use (reg:CC FLAGS_REG))
15633 (clobber (match_operand:SI 0 "register_operand" "=S"))
15634 (clobber (match_operand:SI 1 "register_operand" "=D"))
15635 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15638 [(set_attr "type" "str")
15639 (set_attr "mode" "QI")
15640 (set_attr "prefix_rep" "1")])
15642 (define_insn "*cmpstrnqi_rex_1"
15643 [(set (reg:CC FLAGS_REG)
15644 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15646 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15647 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15649 (use (match_operand:SI 3 "immediate_operand" "i"))
15650 (use (reg:CC FLAGS_REG))
15651 (clobber (match_operand:DI 0 "register_operand" "=S"))
15652 (clobber (match_operand:DI 1 "register_operand" "=D"))
15653 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15656 [(set_attr "type" "str")
15657 (set_attr "mode" "QI")
15658 (set_attr "prefix_rex" "0")
15659 (set_attr "prefix_rep" "1")])
15661 (define_expand "strlensi"
15662 [(set (match_operand:SI 0 "register_operand" "")
15663 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15664 (match_operand:QI 2 "immediate_operand" "")
15665 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15668 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15674 (define_expand "strlendi"
15675 [(set (match_operand:DI 0 "register_operand" "")
15676 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15677 (match_operand:QI 2 "immediate_operand" "")
15678 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15681 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15687 (define_expand "strlenqi_1"
15688 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15689 (clobber (match_operand 1 "register_operand" ""))
15690 (clobber (reg:CC FLAGS_REG))])]
15692 "ix86_current_function_needs_cld = 1;")
15694 (define_insn "*strlenqi_1"
15695 [(set (match_operand:SI 0 "register_operand" "=&c")
15696 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15697 (match_operand:QI 2 "register_operand" "a")
15698 (match_operand:SI 3 "immediate_operand" "i")
15699 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15700 (clobber (match_operand:SI 1 "register_operand" "=D"))
15701 (clobber (reg:CC FLAGS_REG))]
15704 [(set_attr "type" "str")
15705 (set_attr "mode" "QI")
15706 (set_attr "prefix_rep" "1")])
15708 (define_insn "*strlenqi_rex_1"
15709 [(set (match_operand:DI 0 "register_operand" "=&c")
15710 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15711 (match_operand:QI 2 "register_operand" "a")
15712 (match_operand:DI 3 "immediate_operand" "i")
15713 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15714 (clobber (match_operand:DI 1 "register_operand" "=D"))
15715 (clobber (reg:CC FLAGS_REG))]
15718 [(set_attr "type" "str")
15719 (set_attr "mode" "QI")
15720 (set_attr "prefix_rex" "0")
15721 (set_attr "prefix_rep" "1")])
15723 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15724 ;; handled in combine, but it is not currently up to the task.
15725 ;; When used for their truth value, the cmpstrn* expanders generate
15734 ;; The intermediate three instructions are unnecessary.
15736 ;; This one handles cmpstrn*_nz_1...
15739 (set (reg:CC FLAGS_REG)
15740 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15741 (mem:BLK (match_operand 5 "register_operand" ""))))
15742 (use (match_operand 6 "register_operand" ""))
15743 (use (match_operand:SI 3 "immediate_operand" ""))
15744 (clobber (match_operand 0 "register_operand" ""))
15745 (clobber (match_operand 1 "register_operand" ""))
15746 (clobber (match_operand 2 "register_operand" ""))])
15747 (set (match_operand:QI 7 "register_operand" "")
15748 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15749 (set (match_operand:QI 8 "register_operand" "")
15750 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15751 (set (reg FLAGS_REG)
15752 (compare (match_dup 7) (match_dup 8)))
15754 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15756 (set (reg:CC FLAGS_REG)
15757 (compare:CC (mem:BLK (match_dup 4))
15758 (mem:BLK (match_dup 5))))
15759 (use (match_dup 6))
15760 (use (match_dup 3))
15761 (clobber (match_dup 0))
15762 (clobber (match_dup 1))
15763 (clobber (match_dup 2))])])
15765 ;; ...and this one handles cmpstrn*_1.
15768 (set (reg:CC FLAGS_REG)
15769 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15771 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15772 (mem:BLK (match_operand 5 "register_operand" "")))
15774 (use (match_operand:SI 3 "immediate_operand" ""))
15775 (use (reg:CC FLAGS_REG))
15776 (clobber (match_operand 0 "register_operand" ""))
15777 (clobber (match_operand 1 "register_operand" ""))
15778 (clobber (match_operand 2 "register_operand" ""))])
15779 (set (match_operand:QI 7 "register_operand" "")
15780 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15781 (set (match_operand:QI 8 "register_operand" "")
15782 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15783 (set (reg FLAGS_REG)
15784 (compare (match_dup 7) (match_dup 8)))
15786 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15788 (set (reg:CC FLAGS_REG)
15789 (if_then_else:CC (ne (match_dup 6)
15791 (compare:CC (mem:BLK (match_dup 4))
15792 (mem:BLK (match_dup 5)))
15794 (use (match_dup 3))
15795 (use (reg:CC FLAGS_REG))
15796 (clobber (match_dup 0))
15797 (clobber (match_dup 1))
15798 (clobber (match_dup 2))])])
15800 ;; Conditional move instructions.
15802 (define_expand "mov<mode>cc"
15803 [(set (match_operand:SWIM 0 "register_operand" "")
15804 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15805 (match_operand:SWIM 2 "general_operand" "")
15806 (match_operand:SWIM 3 "general_operand" "")))]
15808 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15810 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15811 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15812 ;; So just document what we're doing explicitly.
15814 (define_expand "x86_mov<mode>cc_0_m1"
15816 [(set (match_operand:SWI48 0 "register_operand" "")
15817 (if_then_else:SWI48
15818 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15819 [(match_operand 1 "flags_reg_operand" "")
15823 (clobber (reg:CC FLAGS_REG))])]
15827 (define_insn "*x86_mov<mode>cc_0_m1"
15828 [(set (match_operand:SWI48 0 "register_operand" "=r")
15829 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15830 [(reg FLAGS_REG) (const_int 0)])
15833 (clobber (reg:CC FLAGS_REG))]
15835 "sbb{<imodesuffix>}\t%0, %0"
15836 ; Since we don't have the proper number of operands for an alu insn,
15837 ; fill in all the blanks.
15838 [(set_attr "type" "alu")
15839 (set_attr "use_carry" "1")
15840 (set_attr "pent_pair" "pu")
15841 (set_attr "memory" "none")
15842 (set_attr "imm_disp" "false")
15843 (set_attr "mode" "<MODE>")
15844 (set_attr "length_immediate" "0")])
15846 (define_insn "*x86_mov<mode>cc_0_m1_se"
15847 [(set (match_operand:SWI48 0 "register_operand" "=r")
15848 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15849 [(reg FLAGS_REG) (const_int 0)])
15852 (clobber (reg:CC FLAGS_REG))]
15854 "sbb{<imodesuffix>}\t%0, %0"
15855 [(set_attr "type" "alu")
15856 (set_attr "use_carry" "1")
15857 (set_attr "pent_pair" "pu")
15858 (set_attr "memory" "none")
15859 (set_attr "imm_disp" "false")
15860 (set_attr "mode" "<MODE>")
15861 (set_attr "length_immediate" "0")])
15863 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15864 [(set (match_operand:SWI48 0 "register_operand" "=r")
15865 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15866 [(reg FLAGS_REG) (const_int 0)])))]
15868 "sbb{<imodesuffix>}\t%0, %0"
15869 [(set_attr "type" "alu")
15870 (set_attr "use_carry" "1")
15871 (set_attr "pent_pair" "pu")
15872 (set_attr "memory" "none")
15873 (set_attr "imm_disp" "false")
15874 (set_attr "mode" "<MODE>")
15875 (set_attr "length_immediate" "0")])
15877 (define_insn "*mov<mode>cc_noc"
15878 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15879 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15880 [(reg FLAGS_REG) (const_int 0)])
15881 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15882 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15883 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15885 cmov%O2%C1\t{%2, %0|%0, %2}
15886 cmov%O2%c1\t{%3, %0|%0, %3}"
15887 [(set_attr "type" "icmov")
15888 (set_attr "mode" "<MODE>")])
15890 (define_insn_and_split "*movqicc_noc"
15891 [(set (match_operand:QI 0 "register_operand" "=r,r")
15892 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15893 [(match_operand 4 "flags_reg_operand" "")
15895 (match_operand:QI 2 "register_operand" "r,0")
15896 (match_operand:QI 3 "register_operand" "0,r")))]
15897 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15899 "&& reload_completed"
15900 [(set (match_dup 0)
15901 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15904 "operands[0] = gen_lowpart (SImode, operands[0]);
15905 operands[2] = gen_lowpart (SImode, operands[2]);
15906 operands[3] = gen_lowpart (SImode, operands[3]);"
15907 [(set_attr "type" "icmov")
15908 (set_attr "mode" "SI")])
15910 (define_expand "mov<mode>cc"
15911 [(set (match_operand:X87MODEF 0 "register_operand" "")
15912 (if_then_else:X87MODEF
15913 (match_operand 1 "ix86_fp_comparison_operator" "")
15914 (match_operand:X87MODEF 2 "register_operand" "")
15915 (match_operand:X87MODEF 3 "register_operand" "")))]
15916 "(TARGET_80387 && TARGET_CMOVE)
15917 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15918 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15920 (define_insn "*movsfcc_1_387"
15921 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15922 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15923 [(reg FLAGS_REG) (const_int 0)])
15924 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15925 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15926 "TARGET_80387 && TARGET_CMOVE
15927 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15929 fcmov%F1\t{%2, %0|%0, %2}
15930 fcmov%f1\t{%3, %0|%0, %3}
15931 cmov%O2%C1\t{%2, %0|%0, %2}
15932 cmov%O2%c1\t{%3, %0|%0, %3}"
15933 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15934 (set_attr "mode" "SF,SF,SI,SI")])
15936 (define_insn "*movdfcc_1"
15937 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15938 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15939 [(reg FLAGS_REG) (const_int 0)])
15940 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15941 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15942 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15943 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15945 fcmov%F1\t{%2, %0|%0, %2}
15946 fcmov%f1\t{%3, %0|%0, %3}
15949 [(set_attr "type" "fcmov,fcmov,multi,multi")
15950 (set_attr "mode" "DF")])
15952 (define_insn "*movdfcc_1_rex64"
15953 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15954 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15955 [(reg FLAGS_REG) (const_int 0)])
15956 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15957 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15958 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15959 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15961 fcmov%F1\t{%2, %0|%0, %2}
15962 fcmov%f1\t{%3, %0|%0, %3}
15963 cmov%O2%C1\t{%2, %0|%0, %2}
15964 cmov%O2%c1\t{%3, %0|%0, %3}"
15965 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15966 (set_attr "mode" "DF")])
15969 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15970 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15971 [(match_operand 4 "flags_reg_operand" "")
15973 (match_operand:DF 2 "nonimmediate_operand" "")
15974 (match_operand:DF 3 "nonimmediate_operand" "")))]
15975 "!TARGET_64BIT && reload_completed"
15976 [(set (match_dup 2)
15977 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15981 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15985 split_di (&operands[2], 2, &operands[5], &operands[7]);
15986 split_di (&operands[0], 1, &operands[2], &operands[3]);
15989 (define_insn "*movxfcc_1"
15990 [(set (match_operand:XF 0 "register_operand" "=f,f")
15991 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15992 [(reg FLAGS_REG) (const_int 0)])
15993 (match_operand:XF 2 "register_operand" "f,0")
15994 (match_operand:XF 3 "register_operand" "0,f")))]
15995 "TARGET_80387 && TARGET_CMOVE"
15997 fcmov%F1\t{%2, %0|%0, %2}
15998 fcmov%f1\t{%3, %0|%0, %3}"
15999 [(set_attr "type" "fcmov")
16000 (set_attr "mode" "XF")])
16002 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16003 ;; the scalar versions to have only XMM registers as operands.
16005 ;; XOP conditional move
16006 (define_insn "*xop_pcmov_<mode>"
16007 [(set (match_operand:MODEF 0 "register_operand" "=x")
16008 (if_then_else:MODEF
16009 (match_operand:MODEF 1 "register_operand" "x")
16010 (match_operand:MODEF 2 "register_operand" "x")
16011 (match_operand:MODEF 3 "register_operand" "x")))]
16013 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16014 [(set_attr "type" "sse4arg")])
16016 ;; These versions of the min/max patterns are intentionally ignorant of
16017 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16018 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16019 ;; are undefined in this condition, we're certain this is correct.
16021 (define_insn "*avx_<code><mode>3"
16022 [(set (match_operand:MODEF 0 "register_operand" "=x")
16024 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16025 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16026 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16027 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16028 [(set_attr "type" "sseadd")
16029 (set_attr "prefix" "vex")
16030 (set_attr "mode" "<MODE>")])
16032 (define_insn "<code><mode>3"
16033 [(set (match_operand:MODEF 0 "register_operand" "=x")
16035 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16036 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16037 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16038 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16039 [(set_attr "type" "sseadd")
16040 (set_attr "mode" "<MODE>")])
16042 ;; These versions of the min/max patterns implement exactly the operations
16043 ;; min = (op1 < op2 ? op1 : op2)
16044 ;; max = (!(op1 < op2) ? op1 : op2)
16045 ;; Their operands are not commutative, and thus they may be used in the
16046 ;; presence of -0.0 and NaN.
16048 (define_insn "*avx_ieee_smin<mode>3"
16049 [(set (match_operand:MODEF 0 "register_operand" "=x")
16051 [(match_operand:MODEF 1 "register_operand" "x")
16052 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16054 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16055 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16056 [(set_attr "type" "sseadd")
16057 (set_attr "prefix" "vex")
16058 (set_attr "mode" "<MODE>")])
16060 (define_insn "*ieee_smin<mode>3"
16061 [(set (match_operand:MODEF 0 "register_operand" "=x")
16063 [(match_operand:MODEF 1 "register_operand" "0")
16064 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16066 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16067 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16068 [(set_attr "type" "sseadd")
16069 (set_attr "mode" "<MODE>")])
16071 (define_insn "*avx_ieee_smax<mode>3"
16072 [(set (match_operand:MODEF 0 "register_operand" "=x")
16074 [(match_operand:MODEF 1 "register_operand" "0")
16075 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16077 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16078 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16079 [(set_attr "type" "sseadd")
16080 (set_attr "prefix" "vex")
16081 (set_attr "mode" "<MODE>")])
16083 (define_insn "*ieee_smax<mode>3"
16084 [(set (match_operand:MODEF 0 "register_operand" "=x")
16086 [(match_operand:MODEF 1 "register_operand" "0")
16087 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16089 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16090 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16091 [(set_attr "type" "sseadd")
16092 (set_attr "mode" "<MODE>")])
16094 ;; Make two stack loads independent:
16096 ;; fld %st(0) -> fld bb
16097 ;; fmul bb fmul %st(1), %st
16099 ;; Actually we only match the last two instructions for simplicity.
16101 [(set (match_operand 0 "fp_register_operand" "")
16102 (match_operand 1 "fp_register_operand" ""))
16104 (match_operator 2 "binary_fp_operator"
16106 (match_operand 3 "memory_operand" "")]))]
16107 "REGNO (operands[0]) != REGNO (operands[1])"
16108 [(set (match_dup 0) (match_dup 3))
16109 (set (match_dup 0) (match_dup 4))]
16111 ;; The % modifier is not operational anymore in peephole2's, so we have to
16112 ;; swap the operands manually in the case of addition and multiplication.
16113 "if (COMMUTATIVE_ARITH_P (operands[2]))
16114 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16115 GET_MODE (operands[2]),
16116 operands[0], operands[1]);
16118 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16119 GET_MODE (operands[2]),
16120 operands[1], operands[0]);")
16122 ;; Conditional addition patterns
16123 (define_expand "add<mode>cc"
16124 [(match_operand:SWI 0 "register_operand" "")
16125 (match_operand 1 "ordered_comparison_operator" "")
16126 (match_operand:SWI 2 "register_operand" "")
16127 (match_operand:SWI 3 "const_int_operand" "")]
16129 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16131 ;; Misc patterns (?)
16133 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16134 ;; Otherwise there will be nothing to keep
16136 ;; [(set (reg ebp) (reg esp))]
16137 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16138 ;; (clobber (eflags)]
16139 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16141 ;; in proper program order.
16143 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16144 [(set (match_operand:P 0 "register_operand" "=r,r")
16145 (plus:P (match_operand:P 1 "register_operand" "0,r")
16146 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16147 (clobber (reg:CC FLAGS_REG))
16148 (clobber (mem:BLK (scratch)))]
16151 switch (get_attr_type (insn))
16154 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16157 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16158 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16159 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16161 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16164 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16165 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16168 [(set (attr "type")
16169 (cond [(and (eq_attr "alternative" "0")
16170 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16171 (const_string "alu")
16172 (match_operand:<MODE> 2 "const0_operand" "")
16173 (const_string "imov")
16175 (const_string "lea")))
16176 (set (attr "length_immediate")
16177 (cond [(eq_attr "type" "imov")
16179 (and (eq_attr "type" "alu")
16180 (match_operand 2 "const128_operand" ""))
16183 (const_string "*")))
16184 (set_attr "mode" "<MODE>")])
16186 (define_insn "pro_epilogue_adjust_stack_di_2"
16187 [(set (match_operand:DI 0 "register_operand" "=r,r")
16188 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16189 (match_operand:DI 3 "immediate_operand" "i,i")))
16190 (use (match_operand:DI 2 "register_operand" "r,l"))
16191 (clobber (reg:CC FLAGS_REG))
16192 (clobber (mem:BLK (scratch)))]
16195 switch (get_attr_type (insn))
16198 return "add{q}\t{%2, %0|%0, %2}";
16201 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16202 return "lea{q}\t{%a2, %0|%0, %a2}";
16205 gcc_unreachable ();
16208 [(set_attr "type" "alu,lea")
16209 (set_attr "mode" "DI")])
16211 (define_insn "allocate_stack_worker_32"
16212 [(set (match_operand:SI 0 "register_operand" "=a")
16213 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16214 UNSPECV_STACK_PROBE))
16215 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16216 (clobber (reg:CC FLAGS_REG))]
16217 "!TARGET_64BIT && ix86_target_stack_probe ()"
16219 [(set_attr "type" "multi")
16220 (set_attr "length" "5")])
16222 (define_insn "allocate_stack_worker_64"
16223 [(set (match_operand:DI 0 "register_operand" "=a")
16224 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16225 UNSPECV_STACK_PROBE))
16226 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16227 (clobber (reg:DI R10_REG))
16228 (clobber (reg:DI R11_REG))
16229 (clobber (reg:CC FLAGS_REG))]
16230 "TARGET_64BIT && ix86_target_stack_probe ()"
16232 [(set_attr "type" "multi")
16233 (set_attr "length" "5")])
16235 (define_expand "allocate_stack"
16236 [(match_operand 0 "register_operand" "")
16237 (match_operand 1 "general_operand" "")]
16238 "ix86_target_stack_probe ()"
16242 #ifndef CHECK_STACK_LIMIT
16243 #define CHECK_STACK_LIMIT 0
16246 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16247 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16249 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16250 stack_pointer_rtx, 0, OPTAB_DIRECT);
16251 if (x != stack_pointer_rtx)
16252 emit_move_insn (stack_pointer_rtx, x);
16256 rtx (*gen_allocate_stack_worker) (rtx, rtx);
16259 gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16261 gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16263 x = copy_to_mode_reg (Pmode, operands[1]);
16264 emit_insn (gen_allocate_stack_worker (x, x));
16267 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16271 ;; Use IOR for stack probes, this is shorter.
16272 (define_expand "probe_stack"
16273 [(match_operand 0 "memory_operand" "")]
16276 rtx (*gen_ior3) (rtx, rtx, rtx);
16278 gen_ior3 = (GET_MODE (operands[0]) == DImode
16279 ? gen_iordi3 : gen_iorsi3);
16281 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16285 (define_insn "adjust_stack_and_probe<mode>"
16286 [(set (match_operand:P 0 "register_operand" "=r")
16287 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16288 UNSPECV_PROBE_STACK_RANGE))
16289 (set (reg:P SP_REG)
16290 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16291 (clobber (reg:CC FLAGS_REG))
16292 (clobber (mem:BLK (scratch)))]
16294 "* return output_adjust_stack_and_probe (operands[0]);"
16295 [(set_attr "type" "multi")])
16297 (define_insn "probe_stack_range<mode>"
16298 [(set (match_operand:P 0 "register_operand" "=r")
16299 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16300 (match_operand:P 2 "const_int_operand" "n")]
16301 UNSPECV_PROBE_STACK_RANGE))
16302 (clobber (reg:CC FLAGS_REG))]
16304 "* return output_probe_stack_range (operands[0], operands[2]);"
16305 [(set_attr "type" "multi")])
16307 (define_expand "builtin_setjmp_receiver"
16308 [(label_ref (match_operand 0 "" ""))]
16309 "!TARGET_64BIT && flag_pic"
16315 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16316 rtx label_rtx = gen_label_rtx ();
16317 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16318 xops[0] = xops[1] = picreg;
16319 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16320 ix86_expand_binary_operator (MINUS, SImode, xops);
16324 emit_insn (gen_set_got (pic_offset_table_rtx));
16328 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16331 [(set (match_operand 0 "register_operand" "")
16332 (match_operator 3 "promotable_binary_operator"
16333 [(match_operand 1 "register_operand" "")
16334 (match_operand 2 "aligned_operand" "")]))
16335 (clobber (reg:CC FLAGS_REG))]
16336 "! TARGET_PARTIAL_REG_STALL && reload_completed
16337 && ((GET_MODE (operands[0]) == HImode
16338 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16339 /* ??? next two lines just !satisfies_constraint_K (...) */
16340 || !CONST_INT_P (operands[2])
16341 || satisfies_constraint_K (operands[2])))
16342 || (GET_MODE (operands[0]) == QImode
16343 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16344 [(parallel [(set (match_dup 0)
16345 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16346 (clobber (reg:CC FLAGS_REG))])]
16347 "operands[0] = gen_lowpart (SImode, operands[0]);
16348 operands[1] = gen_lowpart (SImode, operands[1]);
16349 if (GET_CODE (operands[3]) != ASHIFT)
16350 operands[2] = gen_lowpart (SImode, operands[2]);
16351 PUT_MODE (operands[3], SImode);")
16353 ; Promote the QImode tests, as i386 has encoding of the AND
16354 ; instruction with 32-bit sign-extended immediate and thus the
16355 ; instruction size is unchanged, except in the %eax case for
16356 ; which it is increased by one byte, hence the ! optimize_size.
16358 [(set (match_operand 0 "flags_reg_operand" "")
16359 (match_operator 2 "compare_operator"
16360 [(and (match_operand 3 "aligned_operand" "")
16361 (match_operand 4 "const_int_operand" ""))
16363 (set (match_operand 1 "register_operand" "")
16364 (and (match_dup 3) (match_dup 4)))]
16365 "! TARGET_PARTIAL_REG_STALL && reload_completed
16366 && optimize_insn_for_speed_p ()
16367 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16368 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16369 /* Ensure that the operand will remain sign-extended immediate. */
16370 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16371 [(parallel [(set (match_dup 0)
16372 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16375 (and:SI (match_dup 3) (match_dup 4)))])]
16378 = gen_int_mode (INTVAL (operands[4])
16379 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16380 operands[1] = gen_lowpart (SImode, operands[1]);
16381 operands[3] = gen_lowpart (SImode, operands[3]);
16384 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16385 ; the TEST instruction with 32-bit sign-extended immediate and thus
16386 ; the instruction size would at least double, which is not what we
16387 ; want even with ! optimize_size.
16389 [(set (match_operand 0 "flags_reg_operand" "")
16390 (match_operator 1 "compare_operator"
16391 [(and (match_operand:HI 2 "aligned_operand" "")
16392 (match_operand:HI 3 "const_int_operand" ""))
16394 "! TARGET_PARTIAL_REG_STALL && reload_completed
16395 && ! TARGET_FAST_PREFIX
16396 && optimize_insn_for_speed_p ()
16397 /* Ensure that the operand will remain sign-extended immediate. */
16398 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16399 [(set (match_dup 0)
16400 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16404 = gen_int_mode (INTVAL (operands[3])
16405 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16406 operands[2] = gen_lowpart (SImode, operands[2]);
16410 [(set (match_operand 0 "register_operand" "")
16411 (neg (match_operand 1 "register_operand" "")))
16412 (clobber (reg:CC FLAGS_REG))]
16413 "! TARGET_PARTIAL_REG_STALL && reload_completed
16414 && (GET_MODE (operands[0]) == HImode
16415 || (GET_MODE (operands[0]) == QImode
16416 && (TARGET_PROMOTE_QImode
16417 || optimize_insn_for_size_p ())))"
16418 [(parallel [(set (match_dup 0)
16419 (neg:SI (match_dup 1)))
16420 (clobber (reg:CC FLAGS_REG))])]
16421 "operands[0] = gen_lowpart (SImode, operands[0]);
16422 operands[1] = gen_lowpart (SImode, operands[1]);")
16425 [(set (match_operand 0 "register_operand" "")
16426 (not (match_operand 1 "register_operand" "")))]
16427 "! TARGET_PARTIAL_REG_STALL && reload_completed
16428 && (GET_MODE (operands[0]) == HImode
16429 || (GET_MODE (operands[0]) == QImode
16430 && (TARGET_PROMOTE_QImode
16431 || optimize_insn_for_size_p ())))"
16432 [(set (match_dup 0)
16433 (not:SI (match_dup 1)))]
16434 "operands[0] = gen_lowpart (SImode, operands[0]);
16435 operands[1] = gen_lowpart (SImode, operands[1]);")
16438 [(set (match_operand 0 "register_operand" "")
16439 (if_then_else (match_operator 1 "ordered_comparison_operator"
16440 [(reg FLAGS_REG) (const_int 0)])
16441 (match_operand 2 "register_operand" "")
16442 (match_operand 3 "register_operand" "")))]
16443 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16444 && (GET_MODE (operands[0]) == HImode
16445 || (GET_MODE (operands[0]) == QImode
16446 && (TARGET_PROMOTE_QImode
16447 || optimize_insn_for_size_p ())))"
16448 [(set (match_dup 0)
16449 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16450 "operands[0] = gen_lowpart (SImode, operands[0]);
16451 operands[2] = gen_lowpart (SImode, operands[2]);
16452 operands[3] = gen_lowpart (SImode, operands[3]);")
16454 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16455 ;; transform a complex memory operation into two memory to register operations.
16457 ;; Don't push memory operands
16459 [(set (match_operand:SWI 0 "push_operand" "")
16460 (match_operand:SWI 1 "memory_operand" ""))
16461 (match_scratch:SWI 2 "<r>")]
16462 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16463 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16464 [(set (match_dup 2) (match_dup 1))
16465 (set (match_dup 0) (match_dup 2))])
16467 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16470 [(set (match_operand:SF 0 "push_operand" "")
16471 (match_operand:SF 1 "memory_operand" ""))
16472 (match_scratch:SF 2 "r")]
16473 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16474 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16475 [(set (match_dup 2) (match_dup 1))
16476 (set (match_dup 0) (match_dup 2))])
16478 ;; Don't move an immediate directly to memory when the instruction
16481 [(match_scratch:SWI124 1 "<r>")
16482 (set (match_operand:SWI124 0 "memory_operand" "")
16484 "optimize_insn_for_speed_p ()
16485 && !TARGET_USE_MOV0
16486 && TARGET_SPLIT_LONG_MOVES
16487 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16488 && peep2_regno_dead_p (0, FLAGS_REG)"
16489 [(parallel [(set (match_dup 2) (const_int 0))
16490 (clobber (reg:CC FLAGS_REG))])
16491 (set (match_dup 0) (match_dup 1))]
16492 "operands[2] = gen_lowpart (SImode, operands[1]);")
16495 [(match_scratch:SWI124 2 "<r>")
16496 (set (match_operand:SWI124 0 "memory_operand" "")
16497 (match_operand:SWI124 1 "immediate_operand" ""))]
16498 "optimize_insn_for_speed_p ()
16499 && TARGET_SPLIT_LONG_MOVES
16500 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16501 [(set (match_dup 2) (match_dup 1))
16502 (set (match_dup 0) (match_dup 2))])
16504 ;; Don't compare memory with zero, load and use a test instead.
16506 [(set (match_operand 0 "flags_reg_operand" "")
16507 (match_operator 1 "compare_operator"
16508 [(match_operand:SI 2 "memory_operand" "")
16510 (match_scratch:SI 3 "r")]
16511 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16512 [(set (match_dup 3) (match_dup 2))
16513 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16515 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16516 ;; Don't split NOTs with a displacement operand, because resulting XOR
16517 ;; will not be pairable anyway.
16519 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16520 ;; represented using a modRM byte. The XOR replacement is long decoded,
16521 ;; so this split helps here as well.
16523 ;; Note: Can't do this as a regular split because we can't get proper
16524 ;; lifetime information then.
16527 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16528 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16529 "optimize_insn_for_speed_p ()
16530 && ((TARGET_NOT_UNPAIRABLE
16531 && (!MEM_P (operands[0])
16532 || !memory_displacement_operand (operands[0], <MODE>mode)))
16533 || (TARGET_NOT_VECTORMODE
16534 && long_memory_operand (operands[0], <MODE>mode)))
16535 && peep2_regno_dead_p (0, FLAGS_REG)"
16536 [(parallel [(set (match_dup 0)
16537 (xor:SWI124 (match_dup 1) (const_int -1)))
16538 (clobber (reg:CC FLAGS_REG))])])
16540 ;; Non pairable "test imm, reg" instructions can be translated to
16541 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16542 ;; byte opcode instead of two, have a short form for byte operands),
16543 ;; so do it for other CPUs as well. Given that the value was dead,
16544 ;; this should not create any new dependencies. Pass on the sub-word
16545 ;; versions if we're concerned about partial register stalls.
16548 [(set (match_operand 0 "flags_reg_operand" "")
16549 (match_operator 1 "compare_operator"
16550 [(and:SI (match_operand:SI 2 "register_operand" "")
16551 (match_operand:SI 3 "immediate_operand" ""))
16553 "ix86_match_ccmode (insn, CCNOmode)
16554 && (true_regnum (operands[2]) != AX_REG
16555 || satisfies_constraint_K (operands[3]))
16556 && peep2_reg_dead_p (1, operands[2])"
16558 [(set (match_dup 0)
16559 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16562 (and:SI (match_dup 2) (match_dup 3)))])])
16564 ;; We don't need to handle HImode case, because it will be promoted to SImode
16565 ;; on ! TARGET_PARTIAL_REG_STALL
16568 [(set (match_operand 0 "flags_reg_operand" "")
16569 (match_operator 1 "compare_operator"
16570 [(and:QI (match_operand:QI 2 "register_operand" "")
16571 (match_operand:QI 3 "immediate_operand" ""))
16573 "! TARGET_PARTIAL_REG_STALL
16574 && ix86_match_ccmode (insn, CCNOmode)
16575 && true_regnum (operands[2]) != AX_REG
16576 && peep2_reg_dead_p (1, operands[2])"
16578 [(set (match_dup 0)
16579 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16582 (and:QI (match_dup 2) (match_dup 3)))])])
16585 [(set (match_operand 0 "flags_reg_operand" "")
16586 (match_operator 1 "compare_operator"
16589 (match_operand 2 "ext_register_operand" "")
16592 (match_operand 3 "const_int_operand" ""))
16594 "! TARGET_PARTIAL_REG_STALL
16595 && ix86_match_ccmode (insn, CCNOmode)
16596 && true_regnum (operands[2]) != AX_REG
16597 && peep2_reg_dead_p (1, operands[2])"
16598 [(parallel [(set (match_dup 0)
16607 (set (zero_extract:SI (match_dup 2)
16615 (match_dup 3)))])])
16617 ;; Don't do logical operations with memory inputs.
16619 [(match_scratch:SI 2 "r")
16620 (parallel [(set (match_operand:SI 0 "register_operand" "")
16621 (match_operator:SI 3 "arith_or_logical_operator"
16623 (match_operand:SI 1 "memory_operand" "")]))
16624 (clobber (reg:CC FLAGS_REG))])]
16625 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16626 [(set (match_dup 2) (match_dup 1))
16627 (parallel [(set (match_dup 0)
16628 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16629 (clobber (reg:CC FLAGS_REG))])])
16632 [(match_scratch:SI 2 "r")
16633 (parallel [(set (match_operand:SI 0 "register_operand" "")
16634 (match_operator:SI 3 "arith_or_logical_operator"
16635 [(match_operand:SI 1 "memory_operand" "")
16637 (clobber (reg:CC FLAGS_REG))])]
16638 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16639 [(set (match_dup 2) (match_dup 1))
16640 (parallel [(set (match_dup 0)
16641 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16642 (clobber (reg:CC FLAGS_REG))])])
16644 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16645 ;; refers to the destination of the load!
16648 [(set (match_operand:SI 0 "register_operand" "")
16649 (match_operand:SI 1 "register_operand" ""))
16650 (parallel [(set (match_dup 0)
16651 (match_operator:SI 3 "commutative_operator"
16653 (match_operand:SI 2 "memory_operand" "")]))
16654 (clobber (reg:CC FLAGS_REG))])]
16655 "REGNO (operands[0]) != REGNO (operands[1])
16656 && GENERAL_REGNO_P (REGNO (operands[0]))
16657 && GENERAL_REGNO_P (REGNO (operands[1]))"
16658 [(set (match_dup 0) (match_dup 4))
16659 (parallel [(set (match_dup 0)
16660 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16661 (clobber (reg:CC FLAGS_REG))])]
16662 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16665 [(set (match_operand 0 "register_operand" "")
16666 (match_operand 1 "register_operand" ""))
16668 (match_operator 3 "commutative_operator"
16670 (match_operand 2 "memory_operand" "")]))]
16671 "REGNO (operands[0]) != REGNO (operands[1])
16672 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16673 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16674 [(set (match_dup 0) (match_dup 2))
16676 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16678 ; Don't do logical operations with memory outputs
16680 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16681 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16682 ; the same decoder scheduling characteristics as the original.
16685 [(match_scratch:SI 2 "r")
16686 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16687 (match_operator:SI 3 "arith_or_logical_operator"
16689 (match_operand:SI 1 "nonmemory_operand" "")]))
16690 (clobber (reg:CC FLAGS_REG))])]
16691 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16692 /* Do not split stack checking probes. */
16693 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16694 [(set (match_dup 2) (match_dup 0))
16695 (parallel [(set (match_dup 2)
16696 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16697 (clobber (reg:CC FLAGS_REG))])
16698 (set (match_dup 0) (match_dup 2))])
16701 [(match_scratch:SI 2 "r")
16702 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16703 (match_operator:SI 3 "arith_or_logical_operator"
16704 [(match_operand:SI 1 "nonmemory_operand" "")
16706 (clobber (reg:CC FLAGS_REG))])]
16707 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16708 /* Do not split stack checking probes. */
16709 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16710 [(set (match_dup 2) (match_dup 0))
16711 (parallel [(set (match_dup 2)
16712 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16713 (clobber (reg:CC FLAGS_REG))])
16714 (set (match_dup 0) (match_dup 2))])
16716 ;; Attempt to always use XOR for zeroing registers.
16718 [(set (match_operand 0 "register_operand" "")
16719 (match_operand 1 "const0_operand" ""))]
16720 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16721 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16722 && GENERAL_REG_P (operands[0])
16723 && peep2_regno_dead_p (0, FLAGS_REG)"
16724 [(parallel [(set (match_dup 0) (const_int 0))
16725 (clobber (reg:CC FLAGS_REG))])]
16726 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16729 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16731 "(GET_MODE (operands[0]) == QImode
16732 || GET_MODE (operands[0]) == HImode)
16733 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16734 && peep2_regno_dead_p (0, FLAGS_REG)"
16735 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16736 (clobber (reg:CC FLAGS_REG))])])
16738 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16740 [(set (match_operand:SWI248 0 "register_operand" "")
16742 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16743 && peep2_regno_dead_p (0, FLAGS_REG)"
16744 [(parallel [(set (match_dup 0) (const_int -1))
16745 (clobber (reg:CC FLAGS_REG))])]
16747 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16748 operands[0] = gen_lowpart (SImode, operands[0]);
16751 ;; Attempt to convert simple lea to add/shift.
16752 ;; These can be created by move expanders.
16755 [(set (match_operand:SWI48 0 "register_operand" "")
16756 (plus:SWI48 (match_dup 0)
16757 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16758 "peep2_regno_dead_p (0, FLAGS_REG)"
16759 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16760 (clobber (reg:CC FLAGS_REG))])])
16763 [(set (match_operand:SI 0 "register_operand" "")
16764 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16765 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16767 && peep2_regno_dead_p (0, FLAGS_REG)
16768 && REGNO (operands[0]) == REGNO (operands[1])"
16769 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16770 (clobber (reg:CC FLAGS_REG))])]
16771 "operands[2] = gen_lowpart (SImode, operands[2]);")
16774 [(set (match_operand:SWI48 0 "register_operand" "")
16775 (mult:SWI48 (match_dup 0)
16776 (match_operand:SWI48 1 "const_int_operand" "")))]
16777 "exact_log2 (INTVAL (operands[1])) >= 0
16778 && peep2_regno_dead_p (0, FLAGS_REG)"
16779 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16780 (clobber (reg:CC FLAGS_REG))])]
16781 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16784 [(set (match_operand:SI 0 "register_operand" "")
16785 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16786 (match_operand:DI 2 "const_int_operand" "")) 0))]
16788 && exact_log2 (INTVAL (operands[2])) >= 0
16789 && REGNO (operands[0]) == REGNO (operands[1])
16790 && peep2_regno_dead_p (0, FLAGS_REG)"
16791 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16792 (clobber (reg:CC FLAGS_REG))])]
16793 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16795 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16796 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16797 ;; On many CPUs it is also faster, since special hardware to avoid esp
16798 ;; dependencies is present.
16800 ;; While some of these conversions may be done using splitters, we use
16801 ;; peepholes in order to allow combine_stack_adjustments pass to see
16802 ;; nonobfuscated RTL.
16804 ;; Convert prologue esp subtractions to push.
16805 ;; We need register to push. In order to keep verify_flow_info happy we have
16807 ;; - use scratch and clobber it in order to avoid dependencies
16808 ;; - use already live register
16809 ;; We can't use the second way right now, since there is no reliable way how to
16810 ;; verify that given register is live. First choice will also most likely in
16811 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16812 ;; call clobbered registers are dead. We may want to use base pointer as an
16813 ;; alternative when no register is available later.
16816 [(match_scratch:P 1 "r")
16817 (parallel [(set (reg:P SP_REG)
16818 (plus:P (reg:P SP_REG)
16819 (match_operand:P 0 "const_int_operand" "")))
16820 (clobber (reg:CC FLAGS_REG))
16821 (clobber (mem:BLK (scratch)))])]
16822 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16823 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16824 [(clobber (match_dup 1))
16825 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16826 (clobber (mem:BLK (scratch)))])])
16829 [(match_scratch:P 1 "r")
16830 (parallel [(set (reg:P SP_REG)
16831 (plus:P (reg:P SP_REG)
16832 (match_operand:P 0 "const_int_operand" "")))
16833 (clobber (reg:CC FLAGS_REG))
16834 (clobber (mem:BLK (scratch)))])]
16835 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16836 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16837 [(clobber (match_dup 1))
16838 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16839 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16840 (clobber (mem:BLK (scratch)))])])
16842 ;; Convert esp subtractions to push.
16844 [(match_scratch:P 1 "r")
16845 (parallel [(set (reg:P SP_REG)
16846 (plus:P (reg:P SP_REG)
16847 (match_operand:P 0 "const_int_operand" "")))
16848 (clobber (reg:CC FLAGS_REG))])]
16849 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16850 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16851 [(clobber (match_dup 1))
16852 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16855 [(match_scratch:P 1 "r")
16856 (parallel [(set (reg:P SP_REG)
16857 (plus:P (reg:P SP_REG)
16858 (match_operand:P 0 "const_int_operand" "")))
16859 (clobber (reg:CC FLAGS_REG))])]
16860 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16861 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16862 [(clobber (match_dup 1))
16863 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16864 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16866 ;; Convert epilogue deallocator to pop.
16868 [(match_scratch:P 1 "r")
16869 (parallel [(set (reg:P SP_REG)
16870 (plus:P (reg:P SP_REG)
16871 (match_operand:P 0 "const_int_operand" "")))
16872 (clobber (reg:CC FLAGS_REG))
16873 (clobber (mem:BLK (scratch)))])]
16874 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16875 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16876 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16877 (clobber (mem:BLK (scratch)))])])
16879 ;; Two pops case is tricky, since pop causes dependency
16880 ;; on destination register. We use two registers if available.
16882 [(match_scratch:P 1 "r")
16883 (match_scratch:P 2 "r")
16884 (parallel [(set (reg:P SP_REG)
16885 (plus:P (reg:P SP_REG)
16886 (match_operand:P 0 "const_int_operand" "")))
16887 (clobber (reg:CC FLAGS_REG))
16888 (clobber (mem:BLK (scratch)))])]
16889 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16890 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16891 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16892 (clobber (mem:BLK (scratch)))])
16893 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16896 [(match_scratch:P 1 "r")
16897 (parallel [(set (reg:P SP_REG)
16898 (plus:P (reg:P SP_REG)
16899 (match_operand:P 0 "const_int_operand" "")))
16900 (clobber (reg:CC FLAGS_REG))
16901 (clobber (mem:BLK (scratch)))])]
16902 "optimize_insn_for_size_p ()
16903 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16904 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16905 (clobber (mem:BLK (scratch)))])
16906 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16908 ;; Convert esp additions to pop.
16910 [(match_scratch:P 1 "r")
16911 (parallel [(set (reg:P SP_REG)
16912 (plus:P (reg:P SP_REG)
16913 (match_operand:P 0 "const_int_operand" "")))
16914 (clobber (reg:CC FLAGS_REG))])]
16915 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16916 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16918 ;; Two pops case is tricky, since pop causes dependency
16919 ;; on destination register. We use two registers if available.
16921 [(match_scratch:P 1 "r")
16922 (match_scratch:P 2 "r")
16923 (parallel [(set (reg:P SP_REG)
16924 (plus:P (reg:P SP_REG)
16925 (match_operand:P 0 "const_int_operand" "")))
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16928 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16929 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16932 [(match_scratch:P 1 "r")
16933 (parallel [(set (reg:P SP_REG)
16934 (plus:P (reg:P SP_REG)
16935 (match_operand:P 0 "const_int_operand" "")))
16936 (clobber (reg:CC FLAGS_REG))])]
16937 "optimize_insn_for_size_p ()
16938 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16939 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16940 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16942 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16943 ;; required and register dies. Similarly for 128 to -128.
16945 [(set (match_operand 0 "flags_reg_operand" "")
16946 (match_operator 1 "compare_operator"
16947 [(match_operand 2 "register_operand" "")
16948 (match_operand 3 "const_int_operand" "")]))]
16949 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16950 && incdec_operand (operands[3], GET_MODE (operands[3])))
16951 || (!TARGET_FUSE_CMP_AND_BRANCH
16952 && INTVAL (operands[3]) == 128))
16953 && ix86_match_ccmode (insn, CCGCmode)
16954 && peep2_reg_dead_p (1, operands[2])"
16955 [(parallel [(set (match_dup 0)
16956 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16957 (clobber (match_dup 2))])])
16959 ;; Convert imul by three, five and nine into lea
16962 [(set (match_operand:SWI48 0 "register_operand" "")
16963 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16964 (match_operand:SWI48 2 "const_int_operand" "")))
16965 (clobber (reg:CC FLAGS_REG))])]
16966 "INTVAL (operands[2]) == 3
16967 || INTVAL (operands[2]) == 5
16968 || INTVAL (operands[2]) == 9"
16969 [(set (match_dup 0)
16970 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16972 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16976 [(set (match_operand:SWI48 0 "register_operand" "")
16977 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16978 (match_operand:SWI48 2 "const_int_operand" "")))
16979 (clobber (reg:CC FLAGS_REG))])]
16980 "optimize_insn_for_speed_p ()
16981 && (INTVAL (operands[2]) == 3
16982 || INTVAL (operands[2]) == 5
16983 || INTVAL (operands[2]) == 9)"
16984 [(set (match_dup 0) (match_dup 1))
16986 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16988 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16990 ;; imul $32bit_imm, mem, reg is vector decoded, while
16991 ;; imul $32bit_imm, reg, reg is direct decoded.
16993 [(match_scratch:SWI48 3 "r")
16994 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
16995 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
16996 (match_operand:SWI48 2 "immediate_operand" "")))
16997 (clobber (reg:CC FLAGS_REG))])]
16998 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16999 && !satisfies_constraint_K (operands[2])"
17000 [(set (match_dup 3) (match_dup 1))
17001 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17002 (clobber (reg:CC FLAGS_REG))])])
17005 [(match_scratch:SI 3 "r")
17006 (parallel [(set (match_operand:DI 0 "register_operand" "")
17008 (mult:SI (match_operand:SI 1 "memory_operand" "")
17009 (match_operand:SI 2 "immediate_operand" ""))))
17010 (clobber (reg:CC FLAGS_REG))])]
17012 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17013 && !satisfies_constraint_K (operands[2])"
17014 [(set (match_dup 3) (match_dup 1))
17015 (parallel [(set (match_dup 0)
17016 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17017 (clobber (reg:CC FLAGS_REG))])])
17019 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17020 ;; Convert it into imul reg, reg
17021 ;; It would be better to force assembler to encode instruction using long
17022 ;; immediate, but there is apparently no way to do so.
17024 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17026 (match_operand:SWI248 1 "nonimmediate_operand" "")
17027 (match_operand:SWI248 2 "const_int_operand" "")))
17028 (clobber (reg:CC FLAGS_REG))])
17029 (match_scratch:SWI248 3 "r")]
17030 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17031 && satisfies_constraint_K (operands[2])"
17032 [(set (match_dup 3) (match_dup 2))
17033 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17034 (clobber (reg:CC FLAGS_REG))])]
17036 if (!rtx_equal_p (operands[0], operands[1]))
17037 emit_move_insn (operands[0], operands[1]);
17040 ;; After splitting up read-modify operations, array accesses with memory
17041 ;; operands might end up in form:
17043 ;; movl 4(%esp), %edx
17045 ;; instead of pre-splitting:
17047 ;; addl 4(%esp), %eax
17049 ;; movl 4(%esp), %edx
17050 ;; leal (%edx,%eax,4), %eax
17053 [(match_scratch:P 5 "r")
17054 (parallel [(set (match_operand 0 "register_operand" "")
17055 (ashift (match_operand 1 "register_operand" "")
17056 (match_operand 2 "const_int_operand" "")))
17057 (clobber (reg:CC FLAGS_REG))])
17058 (parallel [(set (match_operand 3 "register_operand" "")
17059 (plus (match_dup 0)
17060 (match_operand 4 "x86_64_general_operand" "")))
17061 (clobber (reg:CC FLAGS_REG))])]
17062 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17063 /* Validate MODE for lea. */
17064 && ((!TARGET_PARTIAL_REG_STALL
17065 && (GET_MODE (operands[0]) == QImode
17066 || GET_MODE (operands[0]) == HImode))
17067 || GET_MODE (operands[0]) == SImode
17068 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17069 && (rtx_equal_p (operands[0], operands[3])
17070 || peep2_reg_dead_p (2, operands[0]))
17071 /* We reorder load and the shift. */
17072 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17073 [(set (match_dup 5) (match_dup 4))
17074 (set (match_dup 0) (match_dup 1))]
17076 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17077 int scale = 1 << INTVAL (operands[2]);
17078 rtx index = gen_lowpart (Pmode, operands[1]);
17079 rtx base = gen_lowpart (Pmode, operands[5]);
17080 rtx dest = gen_lowpart (mode, operands[3]);
17082 operands[1] = gen_rtx_PLUS (Pmode, base,
17083 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17084 operands[5] = base;
17087 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17088 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17090 operands[0] = dest;
17093 ;; Call-value patterns last so that the wildcard operand does not
17094 ;; disrupt insn-recog's switch tables.
17096 (define_insn "*call_value_pop_0"
17097 [(set (match_operand 0 "" "")
17098 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17099 (match_operand:SI 2 "" "")))
17100 (set (reg:SI SP_REG)
17101 (plus:SI (reg:SI SP_REG)
17102 (match_operand:SI 3 "immediate_operand" "")))]
17105 if (SIBLING_CALL_P (insn))
17108 return "call\t%P1";
17110 [(set_attr "type" "callv")])
17112 (define_insn "*call_value_pop_1"
17113 [(set (match_operand 0 "" "")
17114 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17115 (match_operand:SI 2 "" "")))
17116 (set (reg:SI SP_REG)
17117 (plus:SI (reg:SI SP_REG)
17118 (match_operand:SI 3 "immediate_operand" "i")))]
17119 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17121 if (constant_call_address_operand (operands[1], Pmode))
17122 return "call\t%P1";
17123 return "call\t%A1";
17125 [(set_attr "type" "callv")])
17127 (define_insn "*sibcall_value_pop_1"
17128 [(set (match_operand 0 "" "")
17129 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17130 (match_operand:SI 2 "" "")))
17131 (set (reg:SI SP_REG)
17132 (plus:SI (reg:SI SP_REG)
17133 (match_operand:SI 3 "immediate_operand" "i,i")))]
17134 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17138 [(set_attr "type" "callv")])
17140 (define_insn "*call_value_0"
17141 [(set (match_operand 0 "" "")
17142 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17143 (match_operand:SI 2 "" "")))]
17146 if (SIBLING_CALL_P (insn))
17149 return "call\t%P1";
17151 [(set_attr "type" "callv")])
17153 (define_insn "*call_value_0_rex64"
17154 [(set (match_operand 0 "" "")
17155 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17156 (match_operand:DI 2 "const_int_operand" "")))]
17159 if (SIBLING_CALL_P (insn))
17162 return "call\t%P1";
17164 [(set_attr "type" "callv")])
17166 (define_insn "*call_value_0_rex64_ms_sysv"
17167 [(set (match_operand 0 "" "")
17168 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17169 (match_operand:DI 2 "const_int_operand" "")))
17170 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17171 (clobber (reg:TI XMM6_REG))
17172 (clobber (reg:TI XMM7_REG))
17173 (clobber (reg:TI XMM8_REG))
17174 (clobber (reg:TI XMM9_REG))
17175 (clobber (reg:TI XMM10_REG))
17176 (clobber (reg:TI XMM11_REG))
17177 (clobber (reg:TI XMM12_REG))
17178 (clobber (reg:TI XMM13_REG))
17179 (clobber (reg:TI XMM14_REG))
17180 (clobber (reg:TI XMM15_REG))
17181 (clobber (reg:DI SI_REG))
17182 (clobber (reg:DI DI_REG))]
17183 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17185 if (SIBLING_CALL_P (insn))
17188 return "call\t%P1";
17190 [(set_attr "type" "callv")])
17192 (define_insn "*call_value_1"
17193 [(set (match_operand 0 "" "")
17194 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17195 (match_operand:SI 2 "" "")))]
17196 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17198 if (constant_call_address_operand (operands[1], Pmode))
17199 return "call\t%P1";
17200 return "call\t%A1";
17202 [(set_attr "type" "callv")])
17204 (define_insn "*sibcall_value_1"
17205 [(set (match_operand 0 "" "")
17206 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17207 (match_operand:SI 2 "" "")))]
17208 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17212 [(set_attr "type" "callv")])
17214 (define_insn "*call_value_1_rex64"
17215 [(set (match_operand 0 "" "")
17216 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17217 (match_operand:DI 2 "" "")))]
17218 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17219 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17221 if (constant_call_address_operand (operands[1], Pmode))
17222 return "call\t%P1";
17223 return "call\t%A1";
17225 [(set_attr "type" "callv")])
17227 (define_insn "*call_value_1_rex64_ms_sysv"
17228 [(set (match_operand 0 "" "")
17229 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17230 (match_operand:DI 2 "" "")))
17231 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17232 (clobber (reg:TI XMM6_REG))
17233 (clobber (reg:TI XMM7_REG))
17234 (clobber (reg:TI XMM8_REG))
17235 (clobber (reg:TI XMM9_REG))
17236 (clobber (reg:TI XMM10_REG))
17237 (clobber (reg:TI XMM11_REG))
17238 (clobber (reg:TI XMM12_REG))
17239 (clobber (reg:TI XMM13_REG))
17240 (clobber (reg:TI XMM14_REG))
17241 (clobber (reg:TI XMM15_REG))
17242 (clobber (reg:DI SI_REG))
17243 (clobber (reg:DI DI_REG))]
17244 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17246 if (constant_call_address_operand (operands[1], Pmode))
17247 return "call\t%P1";
17248 return "call\t%A1";
17250 [(set_attr "type" "callv")])
17252 (define_insn "*call_value_1_rex64_large"
17253 [(set (match_operand 0 "" "")
17254 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17255 (match_operand:DI 2 "" "")))]
17256 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17258 [(set_attr "type" "callv")])
17260 (define_insn "*sibcall_value_1_rex64"
17261 [(set (match_operand 0 "" "")
17262 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17263 (match_operand:DI 2 "" "")))]
17264 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17268 [(set_attr "type" "callv")])
17270 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17271 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17272 ;; caught for use by garbage collectors and the like. Using an insn that
17273 ;; maps to SIGILL makes it more likely the program will rightfully die.
17274 ;; Keeping with tradition, "6" is in honor of #UD.
17275 (define_insn "trap"
17276 [(trap_if (const_int 1) (const_int 6))]
17278 { return ASM_SHORT "0x0b0f"; }
17279 [(set_attr "length" "2")])
17281 (define_expand "prefetch"
17282 [(prefetch (match_operand 0 "address_operand" "")
17283 (match_operand:SI 1 "const_int_operand" "")
17284 (match_operand:SI 2 "const_int_operand" ""))]
17285 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17287 int rw = INTVAL (operands[1]);
17288 int locality = INTVAL (operands[2]);
17290 gcc_assert (rw == 0 || rw == 1);
17291 gcc_assert (locality >= 0 && locality <= 3);
17292 gcc_assert (GET_MODE (operands[0]) == Pmode
17293 || GET_MODE (operands[0]) == VOIDmode);
17295 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17296 supported by SSE counterpart or the SSE prefetch is not available
17297 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17299 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17300 operands[2] = GEN_INT (3);
17302 operands[1] = const0_rtx;
17305 (define_insn "*prefetch_sse_<mode>"
17306 [(prefetch (match_operand:P 0 "address_operand" "p")
17308 (match_operand:SI 1 "const_int_operand" ""))]
17309 "TARGET_PREFETCH_SSE"
17311 static const char * const patterns[4] = {
17312 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17315 int locality = INTVAL (operands[1]);
17316 gcc_assert (locality >= 0 && locality <= 3);
17318 return patterns[locality];
17320 [(set_attr "type" "sse")
17321 (set_attr "atom_sse_attr" "prefetch")
17322 (set (attr "length_address")
17323 (symbol_ref "memory_address_length (operands[0])"))
17324 (set_attr "memory" "none")])
17326 (define_insn "*prefetch_3dnow_<mode>"
17327 [(prefetch (match_operand:P 0 "address_operand" "p")
17328 (match_operand:SI 1 "const_int_operand" "n")
17332 if (INTVAL (operands[1]) == 0)
17333 return "prefetch\t%a0";
17335 return "prefetchw\t%a0";
17337 [(set_attr "type" "mmx")
17338 (set (attr "length_address")
17339 (symbol_ref "memory_address_length (operands[0])"))
17340 (set_attr "memory" "none")])
17342 (define_expand "stack_protect_set"
17343 [(match_operand 0 "memory_operand" "")
17344 (match_operand 1 "memory_operand" "")]
17347 #ifdef TARGET_THREAD_SSP_OFFSET
17349 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17350 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17352 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17353 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17356 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17358 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17363 (define_insn "stack_protect_set_si"
17364 [(set (match_operand:SI 0 "memory_operand" "=m")
17365 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17366 (set (match_scratch:SI 2 "=&r") (const_int 0))
17367 (clobber (reg:CC FLAGS_REG))]
17369 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17370 [(set_attr "type" "multi")])
17372 (define_insn "stack_protect_set_di"
17373 [(set (match_operand:DI 0 "memory_operand" "=m")
17374 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17375 (set (match_scratch:DI 2 "=&r") (const_int 0))
17376 (clobber (reg:CC FLAGS_REG))]
17378 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17379 [(set_attr "type" "multi")])
17381 (define_insn "stack_tls_protect_set_si"
17382 [(set (match_operand:SI 0 "memory_operand" "=m")
17383 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17384 UNSPEC_SP_TLS_SET))
17385 (set (match_scratch:SI 2 "=&r") (const_int 0))
17386 (clobber (reg:CC FLAGS_REG))]
17388 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17389 [(set_attr "type" "multi")])
17391 (define_insn "stack_tls_protect_set_di"
17392 [(set (match_operand:DI 0 "memory_operand" "=m")
17393 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17394 UNSPEC_SP_TLS_SET))
17395 (set (match_scratch:DI 2 "=&r") (const_int 0))
17396 (clobber (reg:CC FLAGS_REG))]
17399 /* The kernel uses a different segment register for performance reasons; a
17400 system call would not have to trash the userspace segment register,
17401 which would be expensive */
17402 if (ix86_cmodel != CM_KERNEL)
17403 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17405 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17407 [(set_attr "type" "multi")])
17409 (define_expand "stack_protect_test"
17410 [(match_operand 0 "memory_operand" "")
17411 (match_operand 1 "memory_operand" "")
17412 (match_operand 2 "" "")]
17415 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17417 #ifdef TARGET_THREAD_SSP_OFFSET
17419 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17420 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17422 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17423 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17426 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17428 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17431 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17432 flags, const0_rtx, operands[2]));
17436 (define_insn "stack_protect_test_si"
17437 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17438 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17439 (match_operand:SI 2 "memory_operand" "m")]
17441 (clobber (match_scratch:SI 3 "=&r"))]
17443 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17444 [(set_attr "type" "multi")])
17446 (define_insn "stack_protect_test_di"
17447 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17448 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17449 (match_operand:DI 2 "memory_operand" "m")]
17451 (clobber (match_scratch:DI 3 "=&r"))]
17453 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
17454 [(set_attr "type" "multi")])
17456 (define_insn "stack_tls_protect_test_si"
17457 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17458 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17459 (match_operand:SI 2 "const_int_operand" "i")]
17460 UNSPEC_SP_TLS_TEST))
17461 (clobber (match_scratch:SI 3 "=r"))]
17463 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
17464 [(set_attr "type" "multi")])
17466 (define_insn "stack_tls_protect_test_di"
17467 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17468 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17469 (match_operand:DI 2 "const_int_operand" "i")]
17470 UNSPEC_SP_TLS_TEST))
17471 (clobber (match_scratch:DI 3 "=r"))]
17474 /* The kernel uses a different segment register for performance reasons; a
17475 system call would not have to trash the userspace segment register,
17476 which would be expensive */
17477 if (ix86_cmodel != CM_KERNEL)
17478 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
17480 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
17482 [(set_attr "type" "multi")])
17484 (define_insn "sse4_2_crc32<mode>"
17485 [(set (match_operand:SI 0 "register_operand" "=r")
17487 [(match_operand:SI 1 "register_operand" "0")
17488 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17490 "TARGET_SSE4_2 || TARGET_CRC32"
17491 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17492 [(set_attr "type" "sselog1")
17493 (set_attr "prefix_rep" "1")
17494 (set_attr "prefix_extra" "1")
17495 (set (attr "prefix_data16")
17496 (if_then_else (match_operand:HI 2 "" "")
17498 (const_string "*")))
17499 (set (attr "prefix_rex")
17500 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17502 (const_string "*")))
17503 (set_attr "mode" "SI")])
17505 (define_insn "sse4_2_crc32di"
17506 [(set (match_operand:DI 0 "register_operand" "=r")
17508 [(match_operand:DI 1 "register_operand" "0")
17509 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17511 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17512 "crc32{q}\t{%2, %0|%0, %2}"
17513 [(set_attr "type" "sselog1")
17514 (set_attr "prefix_rep" "1")
17515 (set_attr "prefix_extra" "1")
17516 (set_attr "mode" "DI")])
17518 (define_expand "rdpmc"
17519 [(match_operand:DI 0 "register_operand" "")
17520 (match_operand:SI 1 "register_operand" "")]
17523 rtx reg = gen_reg_rtx (DImode);
17526 /* Force operand 1 into ECX. */
17527 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17528 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17529 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17534 rtvec vec = rtvec_alloc (2);
17535 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17536 rtx upper = gen_reg_rtx (DImode);
17537 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17538 gen_rtvec (1, const0_rtx),
17540 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17541 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17543 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17544 NULL, 1, OPTAB_DIRECT);
17545 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17549 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17550 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17554 (define_insn "*rdpmc"
17555 [(set (match_operand:DI 0 "register_operand" "=A")
17556 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17560 [(set_attr "type" "other")
17561 (set_attr "length" "2")])
17563 (define_insn "*rdpmc_rex64"
17564 [(set (match_operand:DI 0 "register_operand" "=a")
17565 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17567 (set (match_operand:DI 1 "register_operand" "=d")
17568 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17571 [(set_attr "type" "other")
17572 (set_attr "length" "2")])
17574 (define_expand "rdtsc"
17575 [(set (match_operand:DI 0 "register_operand" "")
17576 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17581 rtvec vec = rtvec_alloc (2);
17582 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17583 rtx upper = gen_reg_rtx (DImode);
17584 rtx lower = gen_reg_rtx (DImode);
17585 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17586 gen_rtvec (1, const0_rtx),
17588 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17589 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17591 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17592 NULL, 1, OPTAB_DIRECT);
17593 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17595 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17600 (define_insn "*rdtsc"
17601 [(set (match_operand:DI 0 "register_operand" "=A")
17602 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17605 [(set_attr "type" "other")
17606 (set_attr "length" "2")])
17608 (define_insn "*rdtsc_rex64"
17609 [(set (match_operand:DI 0 "register_operand" "=a")
17610 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17611 (set (match_operand:DI 1 "register_operand" "=d")
17612 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17615 [(set_attr "type" "other")
17616 (set_attr "length" "2")])
17618 (define_expand "rdtscp"
17619 [(match_operand:DI 0 "register_operand" "")
17620 (match_operand:SI 1 "memory_operand" "")]
17623 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17624 gen_rtvec (1, const0_rtx),
17626 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17627 gen_rtvec (1, const0_rtx),
17629 rtx reg = gen_reg_rtx (DImode);
17630 rtx tmp = gen_reg_rtx (SImode);
17634 rtvec vec = rtvec_alloc (3);
17635 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17636 rtx upper = gen_reg_rtx (DImode);
17637 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17638 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17639 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17641 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17642 NULL, 1, OPTAB_DIRECT);
17643 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17648 rtvec vec = rtvec_alloc (2);
17649 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17650 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17651 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17654 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17655 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17659 (define_insn "*rdtscp"
17660 [(set (match_operand:DI 0 "register_operand" "=A")
17661 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17662 (set (match_operand:SI 1 "register_operand" "=c")
17663 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17666 [(set_attr "type" "other")
17667 (set_attr "length" "3")])
17669 (define_insn "*rdtscp_rex64"
17670 [(set (match_operand:DI 0 "register_operand" "=a")
17671 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17672 (set (match_operand:DI 1 "register_operand" "=d")
17673 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17674 (set (match_operand:SI 2 "register_operand" "=c")
17675 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17678 [(set_attr "type" "other")
17679 (set_attr "length" "3")])
17681 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17683 ;; LWP instructions
17685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17687 (define_expand "lwp_llwpcb"
17688 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17689 UNSPECV_LLWP_INTRINSIC)]
17693 (define_insn "*lwp_llwpcb<mode>1"
17694 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17695 UNSPECV_LLWP_INTRINSIC)]
17698 [(set_attr "type" "lwp")
17699 (set_attr "mode" "<MODE>")
17700 (set_attr "length" "5")])
17702 (define_expand "lwp_slwpcb"
17703 [(set (match_operand 0 "register_operand" "=r")
17704 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17708 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17710 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17714 (define_insn "lwp_slwpcb<mode>"
17715 [(set (match_operand:P 0 "register_operand" "=r")
17716 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17719 [(set_attr "type" "lwp")
17720 (set_attr "mode" "<MODE>")
17721 (set_attr "length" "5")])
17723 (define_expand "lwp_lwpval<mode>3"
17724 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17725 (match_operand:SI 2 "nonimmediate_operand" "rm")
17726 (match_operand:SI 3 "const_int_operand" "i")]
17727 UNSPECV_LWPVAL_INTRINSIC)]
17729 "/* Avoid unused variable warning. */
17732 (define_insn "*lwp_lwpval<mode>3_1"
17733 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17734 (match_operand:SI 1 "nonimmediate_operand" "rm")
17735 (match_operand:SI 2 "const_int_operand" "i")]
17736 UNSPECV_LWPVAL_INTRINSIC)]
17738 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17739 [(set_attr "type" "lwp")
17740 (set_attr "mode" "<MODE>")
17741 (set (attr "length")
17742 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17744 (define_expand "lwp_lwpins<mode>3"
17745 [(set (reg:CCC FLAGS_REG)
17746 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17747 (match_operand:SI 2 "nonimmediate_operand" "rm")
17748 (match_operand:SI 3 "const_int_operand" "i")]
17749 UNSPECV_LWPINS_INTRINSIC))
17750 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17751 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17755 (define_insn "*lwp_lwpins<mode>3_1"
17756 [(set (reg:CCC FLAGS_REG)
17757 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17758 (match_operand:SI 1 "nonimmediate_operand" "rm")
17759 (match_operand:SI 2 "const_int_operand" "i")]
17760 UNSPECV_LWPINS_INTRINSIC))]
17762 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17763 [(set_attr "type" "lwp")
17764 (set_attr "mode" "<MODE>")
17765 (set (attr "length")
17766 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17768 (define_insn "rdfsbase<mode>"
17769 [(set (match_operand:SWI48 0 "register_operand" "=r")
17770 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17771 "TARGET_64BIT && TARGET_FSGSBASE"
17773 [(set_attr "type" "other")
17774 (set_attr "prefix_extra" "2")])
17776 (define_insn "rdgsbase<mode>"
17777 [(set (match_operand:SWI48 0 "register_operand" "=r")
17778 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17779 "TARGET_64BIT && TARGET_FSGSBASE"
17781 [(set_attr "type" "other")
17782 (set_attr "prefix_extra" "2")])
17784 (define_insn "wrfsbase<mode>"
17785 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17787 "TARGET_64BIT && TARGET_FSGSBASE"
17789 [(set_attr "type" "other")
17790 (set_attr "prefix_extra" "2")])
17792 (define_insn "wrgsbase<mode>"
17793 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17795 "TARGET_64BIT && TARGET_FSGSBASE"
17797 [(set_attr "type" "other")
17798 (set_attr "prefix_extra" "2")])
17800 (define_expand "rdrand<mode>"
17801 [(set (match_operand:SWI248 0 "register_operand" "=r")
17802 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17805 rtx retry_label, insn, ccc;
17807 retry_label = gen_label_rtx ();
17809 emit_label (retry_label);
17811 /* Generate rdrand. */
17812 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17814 /* Retry if the carry flag isn't valid. */
17815 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17816 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17817 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17818 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17819 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17820 JUMP_LABEL (insn) = retry_label;
17825 (define_insn "rdrand<mode>_1"
17826 [(set (match_operand:SWI248 0 "register_operand" "=r")
17827 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17830 [(set_attr "type" "other")
17831 (set_attr "prefix_extra" "1")])
17835 (include "sync.md")