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, 2011
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).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
112 ;; For SSE/MMX support:
130 UNSPEC_MS_TO_SYSV_CALL
132 ;; Generic math support
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
137 ;; x87 Floating point
153 UNSPEC_FRNDINT_MASK_PM
157 ;; x87 Double output FP
189 ;; For SSE4.1 support
199 ;; For SSE4.2 support
206 UNSPEC_XOP_UNSIGNED_CMP
217 UNSPEC_AESKEYGENASSIST
219 ;; For PCLMUL support
237 ;; For RDRAND support
241 (define_c_enum "unspecv" [
244 UNSPECV_PROBE_STACK_RANGE
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
272 UNSPECV_SPLIT_STACK_RETURN
275 ;; Constants to represent rounding modes in the ROUND instruction
284 ;; Constants to represent pcomtrue/pcomfalse variants
294 ;; Constants used in the XOP pperm instruction
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
308 ;; Registers by name.
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,btver1"
373 (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
391 ;; Main data type used by the insn
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 (eq_attr "unit" "i387,sse,mmx")
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
419 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
455 (eq_attr "mode" "HI")
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
507 (eq_attr "type" "sseiadd1,ssecvt1")
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
516 (const_string "orig")))
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
539 (eq_attr "unit" "i387")
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
580 (eq_attr "type" "fcmp")
582 (eq_attr "unit" "i387")
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
667 (const_string "none")))
669 ;; Indicates if an instruction has both an immediate and a displacement.
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
683 (const_string "false")))
685 ;; Indicates if an FP operation has an integer source.
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
690 ;; Defines rounding mode of an FP operation.
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
701 ;; Describe a user's asm statement.
702 (define_asm_attributes
703 [(set_attr "length" "128")
704 (set_attr "type" "multi")])
706 (define_code_iterator plusminus [plus minus])
708 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
710 ;; Base name for define_insn
711 (define_code_attr plusminus_insn
712 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
713 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
715 ;; Base name for insn mnemonic.
716 (define_code_attr plusminus_mnemonic
717 [(plus "add") (ss_plus "adds") (us_plus "addus")
718 (minus "sub") (ss_minus "subs") (us_minus "subus")])
719 (define_code_attr plusminus_carry_mnemonic
720 [(plus "adc") (minus "sbb")])
722 ;; Mark commutative operators as such in constraints.
723 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
724 (minus "") (ss_minus "") (us_minus "")])
726 ;; Mapping of signed max and min
727 (define_code_iterator smaxmin [smax smin])
729 ;; Mapping of unsigned max and min
730 (define_code_iterator umaxmin [umax umin])
732 ;; Base name for integer and FP insn mnemonic
733 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
734 (umax "maxu") (umin "minu")])
735 (define_code_attr maxmin_float [(smax "max") (smin "min")])
737 ;; Mapping of logic operators
738 (define_code_iterator any_logic [and ior xor])
739 (define_code_iterator any_or [ior xor])
741 ;; Base name for insn mnemonic.
742 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
744 ;; Mapping of shift-right operators
745 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
747 ;; Base name for define_insn
748 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
750 ;; Base name for insn mnemonic.
751 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
753 ;; Mapping of rotate operators
754 (define_code_iterator any_rotate [rotate rotatert])
756 ;; Base name for define_insn
757 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
759 ;; Base name for insn mnemonic.
760 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
762 ;; Mapping of abs neg operators
763 (define_code_iterator absneg [abs neg])
765 ;; Base name for x87 insn mnemonic.
766 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
768 ;; Used in signed and unsigned widening multiplications.
769 (define_code_iterator any_extend [sign_extend zero_extend])
771 ;; Various insn prefixes for signed and unsigned operations.
772 (define_code_attr u [(sign_extend "") (zero_extend "u")
773 (div "") (udiv "u")])
774 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
776 ;; Used in signed and unsigned divisions.
777 (define_code_iterator any_div [div udiv])
779 ;; Instruction prefix for signed and unsigned operations.
780 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
781 (div "i") (udiv "")])
783 ;; 64bit single word integer modes.
784 (define_mode_iterator SWI1248x [QI HI SI DI])
786 ;; 64bit single word integer modes without QImode and HImode.
787 (define_mode_iterator SWI48x [SI DI])
789 ;; Single word integer modes.
790 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
792 ;; Single word integer modes without SImode and DImode.
793 (define_mode_iterator SWI12 [QI HI])
795 ;; Single word integer modes without DImode.
796 (define_mode_iterator SWI124 [QI HI SI])
798 ;; Single word integer modes without QImode and DImode.
799 (define_mode_iterator SWI24 [HI SI])
801 ;; Single word integer modes without QImode.
802 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
804 ;; Single word integer modes without QImode and HImode.
805 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
807 ;; All math-dependant single and double word integer modes.
808 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
809 (HI "TARGET_HIMODE_MATH")
810 SI DI (TI "TARGET_64BIT")])
812 ;; Math-dependant single word integer modes.
813 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
814 (HI "TARGET_HIMODE_MATH")
815 SI (DI "TARGET_64BIT")])
817 ;; Math-dependant single word integer modes without DImode.
818 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
819 (HI "TARGET_HIMODE_MATH")
822 ;; Math-dependant single word integer modes without QImode.
823 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
824 SI (DI "TARGET_64BIT")])
826 ;; Double word integer modes.
827 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
828 (TI "TARGET_64BIT")])
830 ;; Double word integer modes as mode attribute.
831 (define_mode_attr DWI [(SI "DI") (DI "TI")])
832 (define_mode_attr dwi [(SI "di") (DI "ti")])
834 ;; Half mode for double word integer modes.
835 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
836 (DI "TARGET_64BIT")])
838 ;; Instruction suffix for integer modes.
839 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
841 ;; Pointer size prefix for integer modes (Intel asm dialect)
842 (define_mode_attr iptrsize [(QI "BYTE")
847 ;; Register class for integer modes.
848 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
850 ;; Immediate operand constraint for integer modes.
851 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
853 ;; General operand constraint for word modes.
854 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
856 ;; Immediate operand constraint for double integer modes.
857 (define_mode_attr di [(SI "iF") (DI "e")])
859 ;; Immediate operand constraint for shifts.
860 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
862 ;; General operand predicate for integer modes.
863 (define_mode_attr general_operand
864 [(QI "general_operand")
865 (HI "general_operand")
866 (SI "general_operand")
867 (DI "x86_64_general_operand")
868 (TI "x86_64_general_operand")])
870 ;; General sign/zero extend operand predicate for integer modes.
871 (define_mode_attr general_szext_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_szext_general_operand")])
877 ;; Immediate operand predicate for integer modes.
878 (define_mode_attr immediate_operand
879 [(QI "immediate_operand")
880 (HI "immediate_operand")
881 (SI "immediate_operand")
882 (DI "x86_64_immediate_operand")])
884 ;; Nonmemory operand predicate for integer modes.
885 (define_mode_attr nonmemory_operand
886 [(QI "nonmemory_operand")
887 (HI "nonmemory_operand")
888 (SI "nonmemory_operand")
889 (DI "x86_64_nonmemory_operand")])
891 ;; Operand predicate for shifts.
892 (define_mode_attr shift_operand
893 [(QI "nonimmediate_operand")
894 (HI "nonimmediate_operand")
895 (SI "nonimmediate_operand")
896 (DI "shiftdi_operand")
897 (TI "register_operand")])
899 ;; Operand predicate for shift argument.
900 (define_mode_attr shift_immediate_operand
901 [(QI "const_1_to_31_operand")
902 (HI "const_1_to_31_operand")
903 (SI "const_1_to_31_operand")
904 (DI "const_1_to_63_operand")])
906 ;; Input operand predicate for arithmetic left shifts.
907 (define_mode_attr ashl_input_operand
908 [(QI "nonimmediate_operand")
909 (HI "nonimmediate_operand")
910 (SI "nonimmediate_operand")
911 (DI "ashldi_input_operand")
912 (TI "reg_or_pm1_operand")])
914 ;; SSE and x87 SFmode and DFmode floating point modes
915 (define_mode_iterator MODEF [SF DF])
917 ;; All x87 floating point modes
918 (define_mode_iterator X87MODEF [SF DF XF])
920 ;; All integer modes handled by x87 fisttp operator.
921 (define_mode_iterator X87MODEI [HI SI DI])
923 ;; All integer modes handled by integer x87 operators.
924 (define_mode_iterator X87MODEI12 [HI SI])
926 ;; All integer modes handled by SSE cvtts?2si* operators.
927 (define_mode_iterator SSEMODEI24 [SI DI])
929 ;; SSE asm suffix for floating point modes
930 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
932 ;; SSE vector mode corresponding to a scalar mode
933 (define_mode_attr ssevecmode
934 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
936 ;; Instruction suffix for REX 64bit operators.
937 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
939 ;; This mode iterator allows :P to be used for patterns that operate on
940 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
941 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
943 ;; Scheduling descriptions
945 (include "pentium.md")
948 (include "athlon.md")
949 (include "bdver1.md")
955 ;; Operand and operator predicates and constraints
957 (include "predicates.md")
958 (include "constraints.md")
961 ;; Compare and branch/compare and store instructions.
963 (define_expand "cbranch<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
966 (match_operand:SDWIM 2 "<general_operand>" "")))
967 (set (pc) (if_then_else
968 (match_operator 0 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)])
970 (label_ref (match_operand 3 "" ""))
974 if (MEM_P (operands[1]) && MEM_P (operands[2]))
975 operands[1] = force_reg (<MODE>mode, operands[1]);
976 ix86_expand_branch (GET_CODE (operands[0]),
977 operands[1], operands[2], operands[3]);
981 (define_expand "cstore<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
984 (match_operand:SWIM 3 "<general_operand>" "")))
985 (set (match_operand:QI 0 "register_operand" "")
986 (match_operator 1 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)]))]
990 if (MEM_P (operands[2]) && MEM_P (operands[3]))
991 operands[2] = force_reg (<MODE>mode, operands[2]);
992 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
993 operands[2], operands[3]);
997 (define_expand "cmp<mode>_1"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1000 (match_operand:SWI48 1 "<general_operand>" "")))])
1002 (define_insn "*cmp<mode>_ccno_1"
1003 [(set (reg FLAGS_REG)
1004 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1005 (match_operand:SWI 1 "const0_operand" "")))]
1006 "ix86_match_ccmode (insn, CCNOmode)"
1008 test{<imodesuffix>}\t%0, %0
1009 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "test,icmp")
1011 (set_attr "length_immediate" "0,1")
1012 (set_attr "mode" "<MODE>")])
1014 (define_insn "*cmp<mode>_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1018 "ix86_match_ccmode (insn, CCmode)"
1019 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "<MODE>")])
1023 (define_insn "*cmp<mode>_minus_1"
1024 [(set (reg FLAGS_REG)
1026 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1027 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1029 "ix86_match_ccmode (insn, CCGOCmode)"
1030 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1031 [(set_attr "type" "icmp")
1032 (set_attr "mode" "<MODE>")])
1034 (define_insn "*cmpqi_ext_1"
1035 [(set (reg FLAGS_REG)
1037 (match_operand:QI 0 "general_operand" "Qm")
1040 (match_operand 1 "ext_register_operand" "Q")
1042 (const_int 8)) 0)))]
1043 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044 "cmp{b}\t{%h1, %0|%0, %h1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "mode" "QI")])
1048 (define_insn "*cmpqi_ext_1_rex64"
1049 [(set (reg FLAGS_REG)
1051 (match_operand:QI 0 "register_operand" "Q")
1054 (match_operand 1 "ext_register_operand" "Q")
1056 (const_int 8)) 0)))]
1057 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%h1, %0|%0, %h1}"
1059 [(set_attr "type" "icmp")
1060 (set_attr "mode" "QI")])
1062 (define_insn "*cmpqi_ext_2"
1063 [(set (reg FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "Q")
1070 (match_operand:QI 1 "const0_operand" "")))]
1071 "ix86_match_ccmode (insn, CCNOmode)"
1073 [(set_attr "type" "test")
1074 (set_attr "length_immediate" "0")
1075 (set_attr "mode" "QI")])
1077 (define_expand "cmpqi_ext_3"
1078 [(set (reg:CC FLAGS_REG)
1082 (match_operand 0 "ext_register_operand" "")
1085 (match_operand:QI 1 "immediate_operand" "")))])
1087 (define_insn "*cmpqi_ext_3_insn"
1088 [(set (reg FLAGS_REG)
1092 (match_operand 0 "ext_register_operand" "Q")
1095 (match_operand:QI 1 "general_operand" "Qmn")))]
1096 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%1, %h0|%h0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "modrm" "1")
1100 (set_attr "mode" "QI")])
1102 (define_insn "*cmpqi_ext_3_insn_rex64"
1103 [(set (reg FLAGS_REG)
1107 (match_operand 0 "ext_register_operand" "Q")
1110 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1111 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1112 "cmp{b}\t{%1, %h0|%h0, %1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "modrm" "1")
1115 (set_attr "mode" "QI")])
1117 (define_insn "*cmpqi_ext_4"
1118 [(set (reg FLAGS_REG)
1122 (match_operand 0 "ext_register_operand" "Q")
1127 (match_operand 1 "ext_register_operand" "Q")
1129 (const_int 8)) 0)))]
1130 "ix86_match_ccmode (insn, CCmode)"
1131 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "mode" "QI")])
1135 ;; These implement float point compares.
1136 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1137 ;; which would allow mix and match FP modes on the compares. Which is what
1138 ;; the old patterns did, but with many more of them.
1140 (define_expand "cbranchxf4"
1141 [(set (reg:CC FLAGS_REG)
1142 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1143 (match_operand:XF 2 "nonmemory_operand" "")))
1144 (set (pc) (if_then_else
1145 (match_operator 0 "ix86_fp_comparison_operator"
1148 (label_ref (match_operand 3 "" ""))
1152 ix86_expand_branch (GET_CODE (operands[0]),
1153 operands[1], operands[2], operands[3]);
1157 (define_expand "cstorexf4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1160 (match_operand:XF 3 "nonmemory_operand" "")))
1161 (set (match_operand:QI 0 "register_operand" "")
1162 (match_operator 1 "ix86_fp_comparison_operator"
1167 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1168 operands[2], operands[3]);
1172 (define_expand "cbranch<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1175 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ix86_fp_comparison_operator"
1180 (label_ref (match_operand 3 "" ""))
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1184 ix86_expand_branch (GET_CODE (operands[0]),
1185 operands[1], operands[2], operands[3]);
1189 (define_expand "cstore<mode>4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1192 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1193 (set (match_operand:QI 0 "register_operand" "")
1194 (match_operator 1 "ix86_fp_comparison_operator"
1197 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200 operands[2], operands[3]);
1204 (define_expand "cbranchcc4"
1205 [(set (pc) (if_then_else
1206 (match_operator 0 "comparison_operator"
1207 [(match_operand 1 "flags_reg_operand" "")
1208 (match_operand 2 "const0_operand" "")])
1209 (label_ref (match_operand 3 "" ""))
1213 ix86_expand_branch (GET_CODE (operands[0]),
1214 operands[1], operands[2], operands[3]);
1218 (define_expand "cstorecc4"
1219 [(set (match_operand:QI 0 "register_operand" "")
1220 (match_operator 1 "comparison_operator"
1221 [(match_operand 2 "flags_reg_operand" "")
1222 (match_operand 3 "const0_operand" "")]))]
1225 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1226 operands[2], operands[3]);
1231 ;; FP compares, step 1:
1232 ;; Set the FP condition codes.
1234 ;; CCFPmode compare with exceptions
1235 ;; CCFPUmode compare with no exceptions
1237 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1238 ;; used to manage the reg stack popping would not be preserved.
1240 (define_insn "*cmpfp_0"
1241 [(set (match_operand:HI 0 "register_operand" "=a")
1244 (match_operand 1 "register_operand" "f")
1245 (match_operand 2 "const0_operand" ""))]
1247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "* return output_fp_compare (insn, operands, 0, 0);"
1250 [(set_attr "type" "multi")
1251 (set_attr "unit" "i387")
1253 (cond [(match_operand:SF 1 "" "")
1255 (match_operand:DF 1 "" "")
1258 (const_string "XF")))])
1260 (define_insn_and_split "*cmpfp_0_cc"
1261 [(set (reg:CCFP FLAGS_REG)
1263 (match_operand 1 "register_operand" "f")
1264 (match_operand 2 "const0_operand" "")))
1265 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1267 && TARGET_SAHF && !TARGET_CMOVE
1268 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1270 "&& reload_completed"
1273 [(compare:CCFP (match_dup 1)(match_dup 2))]
1275 (set (reg:CC FLAGS_REG)
1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1281 (cond [(match_operand:SF 1 "" "")
1283 (match_operand:DF 1 "" "")
1286 (const_string "XF")))])
1288 (define_insn "*cmpfp_xf"
1289 [(set (match_operand:HI 0 "register_operand" "=a")
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f"))]
1296 "* return output_fp_compare (insn, operands, 0, 0);"
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1301 (define_insn_and_split "*cmpfp_xf_cc"
1302 [(set (reg:CCFP FLAGS_REG)
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f")))
1306 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1308 && TARGET_SAHF && !TARGET_CMOVE"
1310 "&& reload_completed"
1313 [(compare:CCFP (match_dup 1)(match_dup 2))]
1315 (set (reg:CC FLAGS_REG)
1316 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1318 [(set_attr "type" "multi")
1319 (set_attr "unit" "i387")
1320 (set_attr "mode" "XF")])
1322 (define_insn "*cmpfp_<mode>"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1330 "* return output_fp_compare (insn, operands, 0, 0);"
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn_and_split "*cmpfp_<mode>_cc"
1336 [(set (reg:CCFP FLAGS_REG)
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342 && TARGET_SAHF && !TARGET_CMOVE"
1344 "&& reload_completed"
1347 [(compare:CCFP (match_dup 1)(match_dup 2))]
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "mode" "<MODE>")])
1356 (define_insn "*cmpfp_u"
1357 [(set (match_operand:HI 0 "register_operand" "=a")
1360 (match_operand 1 "register_operand" "f")
1361 (match_operand 2 "register_operand" "f"))]
1363 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "* return output_fp_compare (insn, operands, 0, 1);"
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1369 (cond [(match_operand:SF 1 "" "")
1371 (match_operand:DF 1 "" "")
1374 (const_string "XF")))])
1376 (define_insn_and_split "*cmpfp_u_cc"
1377 [(set (reg:CCFPU FLAGS_REG)
1379 (match_operand 1 "register_operand" "f")
1380 (match_operand 2 "register_operand" "f")))
1381 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1382 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1383 && TARGET_SAHF && !TARGET_CMOVE
1384 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1386 "&& reload_completed"
1389 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1391 (set (reg:CC FLAGS_REG)
1392 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1397 (cond [(match_operand:SF 1 "" "")
1399 (match_operand:DF 1 "" "")
1402 (const_string "XF")))])
1404 (define_insn "*cmpfp_<mode>"
1405 [(set (match_operand:HI 0 "register_operand" "=a")
1408 (match_operand 1 "register_operand" "f")
1409 (match_operator 3 "float_operator"
1410 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415 "* return output_fp_compare (insn, operands, 0, 0);"
1416 [(set_attr "type" "multi")
1417 (set_attr "unit" "i387")
1418 (set_attr "fp_int_src" "true")
1419 (set_attr "mode" "<MODE>")])
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422 [(set (reg:CCFP FLAGS_REG)
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1427 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && TARGET_SAHF && !TARGET_CMOVE
1430 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1433 "&& reload_completed"
1438 (match_op_dup 3 [(match_dup 2)]))]
1440 (set (reg:CC FLAGS_REG)
1441 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1443 [(set_attr "type" "multi")
1444 (set_attr "unit" "i387")
1445 (set_attr "fp_int_src" "true")
1446 (set_attr "mode" "<MODE>")])
1448 ;; FP compares, step 2
1449 ;; Move the fpsw to ax.
1451 (define_insn "x86_fnstsw_1"
1452 [(set (match_operand:HI 0 "register_operand" "=a")
1453 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1456 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1457 (set_attr "mode" "SI")
1458 (set_attr "unit" "i387")])
1460 ;; FP compares, step 3
1461 ;; Get ax into flags, general case.
1463 (define_insn "x86_sahf_1"
1464 [(set (reg:CC FLAGS_REG)
1465 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1469 #ifndef HAVE_AS_IX86_SAHF
1471 return ASM_BYTE "0x9e";
1476 [(set_attr "length" "1")
1477 (set_attr "athlon_decode" "vector")
1478 (set_attr "amdfam10_decode" "direct")
1479 (set_attr "bdver1_decode" "direct")
1480 (set_attr "mode" "SI")])
1482 ;; Pentium Pro can do steps 1 through 3 in one go.
1483 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1484 (define_insn "*cmpfp_i_mixed"
1485 [(set (reg:CCFP FLAGS_REG)
1486 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1487 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1488 "TARGET_MIX_SSE_I387
1489 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1490 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1491 "* return output_fp_compare (insn, operands, 1, 0);"
1492 [(set_attr "type" "fcmp,ssecomi")
1493 (set_attr "prefix" "orig,maybe_vex")
1495 (if_then_else (match_operand:SF 1 "" "")
1497 (const_string "DF")))
1498 (set (attr "prefix_rep")
1499 (if_then_else (eq_attr "type" "ssecomi")
1501 (const_string "*")))
1502 (set (attr "prefix_data16")
1503 (cond [(eq_attr "type" "fcmp")
1505 (eq_attr "mode" "DF")
1508 (const_string "0")))
1509 (set_attr "athlon_decode" "vector")
1510 (set_attr "amdfam10_decode" "direct")
1511 (set_attr "bdver1_decode" "double")])
1513 (define_insn "*cmpfp_i_sse"
1514 [(set (reg:CCFP FLAGS_REG)
1515 (compare:CCFP (match_operand 0 "register_operand" "x")
1516 (match_operand 1 "nonimmediate_operand" "xm")))]
1518 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520 "* return output_fp_compare (insn, operands, 1, 0);"
1521 [(set_attr "type" "ssecomi")
1522 (set_attr "prefix" "maybe_vex")
1524 (if_then_else (match_operand:SF 1 "" "")
1526 (const_string "DF")))
1527 (set_attr "prefix_rep" "0")
1528 (set (attr "prefix_data16")
1529 (if_then_else (eq_attr "mode" "DF")
1531 (const_string "0")))
1532 (set_attr "athlon_decode" "vector")
1533 (set_attr "amdfam10_decode" "direct")
1534 (set_attr "bdver1_decode" "double")])
1536 (define_insn "*cmpfp_i_i387"
1537 [(set (reg:CCFP FLAGS_REG)
1538 (compare:CCFP (match_operand 0 "register_operand" "f")
1539 (match_operand 1 "register_operand" "f")))]
1540 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1542 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1543 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544 "* return output_fp_compare (insn, operands, 1, 0);"
1545 [(set_attr "type" "fcmp")
1547 (cond [(match_operand:SF 1 "" "")
1549 (match_operand:DF 1 "" "")
1552 (const_string "XF")))
1553 (set_attr "athlon_decode" "vector")
1554 (set_attr "amdfam10_decode" "direct")
1555 (set_attr "bdver1_decode" "double")])
1557 (define_insn "*cmpfp_iu_mixed"
1558 [(set (reg:CCFPU FLAGS_REG)
1559 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1560 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1561 "TARGET_MIX_SSE_I387
1562 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1563 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1564 "* return output_fp_compare (insn, operands, 1, 1);"
1565 [(set_attr "type" "fcmp,ssecomi")
1566 (set_attr "prefix" "orig,maybe_vex")
1568 (if_then_else (match_operand:SF 1 "" "")
1570 (const_string "DF")))
1571 (set (attr "prefix_rep")
1572 (if_then_else (eq_attr "type" "ssecomi")
1574 (const_string "*")))
1575 (set (attr "prefix_data16")
1576 (cond [(eq_attr "type" "fcmp")
1578 (eq_attr "mode" "DF")
1581 (const_string "0")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")
1584 (set_attr "bdver1_decode" "double")])
1586 (define_insn "*cmpfp_iu_sse"
1587 [(set (reg:CCFPU FLAGS_REG)
1588 (compare:CCFPU (match_operand 0 "register_operand" "x")
1589 (match_operand 1 "nonimmediate_operand" "xm")))]
1591 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1592 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1593 "* return output_fp_compare (insn, operands, 1, 1);"
1594 [(set_attr "type" "ssecomi")
1595 (set_attr "prefix" "maybe_vex")
1597 (if_then_else (match_operand:SF 1 "" "")
1599 (const_string "DF")))
1600 (set_attr "prefix_rep" "0")
1601 (set (attr "prefix_data16")
1602 (if_then_else (eq_attr "mode" "DF")
1604 (const_string "0")))
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")
1607 (set_attr "bdver1_decode" "double")])
1609 (define_insn "*cmpfp_iu_387"
1610 [(set (reg:CCFPU FLAGS_REG)
1611 (compare:CCFPU (match_operand 0 "register_operand" "f")
1612 (match_operand 1 "register_operand" "f")))]
1613 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1615 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1616 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1617 "* return output_fp_compare (insn, operands, 1, 1);"
1618 [(set_attr "type" "fcmp")
1620 (cond [(match_operand:SF 1 "" "")
1622 (match_operand:DF 1 "" "")
1625 (const_string "XF")))
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "direct")
1628 (set_attr "bdver1_decode" "direct")])
1630 ;; Push/pop instructions.
1632 (define_insn "*push<mode>2"
1633 [(set (match_operand:DWI 0 "push_operand" "=<")
1634 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1639 [(set (match_operand:TI 0 "push_operand" "")
1640 (match_operand:TI 1 "general_operand" ""))]
1641 "TARGET_64BIT && reload_completed
1642 && !SSE_REG_P (operands[1])"
1644 "ix86_split_long_move (operands); DONE;")
1646 (define_insn "*pushdi2_rex64"
1647 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1648 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1653 [(set_attr "type" "push,multi")
1654 (set_attr "mode" "DI")])
1656 ;; Convert impossible pushes of immediate to existing instructions.
1657 ;; First try to get scratch register and go through it. In case this
1658 ;; fails, push sign extended lower part first and then overwrite
1659 ;; upper part by 32bit move.
1661 [(match_scratch:DI 2 "r")
1662 (set (match_operand:DI 0 "push_operand" "")
1663 (match_operand:DI 1 "immediate_operand" ""))]
1664 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1665 && !x86_64_immediate_operand (operands[1], DImode)"
1666 [(set (match_dup 2) (match_dup 1))
1667 (set (match_dup 0) (match_dup 2))])
1669 ;; We need to define this as both peepholer and splitter for case
1670 ;; peephole2 pass is not run.
1671 ;; "&& 1" is needed to keep it from matching the previous pattern.
1673 [(set (match_operand:DI 0 "push_operand" "")
1674 (match_operand:DI 1 "immediate_operand" ""))]
1675 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1676 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1677 [(set (match_dup 0) (match_dup 1))
1678 (set (match_dup 2) (match_dup 3))]
1680 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1682 operands[1] = gen_lowpart (DImode, operands[2]);
1683 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1688 [(set (match_operand:DI 0 "push_operand" "")
1689 (match_operand:DI 1 "immediate_operand" ""))]
1690 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1691 ? epilogue_completed : reload_completed)
1692 && !symbolic_operand (operands[1], DImode)
1693 && !x86_64_immediate_operand (operands[1], DImode)"
1694 [(set (match_dup 0) (match_dup 1))
1695 (set (match_dup 2) (match_dup 3))]
1697 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1699 operands[1] = gen_lowpart (DImode, operands[2]);
1700 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1705 [(set (match_operand:DI 0 "push_operand" "")
1706 (match_operand:DI 1 "general_operand" ""))]
1707 "!TARGET_64BIT && reload_completed
1708 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1710 "ix86_split_long_move (operands); DONE;")
1712 (define_insn "*pushsi2"
1713 [(set (match_operand:SI 0 "push_operand" "=<")
1714 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "SI")])
1720 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1721 ;; "push a byte/word". But actually we use pushl, which has the effect
1722 ;; of rounding the amount pushed up to a word.
1724 ;; For TARGET_64BIT we always round up to 8 bytes.
1725 (define_insn "*push<mode>2_rex64"
1726 [(set (match_operand:SWI124 0 "push_operand" "=X")
1727 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "DI")])
1733 (define_insn "*push<mode>2"
1734 [(set (match_operand:SWI12 0 "push_operand" "=X")
1735 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "SI")])
1741 (define_insn "*push<mode>2_prologue"
1742 [(set (match_operand:P 0 "push_operand" "=<")
1743 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1744 (clobber (mem:BLK (scratch)))]
1746 "push{<imodesuffix>}\t%1"
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "<MODE>")])
1750 (define_insn "*pop<mode>1"
1751 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1752 (match_operand:P 1 "pop_operand" ">"))]
1754 "pop{<imodesuffix>}\t%0"
1755 [(set_attr "type" "pop")
1756 (set_attr "mode" "<MODE>")])
1758 (define_insn "*pop<mode>1_epilogue"
1759 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1760 (match_operand:P 1 "pop_operand" ">"))
1761 (clobber (mem:BLK (scratch)))]
1763 "pop{<imodesuffix>}\t%0"
1764 [(set_attr "type" "pop")
1765 (set_attr "mode" "<MODE>")])
1767 ;; Move instructions.
1769 (define_expand "movoi"
1770 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1771 (match_operand:OI 1 "general_operand" ""))]
1773 "ix86_expand_move (OImode, operands); DONE;")
1775 (define_expand "movti"
1776 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1777 (match_operand:TI 1 "nonimmediate_operand" ""))]
1778 "TARGET_64BIT || TARGET_SSE"
1781 ix86_expand_move (TImode, operands);
1782 else if (push_operand (operands[0], TImode))
1783 ix86_expand_push (TImode, operands[1]);
1785 ix86_expand_vector_move (TImode, operands);
1789 ;; This expands to what emit_move_complex would generate if we didn't
1790 ;; have a movti pattern. Having this avoids problems with reload on
1791 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1792 ;; to have around all the time.
1793 (define_expand "movcdi"
1794 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1795 (match_operand:CDI 1 "general_operand" ""))]
1798 if (push_operand (operands[0], CDImode))
1799 emit_move_complex_push (CDImode, operands[0], operands[1]);
1801 emit_move_complex_parts (operands[0], operands[1]);
1805 (define_expand "mov<mode>"
1806 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1807 (match_operand:SWI1248x 1 "general_operand" ""))]
1809 "ix86_expand_move (<MODE>mode, operands); DONE;")
1811 (define_insn "*mov<mode>_xor"
1812 [(set (match_operand:SWI48 0 "register_operand" "=r")
1813 (match_operand:SWI48 1 "const0_operand" ""))
1814 (clobber (reg:CC FLAGS_REG))]
1817 [(set_attr "type" "alu1")
1818 (set_attr "mode" "SI")
1819 (set_attr "length_immediate" "0")])
1821 (define_insn "*mov<mode>_or"
1822 [(set (match_operand:SWI48 0 "register_operand" "=r")
1823 (match_operand:SWI48 1 "const_int_operand" ""))
1824 (clobber (reg:CC FLAGS_REG))]
1826 && operands[1] == constm1_rtx"
1827 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1828 [(set_attr "type" "alu1")
1829 (set_attr "mode" "<MODE>")
1830 (set_attr "length_immediate" "1")])
1832 (define_insn "*movoi_internal_avx"
1833 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1834 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1835 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1837 switch (which_alternative)
1840 return "vxorps\t%0, %0, %0";
1843 if (misaligned_operand (operands[0], OImode)
1844 || misaligned_operand (operands[1], OImode))
1845 return "vmovdqu\t{%1, %0|%0, %1}";
1847 return "vmovdqa\t{%1, %0|%0, %1}";
1852 [(set_attr "type" "sselog1,ssemov,ssemov")
1853 (set_attr "prefix" "vex")
1854 (set_attr "mode" "OI")])
1856 (define_insn "*movti_internal_rex64"
1857 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1858 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1859 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861 switch (which_alternative)
1867 if (get_attr_mode (insn) == MODE_V4SF)
1868 return "%vxorps\t%0, %d0";
1870 return "%vpxor\t%0, %d0";
1873 /* TDmode values are passed as TImode on the stack. Moving them
1874 to stack may result in unaligned memory access. */
1875 if (misaligned_operand (operands[0], TImode)
1876 || misaligned_operand (operands[1], TImode))
1878 if (get_attr_mode (insn) == MODE_V4SF)
1879 return "%vmovups\t{%1, %0|%0, %1}";
1881 return "%vmovdqu\t{%1, %0|%0, %1}";
1885 if (get_attr_mode (insn) == MODE_V4SF)
1886 return "%vmovaps\t{%1, %0|%0, %1}";
1888 return "%vmovdqa\t{%1, %0|%0, %1}";
1894 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1895 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1897 (cond [(eq_attr "alternative" "2,3")
1899 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1901 (const_string "V4SF")
1902 (const_string "TI"))
1903 (eq_attr "alternative" "4")
1905 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1907 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909 (const_string "V4SF")
1910 (const_string "TI"))]
1911 (const_string "DI")))])
1914 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1915 (match_operand:TI 1 "general_operand" ""))]
1917 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1919 "ix86_split_long_move (operands); DONE;")
1921 (define_insn "*movti_internal_sse"
1922 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1923 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1924 "TARGET_SSE && !TARGET_64BIT
1925 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1927 switch (which_alternative)
1930 if (get_attr_mode (insn) == MODE_V4SF)
1931 return "%vxorps\t%0, %d0";
1933 return "%vpxor\t%0, %d0";
1936 /* TDmode values are passed as TImode on the stack. Moving them
1937 to stack may result in unaligned memory access. */
1938 if (misaligned_operand (operands[0], TImode)
1939 || misaligned_operand (operands[1], TImode))
1941 if (get_attr_mode (insn) == MODE_V4SF)
1942 return "%vmovups\t{%1, %0|%0, %1}";
1944 return "%vmovdqu\t{%1, %0|%0, %1}";
1948 if (get_attr_mode (insn) == MODE_V4SF)
1949 return "%vmovaps\t{%1, %0|%0, %1}";
1951 return "%vmovdqa\t{%1, %0|%0, %1}";
1957 [(set_attr "type" "sselog1,ssemov,ssemov")
1958 (set_attr "prefix" "maybe_vex")
1960 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1961 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1963 (const_string "V4SF")
1964 (and (eq_attr "alternative" "2")
1965 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1967 (const_string "V4SF")]
1968 (const_string "TI")))])
1970 (define_insn "*movdi_internal_rex64"
1971 [(set (match_operand:DI 0 "nonimmediate_operand"
1972 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1973 (match_operand:DI 1 "general_operand"
1974 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1975 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1977 switch (get_attr_type (insn))
1980 if (SSE_REG_P (operands[0]))
1981 return "movq2dq\t{%1, %0|%0, %1}";
1983 return "movdq2q\t{%1, %0|%0, %1}";
1988 if (get_attr_mode (insn) == MODE_TI)
1989 return "vmovdqa\t{%1, %0|%0, %1}";
1991 return "vmovq\t{%1, %0|%0, %1}";
1994 if (get_attr_mode (insn) == MODE_TI)
1995 return "movdqa\t{%1, %0|%0, %1}";
1999 /* Moves from and into integer register is done using movd
2000 opcode with REX prefix. */
2001 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2002 return "movd\t{%1, %0|%0, %1}";
2003 return "movq\t{%1, %0|%0, %1}";
2006 return "%vpxor\t%0, %d0";
2009 return "pxor\t%0, %0";
2015 return "lea{q}\t{%a1, %0|%0, %a1}";
2018 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019 if (get_attr_mode (insn) == MODE_SI)
2020 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021 else if (which_alternative == 2)
2022 return "movabs{q}\t{%1, %0|%0, %1}";
2024 return "mov{q}\t{%1, %0|%0, %1}";
2028 (cond [(eq_attr "alternative" "5")
2029 (const_string "mmx")
2030 (eq_attr "alternative" "6,7,8,9,10")
2031 (const_string "mmxmov")
2032 (eq_attr "alternative" "11")
2033 (const_string "sselog1")
2034 (eq_attr "alternative" "12,13,14,15,16")
2035 (const_string "ssemov")
2036 (eq_attr "alternative" "17,18")
2037 (const_string "ssecvt")
2038 (eq_attr "alternative" "4")
2039 (const_string "multi")
2040 (match_operand:DI 1 "pic_32bit_operand" "")
2041 (const_string "lea")
2043 (const_string "imov")))
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2048 (const_string "*")))
2049 (set (attr "length_immediate")
2051 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2053 (const_string "*")))
2054 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2055 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2056 (set (attr "prefix")
2057 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2058 (const_string "maybe_vex")
2059 (const_string "orig")))
2060 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2062 ;; Convert impossible stores of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it. In case this
2064 ;; fails, move by 32bit parts.
2066 [(match_scratch:DI 2 "r")
2067 (set (match_operand:DI 0 "memory_operand" "")
2068 (match_operand:DI 1 "immediate_operand" ""))]
2069 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070 && !x86_64_immediate_operand (operands[1], DImode)"
2071 [(set (match_dup 2) (match_dup 1))
2072 (set (match_dup 0) (match_dup 2))])
2074 ;; We need to define this as both peepholer and splitter for case
2075 ;; peephole2 pass is not run.
2076 ;; "&& 1" is needed to keep it from matching the previous pattern.
2078 [(set (match_operand:DI 0 "memory_operand" "")
2079 (match_operand:DI 1 "immediate_operand" ""))]
2080 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2082 [(set (match_dup 2) (match_dup 3))
2083 (set (match_dup 4) (match_dup 5))]
2084 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2087 [(set (match_operand:DI 0 "memory_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2090 ? epilogue_completed : reload_completed)
2091 && !symbolic_operand (operands[1], DImode)
2092 && !x86_64_immediate_operand (operands[1], DImode)"
2093 [(set (match_dup 2) (match_dup 3))
2094 (set (match_dup 4) (match_dup 5))]
2095 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2097 (define_insn "*movdi_internal"
2098 [(set (match_operand:DI 0 "nonimmediate_operand"
2099 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2100 (match_operand:DI 1 "general_operand"
2101 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2102 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2107 movq\t{%1, %0|%0, %1}
2108 movq\t{%1, %0|%0, %1}
2110 %vmovq\t{%1, %0|%0, %1}
2111 %vmovdqa\t{%1, %0|%0, %1}
2112 %vmovq\t{%1, %0|%0, %1}
2114 movlps\t{%1, %0|%0, %1}
2115 movaps\t{%1, %0|%0, %1}
2116 movlps\t{%1, %0|%0, %1}"
2117 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2118 (set (attr "prefix")
2119 (if_then_else (eq_attr "alternative" "5,6,7,8")
2120 (const_string "vex")
2121 (const_string "orig")))
2122 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2125 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2126 (match_operand:DI 1 "general_operand" ""))]
2127 "!TARGET_64BIT && reload_completed
2128 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2129 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2131 "ix86_split_long_move (operands); DONE;")
2133 (define_insn "*movsi_internal"
2134 [(set (match_operand:SI 0 "nonimmediate_operand"
2135 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2136 (match_operand:SI 1 "general_operand"
2137 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2138 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2140 switch (get_attr_type (insn))
2143 if (get_attr_mode (insn) == MODE_TI)
2144 return "%vpxor\t%0, %d0";
2145 return "%vxorps\t%0, %d0";
2148 switch (get_attr_mode (insn))
2151 return "%vmovdqa\t{%1, %0|%0, %1}";
2153 return "%vmovaps\t{%1, %0|%0, %1}";
2155 return "%vmovd\t{%1, %0|%0, %1}";
2157 return "%vmovss\t{%1, %0|%0, %1}";
2163 return "pxor\t%0, %0";
2166 if (get_attr_mode (insn) == MODE_DI)
2167 return "movq\t{%1, %0|%0, %1}";
2168 return "movd\t{%1, %0|%0, %1}";
2171 return "lea{l}\t{%a1, %0|%0, %a1}";
2174 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2175 return "mov{l}\t{%1, %0|%0, %1}";
2179 (cond [(eq_attr "alternative" "2")
2180 (const_string "mmx")
2181 (eq_attr "alternative" "3,4,5")
2182 (const_string "mmxmov")
2183 (eq_attr "alternative" "6")
2184 (const_string "sselog1")
2185 (eq_attr "alternative" "7,8,9,10,11")
2186 (const_string "ssemov")
2187 (match_operand:DI 1 "pic_32bit_operand" "")
2188 (const_string "lea")
2190 (const_string "imov")))
2191 (set (attr "prefix")
2192 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2193 (const_string "orig")
2194 (const_string "maybe_vex")))
2195 (set (attr "prefix_data16")
2196 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2198 (const_string "*")))
2200 (cond [(eq_attr "alternative" "2,3")
2202 (eq_attr "alternative" "6,7")
2204 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2205 (const_string "V4SF")
2206 (const_string "TI"))
2207 (and (eq_attr "alternative" "8,9,10,11")
2208 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2211 (const_string "SI")))])
2213 (define_insn "*movhi_internal"
2214 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2215 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2216 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2218 switch (get_attr_type (insn))
2221 /* movzwl is faster than movw on p2 due to partial word stalls,
2222 though not as fast as an aligned movl. */
2223 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2225 if (get_attr_mode (insn) == MODE_SI)
2226 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2228 return "mov{w}\t{%1, %0|%0, %1}";
2232 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2234 (const_string "imov")
2235 (and (eq_attr "alternative" "0")
2236 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2238 (eq (symbol_ref "TARGET_HIMODE_MATH")
2240 (const_string "imov")
2241 (and (eq_attr "alternative" "1,2")
2242 (match_operand:HI 1 "aligned_operand" ""))
2243 (const_string "imov")
2244 (and (ne (symbol_ref "TARGET_MOVX")
2246 (eq_attr "alternative" "0,2"))
2247 (const_string "imovx")
2249 (const_string "imov")))
2251 (cond [(eq_attr "type" "imovx")
2253 (and (eq_attr "alternative" "1,2")
2254 (match_operand:HI 1 "aligned_operand" ""))
2256 (and (eq_attr "alternative" "0")
2257 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2259 (eq (symbol_ref "TARGET_HIMODE_MATH")
2263 (const_string "HI")))])
2265 ;; Situation is quite tricky about when to choose full sized (SImode) move
2266 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2267 ;; partial register dependency machines (such as AMD Athlon), where QImode
2268 ;; moves issue extra dependency and for partial register stalls machines
2269 ;; that don't use QImode patterns (and QImode move cause stall on the next
2272 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2273 ;; register stall machines with, where we use QImode instructions, since
2274 ;; partial register stall can be caused there. Then we use movzx.
2275 (define_insn "*movqi_internal"
2276 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2277 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2278 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2280 switch (get_attr_type (insn))
2283 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2284 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2286 if (get_attr_mode (insn) == MODE_SI)
2287 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2289 return "mov{b}\t{%1, %0|%0, %1}";
2293 (cond [(and (eq_attr "alternative" "5")
2294 (not (match_operand:QI 1 "aligned_operand" "")))
2295 (const_string "imovx")
2296 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2298 (const_string "imov")
2299 (and (eq_attr "alternative" "3")
2300 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2302 (eq (symbol_ref "TARGET_QIMODE_MATH")
2304 (const_string "imov")
2305 (eq_attr "alternative" "3,5")
2306 (const_string "imovx")
2307 (and (ne (symbol_ref "TARGET_MOVX")
2309 (eq_attr "alternative" "2"))
2310 (const_string "imovx")
2312 (const_string "imov")))
2314 (cond [(eq_attr "alternative" "3,4,5")
2316 (eq_attr "alternative" "6")
2318 (eq_attr "type" "imovx")
2320 (and (eq_attr "type" "imov")
2321 (and (eq_attr "alternative" "0,1")
2322 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2324 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2326 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2329 ;; Avoid partial register stalls when not using QImode arithmetic
2330 (and (eq_attr "type" "imov")
2331 (and (eq_attr "alternative" "0,1")
2332 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2334 (eq (symbol_ref "TARGET_QIMODE_MATH")
2338 (const_string "QI")))])
2340 ;; Stores and loads of ax to arbitrary constant address.
2341 ;; We fake an second form of instruction to force reload to load address
2342 ;; into register when rax is not available
2343 (define_insn "*movabs<mode>_1"
2344 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2345 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2346 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2348 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2349 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2350 [(set_attr "type" "imov")
2351 (set_attr "modrm" "0,*")
2352 (set_attr "length_address" "8,0")
2353 (set_attr "length_immediate" "0,*")
2354 (set_attr "memory" "store")
2355 (set_attr "mode" "<MODE>")])
2357 (define_insn "*movabs<mode>_2"
2358 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2359 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2360 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2362 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2363 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2364 [(set_attr "type" "imov")
2365 (set_attr "modrm" "0,*")
2366 (set_attr "length_address" "8,0")
2367 (set_attr "length_immediate" "0")
2368 (set_attr "memory" "load")
2369 (set_attr "mode" "<MODE>")])
2371 (define_insn "*swap<mode>"
2372 [(set (match_operand:SWI48 0 "register_operand" "+r")
2373 (match_operand:SWI48 1 "register_operand" "+r"))
2377 "xchg{<imodesuffix>}\t%1, %0"
2378 [(set_attr "type" "imov")
2379 (set_attr "mode" "<MODE>")
2380 (set_attr "pent_pair" "np")
2381 (set_attr "athlon_decode" "vector")
2382 (set_attr "amdfam10_decode" "double")
2383 (set_attr "bdver1_decode" "double")])
2385 (define_insn "*swap<mode>_1"
2386 [(set (match_operand:SWI12 0 "register_operand" "+r")
2387 (match_operand:SWI12 1 "register_operand" "+r"))
2390 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2392 [(set_attr "type" "imov")
2393 (set_attr "mode" "SI")
2394 (set_attr "pent_pair" "np")
2395 (set_attr "athlon_decode" "vector")
2396 (set_attr "amdfam10_decode" "double")
2397 (set_attr "bdver1_decode" "double")])
2399 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2400 ;; is disabled for AMDFAM10
2401 (define_insn "*swap<mode>_2"
2402 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2403 (match_operand:SWI12 1 "register_operand" "+<r>"))
2406 "TARGET_PARTIAL_REG_STALL"
2407 "xchg{<imodesuffix>}\t%1, %0"
2408 [(set_attr "type" "imov")
2409 (set_attr "mode" "<MODE>")
2410 (set_attr "pent_pair" "np")
2411 (set_attr "athlon_decode" "vector")])
2413 (define_expand "movstrict<mode>"
2414 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2415 (match_operand:SWI12 1 "general_operand" ""))]
2418 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2420 /* Don't generate memory->memory moves, go through a register */
2421 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2422 operands[1] = force_reg (<MODE>mode, operands[1]);
2425 (define_insn "*movstrict<mode>_1"
2426 [(set (strict_low_part
2427 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2428 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2429 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2430 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2431 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2432 [(set_attr "type" "imov")
2433 (set_attr "mode" "<MODE>")])
2435 (define_insn "*movstrict<mode>_xor"
2436 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2437 (match_operand:SWI12 1 "const0_operand" ""))
2438 (clobber (reg:CC FLAGS_REG))]
2440 "xor{<imodesuffix>}\t%0, %0"
2441 [(set_attr "type" "alu1")
2442 (set_attr "mode" "<MODE>")
2443 (set_attr "length_immediate" "0")])
2445 (define_insn "*mov<mode>_extv_1"
2446 [(set (match_operand:SWI24 0 "register_operand" "=R")
2447 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2451 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2452 [(set_attr "type" "imovx")
2453 (set_attr "mode" "SI")])
2455 (define_insn "*movqi_extv_1_rex64"
2456 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2457 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2462 switch (get_attr_type (insn))
2465 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2467 return "mov{b}\t{%h1, %0|%0, %h1}";
2471 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2472 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2473 (ne (symbol_ref "TARGET_MOVX")
2475 (const_string "imovx")
2476 (const_string "imov")))
2478 (if_then_else (eq_attr "type" "imovx")
2480 (const_string "QI")))])
2482 (define_insn "*movqi_extv_1"
2483 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2484 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2489 switch (get_attr_type (insn))
2492 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2494 return "mov{b}\t{%h1, %0|%0, %h1}";
2498 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2499 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2500 (ne (symbol_ref "TARGET_MOVX")
2502 (const_string "imovx")
2503 (const_string "imov")))
2505 (if_then_else (eq_attr "type" "imovx")
2507 (const_string "QI")))])
2509 (define_insn "*mov<mode>_extzv_1"
2510 [(set (match_operand:SWI48 0 "register_operand" "=R")
2511 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2515 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2516 [(set_attr "type" "imovx")
2517 (set_attr "mode" "SI")])
2519 (define_insn "*movqi_extzv_2_rex64"
2520 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2522 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2527 switch (get_attr_type (insn))
2530 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2532 return "mov{b}\t{%h1, %0|%0, %h1}";
2536 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2537 (ne (symbol_ref "TARGET_MOVX")
2539 (const_string "imovx")
2540 (const_string "imov")))
2542 (if_then_else (eq_attr "type" "imovx")
2544 (const_string "QI")))])
2546 (define_insn "*movqi_extzv_2"
2547 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2549 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2554 switch (get_attr_type (insn))
2557 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2559 return "mov{b}\t{%h1, %0|%0, %h1}";
2563 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2564 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2565 (ne (symbol_ref "TARGET_MOVX")
2567 (const_string "imovx")
2568 (const_string "imov")))
2570 (if_then_else (eq_attr "type" "imovx")
2572 (const_string "QI")))])
2574 (define_expand "mov<mode>_insv_1"
2575 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2578 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2580 (define_insn "*mov<mode>_insv_1_rex64"
2581 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2584 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2586 "mov{b}\t{%b1, %h0|%h0, %b1}"
2587 [(set_attr "type" "imov")
2588 (set_attr "mode" "QI")])
2590 (define_insn "*movsi_insv_1"
2591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2594 (match_operand:SI 1 "general_operand" "Qmn"))]
2596 "mov{b}\t{%b1, %h0|%h0, %b1}"
2597 [(set_attr "type" "imov")
2598 (set_attr "mode" "QI")])
2600 (define_insn "*movqi_insv_2"
2601 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2604 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2607 "mov{b}\t{%h1, %h0|%h0, %h1}"
2608 [(set_attr "type" "imov")
2609 (set_attr "mode" "QI")])
2611 ;; Floating point push instructions.
2613 (define_insn "*pushtf"
2614 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2615 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2618 /* This insn should be already split before reg-stack. */
2621 [(set_attr "type" "multi")
2622 (set_attr "unit" "sse,*,*")
2623 (set_attr "mode" "TF,SI,SI")])
2626 [(set (match_operand:TF 0 "push_operand" "")
2627 (match_operand:TF 1 "sse_reg_operand" ""))]
2628 "TARGET_SSE2 && reload_completed"
2629 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2630 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2633 [(set (match_operand:TF 0 "push_operand" "")
2634 (match_operand:TF 1 "general_operand" ""))]
2635 "TARGET_SSE2 && reload_completed
2636 && !SSE_REG_P (operands[1])"
2638 "ix86_split_long_move (operands); DONE;")
2640 (define_insn "*pushxf"
2641 [(set (match_operand:XF 0 "push_operand" "=<,<")
2642 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2643 "optimize_function_for_speed_p (cfun)"
2645 /* This insn should be already split before reg-stack. */
2648 [(set_attr "type" "multi")
2649 (set_attr "unit" "i387,*")
2650 (set_attr "mode" "XF,SI")])
2652 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2653 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2654 ;; Pushing using integer instructions is longer except for constants
2655 ;; and direct memory references (assuming that any given constant is pushed
2656 ;; only once, but this ought to be handled elsewhere).
2658 (define_insn "*pushxf_nointeger"
2659 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2660 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2661 "optimize_function_for_size_p (cfun)"
2663 /* This insn should be already split before reg-stack. */
2666 [(set_attr "type" "multi")
2667 (set_attr "unit" "i387,*,*")
2668 (set_attr "mode" "XF,SI,SI")])
2671 [(set (match_operand:XF 0 "push_operand" "")
2672 (match_operand:XF 1 "fp_register_operand" ""))]
2674 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2675 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2676 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2679 [(set (match_operand:XF 0 "push_operand" "")
2680 (match_operand:XF 1 "general_operand" ""))]
2682 && !FP_REG_P (operands[1])"
2684 "ix86_split_long_move (operands); DONE;")
2686 (define_insn "*pushdf"
2687 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2688 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2689 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2691 /* This insn should be already split before reg-stack. */
2694 [(set_attr "type" "multi")
2695 (set_attr "unit" "i387,*,*")
2696 (set_attr "mode" "DF,SI,DF")])
2698 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2699 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2700 ;; On the average, pushdf using integers can be still shorter. Allow this
2701 ;; pattern for optimize_size too.
2703 (define_insn "*pushdf_nointeger"
2704 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2705 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2706 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2708 /* This insn should be already split before reg-stack. */
2711 [(set_attr "type" "multi")
2712 (set_attr "unit" "i387,*,*,*")
2713 (set_attr "mode" "DF,SI,SI,DF")])
2715 ;; %%% Kill this when call knows how to work this out.
2717 [(set (match_operand:DF 0 "push_operand" "")
2718 (match_operand:DF 1 "any_fp_register_operand" ""))]
2720 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2721 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2724 [(set (match_operand:DF 0 "push_operand" "")
2725 (match_operand:DF 1 "general_operand" ""))]
2727 && !ANY_FP_REG_P (operands[1])"
2729 "ix86_split_long_move (operands); DONE;")
2731 (define_insn "*pushsf_rex64"
2732 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2733 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2736 /* Anything else should be already split before reg-stack. */
2737 gcc_assert (which_alternative == 1);
2738 return "push{q}\t%q1";
2740 [(set_attr "type" "multi,push,multi")
2741 (set_attr "unit" "i387,*,*")
2742 (set_attr "mode" "SF,DI,SF")])
2744 (define_insn "*pushsf"
2745 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2746 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2749 /* Anything else should be already split before reg-stack. */
2750 gcc_assert (which_alternative == 1);
2751 return "push{l}\t%1";
2753 [(set_attr "type" "multi,push,multi")
2754 (set_attr "unit" "i387,*,*")
2755 (set_attr "mode" "SF,SI,SF")])
2758 [(set (match_operand:SF 0 "push_operand" "")
2759 (match_operand:SF 1 "memory_operand" ""))]
2761 && MEM_P (operands[1])
2762 && (operands[2] = find_constant_src (insn))"
2766 ;; %%% Kill this when call knows how to work this out.
2768 [(set (match_operand:SF 0 "push_operand" "")
2769 (match_operand:SF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2772 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2775 ;; Floating point move instructions.
2777 (define_expand "movtf"
2778 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2779 (match_operand:TF 1 "nonimmediate_operand" ""))]
2782 ix86_expand_move (TFmode, operands);
2786 (define_expand "mov<mode>"
2787 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2788 (match_operand:X87MODEF 1 "general_operand" ""))]
2790 "ix86_expand_move (<MODE>mode, operands); DONE;")
2792 (define_insn "*movtf_internal"
2793 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2794 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2796 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2798 switch (which_alternative)
2802 if (get_attr_mode (insn) == MODE_V4SF)
2803 return "%vmovaps\t{%1, %0|%0, %1}";
2805 return "%vmovdqa\t{%1, %0|%0, %1}";
2807 if (get_attr_mode (insn) == MODE_V4SF)
2808 return "%vxorps\t%0, %d0";
2810 return "%vpxor\t%0, %d0";
2818 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2819 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2821 (cond [(eq_attr "alternative" "0,2")
2823 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2825 (const_string "V4SF")
2826 (const_string "TI"))
2827 (eq_attr "alternative" "1")
2829 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2831 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2833 (const_string "V4SF")
2834 (const_string "TI"))]
2835 (const_string "DI")))])
2838 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2839 (match_operand:TF 1 "general_operand" ""))]
2841 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2843 "ix86_split_long_move (operands); DONE;")
2845 (define_insn "*movxf_internal"
2846 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2847 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2848 "optimize_function_for_speed_p (cfun)
2849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2850 && (reload_in_progress || reload_completed
2851 || GET_CODE (operands[1]) != CONST_DOUBLE
2852 || memory_operand (operands[0], XFmode))"
2854 switch (which_alternative)
2858 return output_387_reg_move (insn, operands);
2861 return standard_80387_constant_opcode (operands[1]);
2870 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871 (set_attr "mode" "XF,XF,XF,SI,SI")])
2873 ;; Do not use integer registers when optimizing for size
2874 (define_insn "*movxf_internal_nointeger"
2875 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2876 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2877 "optimize_function_for_size_p (cfun)
2878 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2879 && (reload_in_progress || reload_completed
2880 || standard_80387_constant_p (operands[1])
2881 || GET_CODE (operands[1]) != CONST_DOUBLE
2882 || memory_operand (operands[0], XFmode))"
2884 switch (which_alternative)
2888 return output_387_reg_move (insn, operands);
2891 return standard_80387_constant_opcode (operands[1]);
2899 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2900 (set_attr "mode" "XF,XF,XF,SI,SI")])
2903 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2904 (match_operand:XF 1 "general_operand" ""))]
2906 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2907 && ! (FP_REG_P (operands[0]) ||
2908 (GET_CODE (operands[0]) == SUBREG
2909 && FP_REG_P (SUBREG_REG (operands[0]))))
2910 && ! (FP_REG_P (operands[1]) ||
2911 (GET_CODE (operands[1]) == SUBREG
2912 && FP_REG_P (SUBREG_REG (operands[1]))))"
2914 "ix86_split_long_move (operands); DONE;")
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (reload_in_progress || reload_completed
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2925 && optimize_function_for_size_p (cfun)
2926 && standard_80387_constant_p (operands[1]))
2927 || GET_CODE (operands[1]) != CONST_DOUBLE
2928 || memory_operand (operands[0], DFmode))"
2930 switch (which_alternative)
2934 return output_387_reg_move (insn, operands);
2937 return standard_80387_constant_opcode (operands[1]);
2944 switch (get_attr_mode (insn))
2947 return "%vxorps\t%0, %d0";
2949 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2950 return "%vxorps\t%0, %d0";
2952 return "%vxorpd\t%0, %d0";
2954 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2955 return "%vxorps\t%0, %d0";
2957 return "%vpxor\t%0, %d0";
2964 switch (get_attr_mode (insn))
2967 return "%vmovaps\t{%1, %0|%0, %1}";
2969 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2970 return "%vmovaps\t{%1, %0|%0, %1}";
2972 return "%vmovapd\t{%1, %0|%0, %1}";
2974 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2975 return "%vmovaps\t{%1, %0|%0, %1}";
2977 return "%vmovdqa\t{%1, %0|%0, %1}";
2979 return "%vmovq\t{%1, %0|%0, %1}";
2983 if (REG_P (operands[0]) && REG_P (operands[1]))
2984 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2986 return "vmovsd\t{%1, %0|%0, %1}";
2989 return "movsd\t{%1, %0|%0, %1}";
2991 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2993 return "%vmovlps\t{%1, %d0|%d0, %1}";
3000 return "%vmovd\t{%1, %0|%0, %1}";
3006 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3007 (set (attr "prefix")
3008 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3009 (const_string "orig")
3010 (const_string "maybe_vex")))
3011 (set (attr "prefix_data16")
3012 (if_then_else (eq_attr "mode" "V1DF")
3014 (const_string "*")))
3016 (cond [(eq_attr "alternative" "0,1,2")
3018 (eq_attr "alternative" "3,4,9,10")
3021 /* For SSE1, we have many fewer alternatives. */
3022 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023 (cond [(eq_attr "alternative" "5,6")
3024 (const_string "V4SF")
3026 (const_string "V2SF"))
3028 /* xorps is one byte shorter. */
3029 (eq_attr "alternative" "5")
3030 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_string "V4SF")
3033 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3037 (const_string "V2DF"))
3039 /* For architectures resolving dependencies on
3040 whole SSE registers use APD move to break dependency
3041 chains, otherwise use short move to avoid extra work.
3043 movaps encodes one byte shorter. */
3044 (eq_attr "alternative" "6")
3046 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3048 (const_string "V4SF")
3049 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3051 (const_string "V2DF")
3053 (const_string "DF"))
3054 /* For architectures resolving dependencies on register
3055 parts we may avoid extra work to zero out upper part
3057 (eq_attr "alternative" "7")
3059 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3061 (const_string "V1DF")
3062 (const_string "DF"))
3064 (const_string "DF")))])
3066 (define_insn "*movdf_internal"
3067 [(set (match_operand:DF 0 "nonimmediate_operand"
3068 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3069 (match_operand:DF 1 "general_operand"
3070 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3071 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3072 && optimize_function_for_speed_p (cfun)
3073 && TARGET_INTEGER_DFMODE_MOVES
3074 && (reload_in_progress || reload_completed
3075 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3076 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3077 && optimize_function_for_size_p (cfun)
3078 && standard_80387_constant_p (operands[1]))
3079 || GET_CODE (operands[1]) != CONST_DOUBLE
3080 || memory_operand (operands[0], DFmode))"
3082 switch (which_alternative)
3086 return output_387_reg_move (insn, operands);
3089 return standard_80387_constant_opcode (operands[1]);
3096 switch (get_attr_mode (insn))
3099 return "xorps\t%0, %0";
3101 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3102 return "xorps\t%0, %0";
3104 return "xorpd\t%0, %0";
3106 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3107 return "xorps\t%0, %0";
3109 return "pxor\t%0, %0";
3116 switch (get_attr_mode (insn))
3119 return "movaps\t{%1, %0|%0, %1}";
3121 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3122 return "movaps\t{%1, %0|%0, %1}";
3124 return "movapd\t{%1, %0|%0, %1}";
3126 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3127 return "movaps\t{%1, %0|%0, %1}";
3129 return "movdqa\t{%1, %0|%0, %1}";
3131 return "movq\t{%1, %0|%0, %1}";
3133 return "movsd\t{%1, %0|%0, %1}";
3135 return "movlpd\t{%1, %0|%0, %1}";
3137 return "movlps\t{%1, %0|%0, %1}";
3146 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3147 (set (attr "prefix_data16")
3148 (if_then_else (eq_attr "mode" "V1DF")
3150 (const_string "*")))
3152 (cond [(eq_attr "alternative" "0,1,2")
3154 (eq_attr "alternative" "3,4")
3157 /* For SSE1, we have many fewer alternatives. */
3158 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3159 (cond [(eq_attr "alternative" "5,6")
3160 (const_string "V4SF")
3162 (const_string "V2SF"))
3164 /* xorps is one byte shorter. */
3165 (eq_attr "alternative" "5")
3166 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3168 (const_string "V4SF")
3169 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3173 (const_string "V2DF"))
3175 /* For architectures resolving dependencies on
3176 whole SSE registers use APD move to break dependency
3177 chains, otherwise use short move to avoid extra work.
3179 movaps encodes one byte shorter. */
3180 (eq_attr "alternative" "6")
3182 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3184 (const_string "V4SF")
3185 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3187 (const_string "V2DF")
3189 (const_string "DF"))
3190 /* For architectures resolving dependencies on register
3191 parts we may avoid extra work to zero out upper part
3193 (eq_attr "alternative" "7")
3195 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3197 (const_string "V1DF")
3198 (const_string "DF"))
3200 (const_string "DF")))])
3202 ;; Moving is usually shorter when only FP registers are used. This separate
3203 ;; movdf pattern avoids the use of integer registers for FP operations
3204 ;; when optimizing for size.
3206 (define_insn "*movdf_internal_nointeger"
3207 [(set (match_operand:DF 0 "nonimmediate_operand"
3208 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3209 (match_operand:DF 1 "general_operand"
3210 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3211 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3212 && ((optimize_function_for_size_p (cfun)
3213 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3214 && (reload_in_progress || reload_completed
3215 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3216 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3217 && optimize_function_for_size_p (cfun)
3218 && !memory_operand (operands[0], DFmode)
3219 && standard_80387_constant_p (operands[1]))
3220 || GET_CODE (operands[1]) != CONST_DOUBLE
3221 || ((optimize_function_for_size_p (cfun)
3222 || !TARGET_MEMORY_MISMATCH_STALL
3223 || reload_in_progress || reload_completed)
3224 && memory_operand (operands[0], DFmode)))"
3226 switch (which_alternative)
3230 return output_387_reg_move (insn, operands);
3233 return standard_80387_constant_opcode (operands[1]);
3240 switch (get_attr_mode (insn))
3243 return "%vxorps\t%0, %d0";
3245 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3246 return "%vxorps\t%0, %d0";
3248 return "%vxorpd\t%0, %d0";
3250 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3251 return "%vxorps\t%0, %d0";
3253 return "%vpxor\t%0, %d0";
3260 switch (get_attr_mode (insn))
3263 return "%vmovaps\t{%1, %0|%0, %1}";
3265 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3268 return "%vmovapd\t{%1, %0|%0, %1}";
3270 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3271 return "%vmovaps\t{%1, %0|%0, %1}";
3273 return "%vmovdqa\t{%1, %0|%0, %1}";
3275 return "%vmovq\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]) && REG_P (operands[1]))
3280 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovsd\t{%1, %0|%0, %1}";
3285 return "movsd\t{%1, %0|%0, %1}";
3289 if (REG_P (operands[0]))
3290 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3292 return "vmovlpd\t{%1, %0|%0, %1}";
3295 return "movlpd\t{%1, %0|%0, %1}";
3299 if (REG_P (operands[0]))
3300 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3302 return "vmovlps\t{%1, %0|%0, %1}";
3305 return "movlps\t{%1, %0|%0, %1}";
3314 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3315 (set (attr "prefix")
3316 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3317 (const_string "orig")
3318 (const_string "maybe_vex")))
3319 (set (attr "prefix_data16")
3320 (if_then_else (eq_attr "mode" "V1DF")
3322 (const_string "*")))
3324 (cond [(eq_attr "alternative" "0,1,2")
3326 (eq_attr "alternative" "3,4")
3329 /* For SSE1, we have many fewer alternatives. */
3330 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3331 (cond [(eq_attr "alternative" "5,6")
3332 (const_string "V4SF")
3334 (const_string "V2SF"))
3336 /* xorps is one byte shorter. */
3337 (eq_attr "alternative" "5")
3338 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3340 (const_string "V4SF")
3341 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3345 (const_string "V2DF"))
3347 /* For architectures resolving dependencies on
3348 whole SSE registers use APD move to break dependency
3349 chains, otherwise use short move to avoid extra work.
3351 movaps encodes one byte shorter. */
3352 (eq_attr "alternative" "6")
3354 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3356 (const_string "V4SF")
3357 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (const_string "V2DF")
3361 (const_string "DF"))
3362 /* For architectures resolving dependencies on register
3363 parts we may avoid extra work to zero out upper part
3365 (eq_attr "alternative" "7")
3367 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3369 (const_string "V1DF")
3370 (const_string "DF"))
3372 (const_string "DF")))])
3375 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3376 (match_operand:DF 1 "general_operand" ""))]
3378 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3379 && ! (ANY_FP_REG_P (operands[0]) ||
3380 (GET_CODE (operands[0]) == SUBREG
3381 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3382 && ! (ANY_FP_REG_P (operands[1]) ||
3383 (GET_CODE (operands[1]) == SUBREG
3384 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3386 "ix86_split_long_move (operands); DONE;")
3388 (define_insn "*movsf_internal"
3389 [(set (match_operand:SF 0 "nonimmediate_operand"
3390 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3391 (match_operand:SF 1 "general_operand"
3392 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3393 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3394 && (reload_in_progress || reload_completed
3395 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3396 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3397 && standard_80387_constant_p (operands[1]))
3398 || GET_CODE (operands[1]) != CONST_DOUBLE
3399 || memory_operand (operands[0], SFmode))"
3401 switch (which_alternative)
3405 return output_387_reg_move (insn, operands);
3408 return standard_80387_constant_opcode (operands[1]);
3412 return "mov{l}\t{%1, %0|%0, %1}";
3414 if (get_attr_mode (insn) == MODE_TI)
3415 return "%vpxor\t%0, %d0";
3417 return "%vxorps\t%0, %d0";
3419 if (get_attr_mode (insn) == MODE_V4SF)
3420 return "%vmovaps\t{%1, %0|%0, %1}";
3422 return "%vmovss\t{%1, %d0|%d0, %1}";
3425 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3426 : "vmovss\t{%1, %0|%0, %1}";
3428 return "movss\t{%1, %0|%0, %1}";
3430 return "%vmovss\t{%1, %0|%0, %1}";
3432 case 9: case 10: case 14: case 15:
3433 return "movd\t{%1, %0|%0, %1}";
3435 return "%vmovd\t{%1, %0|%0, %1}";
3438 return "movq\t{%1, %0|%0, %1}";
3444 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3445 (set (attr "prefix")
3446 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3447 (const_string "maybe_vex")
3448 (const_string "orig")))
3450 (cond [(eq_attr "alternative" "3,4,9,10")
3452 (eq_attr "alternative" "5")
3454 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3456 (ne (symbol_ref "TARGET_SSE2")
3458 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3461 (const_string "V4SF"))
3462 /* For architectures resolving dependencies on
3463 whole SSE registers use APS move to break dependency
3464 chains, otherwise use short move to avoid extra work.
3466 Do the same for architectures resolving dependencies on
3467 the parts. While in DF mode it is better to always handle
3468 just register parts, the SF mode is different due to lack
3469 of instructions to load just part of the register. It is
3470 better to maintain the whole registers in single format
3471 to avoid problems on using packed logical operations. */
3472 (eq_attr "alternative" "6")
3474 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3476 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3478 (const_string "V4SF")
3479 (const_string "SF"))
3480 (eq_attr "alternative" "11")
3481 (const_string "DI")]
3482 (const_string "SF")))])
3485 [(set (match_operand 0 "register_operand" "")
3486 (match_operand 1 "memory_operand" ""))]
3488 && MEM_P (operands[1])
3489 && (GET_MODE (operands[0]) == TFmode
3490 || GET_MODE (operands[0]) == XFmode
3491 || GET_MODE (operands[0]) == DFmode
3492 || GET_MODE (operands[0]) == SFmode)
3493 && (operands[2] = find_constant_src (insn))"
3494 [(set (match_dup 0) (match_dup 2))]
3496 rtx c = operands[2];
3497 rtx r = operands[0];
3499 if (GET_CODE (r) == SUBREG)
3504 if (!standard_sse_constant_p (c))
3507 else if (FP_REG_P (r))
3509 if (!standard_80387_constant_p (c))
3512 else if (MMX_REG_P (r))
3517 [(set (match_operand 0 "register_operand" "")
3518 (float_extend (match_operand 1 "memory_operand" "")))]
3520 && MEM_P (operands[1])
3521 && (GET_MODE (operands[0]) == TFmode
3522 || GET_MODE (operands[0]) == XFmode
3523 || GET_MODE (operands[0]) == DFmode
3524 || GET_MODE (operands[0]) == SFmode)
3525 && (operands[2] = find_constant_src (insn))"
3526 [(set (match_dup 0) (match_dup 2))]
3528 rtx c = operands[2];
3529 rtx r = operands[0];
3531 if (GET_CODE (r) == SUBREG)
3536 if (!standard_sse_constant_p (c))
3539 else if (FP_REG_P (r))
3541 if (!standard_80387_constant_p (c))
3544 else if (MMX_REG_P (r))
3548 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3550 [(set (match_operand:X87MODEF 0 "register_operand" "")
3551 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3552 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3553 && (standard_80387_constant_p (operands[1]) == 8
3554 || standard_80387_constant_p (operands[1]) == 9)"
3555 [(set (match_dup 0)(match_dup 1))
3557 (neg:X87MODEF (match_dup 0)))]
3561 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3562 if (real_isnegzero (&r))
3563 operands[1] = CONST0_RTX (<MODE>mode);
3565 operands[1] = CONST1_RTX (<MODE>mode);
3568 (define_insn "swapxf"
3569 [(set (match_operand:XF 0 "register_operand" "+f")
3570 (match_operand:XF 1 "register_operand" "+f"))
3575 if (STACK_TOP_P (operands[0]))
3580 [(set_attr "type" "fxch")
3581 (set_attr "mode" "XF")])
3583 (define_insn "*swap<mode>"
3584 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3585 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3588 "TARGET_80387 || reload_completed"
3590 if (STACK_TOP_P (operands[0]))
3595 [(set_attr "type" "fxch")
3596 (set_attr "mode" "<MODE>")])
3598 ;; Zero extension instructions
3600 (define_expand "zero_extendsidi2"
3601 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3602 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3607 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3612 (define_insn "*zero_extendsidi2_rex64"
3613 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3615 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3618 mov\t{%k1, %k0|%k0, %k1}
3620 movd\t{%1, %0|%0, %1}
3621 movd\t{%1, %0|%0, %1}
3622 %vmovd\t{%1, %0|%0, %1}
3623 %vmovd\t{%1, %0|%0, %1}"
3624 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3625 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3626 (set_attr "prefix_0f" "0,*,*,*,*,*")
3627 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3630 [(set (match_operand:DI 0 "memory_operand" "")
3631 (zero_extend:DI (match_dup 0)))]
3633 [(set (match_dup 4) (const_int 0))]
3634 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3636 ;; %%% Kill me once multi-word ops are sane.
3637 (define_insn "zero_extendsidi2_1"
3638 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3640 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3641 (clobber (reg:CC FLAGS_REG))]
3647 movd\t{%1, %0|%0, %1}
3648 movd\t{%1, %0|%0, %1}
3649 %vmovd\t{%1, %0|%0, %1}
3650 %vmovd\t{%1, %0|%0, %1}"
3651 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3652 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3653 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3656 [(set (match_operand:DI 0 "register_operand" "")
3657 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3658 (clobber (reg:CC FLAGS_REG))]
3659 "!TARGET_64BIT && reload_completed
3660 && true_regnum (operands[0]) == true_regnum (operands[1])"
3661 [(set (match_dup 4) (const_int 0))]
3662 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3665 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3666 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3667 (clobber (reg:CC FLAGS_REG))]
3668 "!TARGET_64BIT && reload_completed
3669 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3670 [(set (match_dup 3) (match_dup 1))
3671 (set (match_dup 4) (const_int 0))]
3672 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3674 (define_insn "zero_extend<mode>di2"
3675 [(set (match_operand:DI 0 "register_operand" "=r")
3677 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3679 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3683 (define_expand "zero_extendhisi2"
3684 [(set (match_operand:SI 0 "register_operand" "")
3685 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3688 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3690 operands[1] = force_reg (HImode, operands[1]);
3691 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3696 (define_insn_and_split "zero_extendhisi2_and"
3697 [(set (match_operand:SI 0 "register_operand" "=r")
3698 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3699 (clobber (reg:CC FLAGS_REG))]
3700 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702 "&& reload_completed"
3703 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3704 (clobber (reg:CC FLAGS_REG))])]
3706 [(set_attr "type" "alu1")
3707 (set_attr "mode" "SI")])
3709 (define_insn "*zero_extendhisi2_movzwl"
3710 [(set (match_operand:SI 0 "register_operand" "=r")
3711 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3712 "!TARGET_ZERO_EXTEND_WITH_AND
3713 || optimize_function_for_size_p (cfun)"
3714 "movz{wl|x}\t{%1, %0|%0, %1}"
3715 [(set_attr "type" "imovx")
3716 (set_attr "mode" "SI")])
3718 (define_expand "zero_extendqi<mode>2"
3720 [(set (match_operand:SWI24 0 "register_operand" "")
3721 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3722 (clobber (reg:CC FLAGS_REG))])])
3724 (define_insn "*zero_extendqi<mode>2_and"
3725 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3726 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3727 (clobber (reg:CC FLAGS_REG))]
3728 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3730 [(set_attr "type" "alu1")
3731 (set_attr "mode" "<MODE>")])
3733 ;; When source and destination does not overlap, clear destination
3734 ;; first and then do the movb
3736 [(set (match_operand:SWI24 0 "register_operand" "")
3737 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3738 (clobber (reg:CC FLAGS_REG))]
3740 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3741 && ANY_QI_REG_P (operands[0])
3742 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3743 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3744 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3746 operands[2] = gen_lowpart (QImode, operands[0]);
3747 ix86_expand_clear (operands[0]);
3750 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3751 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3752 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3753 (clobber (reg:CC FLAGS_REG))]
3754 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3756 [(set_attr "type" "imovx,alu1")
3757 (set_attr "mode" "<MODE>")])
3759 ;; For the movzbl case strip only the clobber
3761 [(set (match_operand:SWI24 0 "register_operand" "")
3762 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3763 (clobber (reg:CC FLAGS_REG))]
3765 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3766 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3768 (zero_extend:SWI24 (match_dup 1)))])
3770 ; zero extend to SImode to avoid partial register stalls
3771 (define_insn "*zero_extendqi<mode>2_movzbl"
3772 [(set (match_operand:SWI24 0 "register_operand" "=r")
3773 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3775 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3776 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "SI")])
3780 ;; Rest is handled by single and.
3782 [(set (match_operand:SWI24 0 "register_operand" "")
3783 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3784 (clobber (reg:CC FLAGS_REG))]
3786 && true_regnum (operands[0]) == true_regnum (operands[1])"
3787 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3788 (clobber (reg:CC FLAGS_REG))])])
3790 ;; Sign extension instructions
3792 (define_expand "extendsidi2"
3793 [(set (match_operand:DI 0 "register_operand" "")
3794 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3799 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3804 (define_insn "*extendsidi2_rex64"
3805 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3806 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3810 movs{lq|x}\t{%1, %0|%0, %1}"
3811 [(set_attr "type" "imovx")
3812 (set_attr "mode" "DI")
3813 (set_attr "prefix_0f" "0")
3814 (set_attr "modrm" "0,1")])
3816 (define_insn "extendsidi2_1"
3817 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3818 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3819 (clobber (reg:CC FLAGS_REG))
3820 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3824 ;; Extend to memory case when source register does die.
3826 [(set (match_operand:DI 0 "memory_operand" "")
3827 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3828 (clobber (reg:CC FLAGS_REG))
3829 (clobber (match_operand:SI 2 "register_operand" ""))]
3831 && dead_or_set_p (insn, operands[1])
3832 && !reg_mentioned_p (operands[1], operands[0]))"
3833 [(set (match_dup 3) (match_dup 1))
3834 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3835 (clobber (reg:CC FLAGS_REG))])
3836 (set (match_dup 4) (match_dup 1))]
3837 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3839 ;; Extend to memory case when source register does not die.
3841 [(set (match_operand:DI 0 "memory_operand" "")
3842 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3843 (clobber (reg:CC FLAGS_REG))
3844 (clobber (match_operand:SI 2 "register_operand" ""))]
3848 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3850 emit_move_insn (operands[3], operands[1]);
3852 /* Generate a cltd if possible and doing so it profitable. */
3853 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3854 && true_regnum (operands[1]) == AX_REG
3855 && true_regnum (operands[2]) == DX_REG)
3857 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3861 emit_move_insn (operands[2], operands[1]);
3862 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3864 emit_move_insn (operands[4], operands[2]);
3868 ;; Extend to register case. Optimize case where source and destination
3869 ;; registers match and cases where we can use cltd.
3871 [(set (match_operand:DI 0 "register_operand" "")
3872 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3873 (clobber (reg:CC FLAGS_REG))
3874 (clobber (match_scratch:SI 2 ""))]
3878 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3880 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3881 emit_move_insn (operands[3], operands[1]);
3883 /* Generate a cltd if possible and doing so it profitable. */
3884 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3885 && true_regnum (operands[3]) == AX_REG
3886 && true_regnum (operands[4]) == DX_REG)
3888 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3892 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3893 emit_move_insn (operands[4], operands[1]);
3895 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3899 (define_insn "extend<mode>di2"
3900 [(set (match_operand:DI 0 "register_operand" "=r")
3902 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3904 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "DI")])
3908 (define_insn "extendhisi2"
3909 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3910 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3913 switch (get_attr_prefix_0f (insn))
3916 return "{cwtl|cwde}";
3918 return "movs{wl|x}\t{%1, %0|%0, %1}";
3921 [(set_attr "type" "imovx")
3922 (set_attr "mode" "SI")
3923 (set (attr "prefix_0f")
3924 ;; movsx is short decodable while cwtl is vector decoded.
3925 (if_then_else (and (eq_attr "cpu" "!k6")
3926 (eq_attr "alternative" "0"))
3928 (const_string "1")))
3930 (if_then_else (eq_attr "prefix_0f" "0")
3932 (const_string "1")))])
3934 (define_insn "*extendhisi2_zext"
3935 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3938 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3941 switch (get_attr_prefix_0f (insn))
3944 return "{cwtl|cwde}";
3946 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "SI")
3951 (set (attr "prefix_0f")
3952 ;; movsx is short decodable while cwtl is vector decoded.
3953 (if_then_else (and (eq_attr "cpu" "!k6")
3954 (eq_attr "alternative" "0"))
3956 (const_string "1")))
3958 (if_then_else (eq_attr "prefix_0f" "0")
3960 (const_string "1")))])
3962 (define_insn "extendqisi2"
3963 [(set (match_operand:SI 0 "register_operand" "=r")
3964 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3966 "movs{bl|x}\t{%1, %0|%0, %1}"
3967 [(set_attr "type" "imovx")
3968 (set_attr "mode" "SI")])
3970 (define_insn "*extendqisi2_zext"
3971 [(set (match_operand:DI 0 "register_operand" "=r")
3973 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3975 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3976 [(set_attr "type" "imovx")
3977 (set_attr "mode" "SI")])
3979 (define_insn "extendqihi2"
3980 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3981 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3984 switch (get_attr_prefix_0f (insn))
3987 return "{cbtw|cbw}";
3989 return "movs{bw|x}\t{%1, %0|%0, %1}";
3992 [(set_attr "type" "imovx")
3993 (set_attr "mode" "HI")
3994 (set (attr "prefix_0f")
3995 ;; movsx is short decodable while cwtl is vector decoded.
3996 (if_then_else (and (eq_attr "cpu" "!k6")
3997 (eq_attr "alternative" "0"))
3999 (const_string "1")))
4001 (if_then_else (eq_attr "prefix_0f" "0")
4003 (const_string "1")))])
4005 ;; Conversions between float and double.
4007 ;; These are all no-ops in the model used for the 80387.
4008 ;; So just emit moves.
4010 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4012 [(set (match_operand:DF 0 "push_operand" "")
4013 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4015 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4016 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4019 [(set (match_operand:XF 0 "push_operand" "")
4020 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4022 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4023 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4024 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4026 (define_expand "extendsfdf2"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4028 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4029 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4031 /* ??? Needed for compress_float_constant since all fp constants
4032 are LEGITIMATE_CONSTANT_P. */
4033 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4035 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4036 && standard_80387_constant_p (operands[1]) > 0)
4038 operands[1] = simplify_const_unary_operation
4039 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4040 emit_move_insn_1 (operands[0], operands[1]);
4043 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4047 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4049 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4051 We do the conversion post reload to avoid producing of 128bit spills
4052 that might lead to ICE on 32bit target. The sequence unlikely combine
4055 [(set (match_operand:DF 0 "register_operand" "")
4057 (match_operand:SF 1 "nonimmediate_operand" "")))]
4058 "TARGET_USE_VECTOR_FP_CONVERTS
4059 && optimize_insn_for_speed_p ()
4060 && reload_completed && SSE_REG_P (operands[0])"
4065 (parallel [(const_int 0) (const_int 1)]))))]
4067 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4068 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4069 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4070 Try to avoid move when unpacking can be done in source. */
4071 if (REG_P (operands[1]))
4073 /* If it is unsafe to overwrite upper half of source, we need
4074 to move to destination and unpack there. */
4075 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4076 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4077 && true_regnum (operands[0]) != true_regnum (operands[1]))
4079 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4080 emit_move_insn (tmp, operands[1]);
4083 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4084 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4088 emit_insn (gen_vec_setv4sf_0 (operands[3],
4089 CONST0_RTX (V4SFmode), operands[1]));
4092 (define_insn "*extendsfdf2_mixed"
4093 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4095 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4096 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4098 switch (which_alternative)
4102 return output_387_reg_move (insn, operands);
4105 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4111 [(set_attr "type" "fmov,fmov,ssecvt")
4112 (set_attr "prefix" "orig,orig,maybe_vex")
4113 (set_attr "mode" "SF,XF,DF")])
4115 (define_insn "*extendsfdf2_sse"
4116 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4117 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4118 "TARGET_SSE2 && TARGET_SSE_MATH"
4119 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4120 [(set_attr "type" "ssecvt")
4121 (set_attr "prefix" "maybe_vex")
4122 (set_attr "mode" "DF")])
4124 (define_insn "*extendsfdf2_i387"
4125 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4126 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF,XF")])
4132 (define_expand "extend<mode>xf2"
4133 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4134 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4137 /* ??? Needed for compress_float_constant since all fp constants
4138 are LEGITIMATE_CONSTANT_P. */
4139 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4141 if (standard_80387_constant_p (operands[1]) > 0)
4143 operands[1] = simplify_const_unary_operation
4144 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4145 emit_move_insn_1 (operands[0], operands[1]);
4148 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4152 (define_insn "*extend<mode>xf2_i387"
4153 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4155 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4157 "* return output_387_reg_move (insn, operands);"
4158 [(set_attr "type" "fmov")
4159 (set_attr "mode" "<MODE>,XF")])
4161 ;; %%% This seems bad bad news.
4162 ;; This cannot output into an f-reg because there is no way to be sure
4163 ;; of truncating in that case. Otherwise this is just like a simple move
4164 ;; insn. So we pretend we can output to a reg in order to get better
4165 ;; register preferencing, but we really use a stack slot.
4167 ;; Conversion from DFmode to SFmode.
4169 (define_expand "truncdfsf2"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4172 (match_operand:DF 1 "nonimmediate_operand" "")))]
4173 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4175 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4177 else if (flag_unsafe_math_optimizations)
4181 enum ix86_stack_slot slot = (virtuals_instantiated
4184 rtx temp = assign_386_stack_local (SFmode, slot);
4185 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4190 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4192 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4194 We do the conversion post reload to avoid producing of 128bit spills
4195 that might lead to ICE on 32bit target. The sequence unlikely combine
4198 [(set (match_operand:SF 0 "register_operand" "")
4200 (match_operand:DF 1 "nonimmediate_operand" "")))]
4201 "TARGET_USE_VECTOR_FP_CONVERTS
4202 && optimize_insn_for_speed_p ()
4203 && reload_completed && SSE_REG_P (operands[0])"
4206 (float_truncate:V2SF
4210 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4211 operands[3] = CONST0_RTX (V2SFmode);
4212 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4213 /* Use movsd for loading from memory, unpcklpd for registers.
4214 Try to avoid move when unpacking can be done in source, or SSE3
4215 movddup is available. */
4216 if (REG_P (operands[1]))
4219 && true_regnum (operands[0]) != true_regnum (operands[1])
4220 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4221 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4223 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4224 emit_move_insn (tmp, operands[1]);
4227 else if (!TARGET_SSE3)
4228 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4229 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4232 emit_insn (gen_sse2_loadlpd (operands[4],
4233 CONST0_RTX (V2DFmode), operands[1]));
4236 (define_expand "truncdfsf2_with_temp"
4237 [(parallel [(set (match_operand:SF 0 "" "")
4238 (float_truncate:SF (match_operand:DF 1 "" "")))
4239 (clobber (match_operand:SF 2 "" ""))])])
4241 (define_insn "*truncdfsf_fast_mixed"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4244 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4245 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4247 switch (which_alternative)
4250 return output_387_reg_move (insn, operands);
4252 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4257 [(set_attr "type" "fmov,ssecvt")
4258 (set_attr "prefix" "orig,maybe_vex")
4259 (set_attr "mode" "SF")])
4261 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4262 ;; because nothing we do here is unsafe.
4263 (define_insn "*truncdfsf_fast_sse"
4264 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4266 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4267 "TARGET_SSE2 && TARGET_SSE_MATH"
4268 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4269 [(set_attr "type" "ssecvt")
4270 (set_attr "prefix" "maybe_vex")
4271 (set_attr "mode" "SF")])
4273 (define_insn "*truncdfsf_fast_i387"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4276 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4277 "TARGET_80387 && flag_unsafe_math_optimizations"
4278 "* return output_387_reg_move (insn, operands);"
4279 [(set_attr "type" "fmov")
4280 (set_attr "mode" "SF")])
4282 (define_insn "*truncdfsf_mixed"
4283 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4285 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4286 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4287 "TARGET_MIX_SSE_I387"
4289 switch (which_alternative)
4292 return output_387_reg_move (insn, operands);
4294 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4300 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4301 (set_attr "unit" "*,*,i387,i387,i387")
4302 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4303 (set_attr "mode" "SF")])
4305 (define_insn "*truncdfsf_i387"
4306 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4308 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4309 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4312 switch (which_alternative)
4315 return output_387_reg_move (insn, operands);
4321 [(set_attr "type" "fmov,multi,multi,multi")
4322 (set_attr "unit" "*,i387,i387,i387")
4323 (set_attr "mode" "SF")])
4325 (define_insn "*truncdfsf2_i387_1"
4326 [(set (match_operand:SF 0 "memory_operand" "=m")
4328 (match_operand:DF 1 "register_operand" "f")))]
4330 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4331 && !TARGET_MIX_SSE_I387"
4332 "* return output_387_reg_move (insn, operands);"
4333 [(set_attr "type" "fmov")
4334 (set_attr "mode" "SF")])
4337 [(set (match_operand:SF 0 "register_operand" "")
4339 (match_operand:DF 1 "fp_register_operand" "")))
4340 (clobber (match_operand 2 "" ""))]
4342 [(set (match_dup 2) (match_dup 1))
4343 (set (match_dup 0) (match_dup 2))]
4344 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4346 ;; Conversion from XFmode to {SF,DF}mode
4348 (define_expand "truncxf<mode>2"
4349 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4350 (float_truncate:MODEF
4351 (match_operand:XF 1 "register_operand" "")))
4352 (clobber (match_dup 2))])]
4355 if (flag_unsafe_math_optimizations)
4357 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4358 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4359 if (reg != operands[0])
4360 emit_move_insn (operands[0], reg);
4365 enum ix86_stack_slot slot = (virtuals_instantiated
4368 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4372 (define_insn "*truncxfsf2_mixed"
4373 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4375 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4376 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4379 gcc_assert (!which_alternative);
4380 return output_387_reg_move (insn, operands);
4382 [(set_attr "type" "fmov,multi,multi,multi")
4383 (set_attr "unit" "*,i387,i387,i387")
4384 (set_attr "mode" "SF")])
4386 (define_insn "*truncxfdf2_mixed"
4387 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4389 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4390 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4393 gcc_assert (!which_alternative);
4394 return output_387_reg_move (insn, operands);
4396 [(set_attr "type" "fmov,multi,multi,multi")
4397 (set_attr "unit" "*,i387,i387,i387")
4398 (set_attr "mode" "DF")])
4400 (define_insn "truncxf<mode>2_i387_noop"
4401 [(set (match_operand:MODEF 0 "register_operand" "=f")
4402 (float_truncate:MODEF
4403 (match_operand:XF 1 "register_operand" "f")))]
4404 "TARGET_80387 && flag_unsafe_math_optimizations"
4405 "* return output_387_reg_move (insn, operands);"
4406 [(set_attr "type" "fmov")
4407 (set_attr "mode" "<MODE>")])
4409 (define_insn "*truncxf<mode>2_i387"
4410 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4411 (float_truncate:MODEF
4412 (match_operand:XF 1 "register_operand" "f")))]
4414 "* return output_387_reg_move (insn, operands);"
4415 [(set_attr "type" "fmov")
4416 (set_attr "mode" "<MODE>")])
4419 [(set (match_operand:MODEF 0 "register_operand" "")
4420 (float_truncate:MODEF
4421 (match_operand:XF 1 "register_operand" "")))
4422 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4423 "TARGET_80387 && reload_completed"
4424 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4425 (set (match_dup 0) (match_dup 2))])
4428 [(set (match_operand:MODEF 0 "memory_operand" "")
4429 (float_truncate:MODEF
4430 (match_operand:XF 1 "register_operand" "")))
4431 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4433 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4435 ;; Signed conversion to DImode.
4437 (define_expand "fix_truncxfdi2"
4438 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4439 (fix:DI (match_operand:XF 1 "register_operand" "")))
4440 (clobber (reg:CC FLAGS_REG))])]
4445 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4450 (define_expand "fix_trunc<mode>di2"
4451 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4452 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4453 (clobber (reg:CC FLAGS_REG))])]
4454 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4457 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4459 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4462 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4464 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4465 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4466 if (out != operands[0])
4467 emit_move_insn (operands[0], out);
4472 ;; Signed conversion to SImode.
4474 (define_expand "fix_truncxfsi2"
4475 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4476 (fix:SI (match_operand:XF 1 "register_operand" "")))
4477 (clobber (reg:CC FLAGS_REG))])]
4482 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4487 (define_expand "fix_trunc<mode>si2"
4488 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4489 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4490 (clobber (reg:CC FLAGS_REG))])]
4491 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4494 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4496 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4499 if (SSE_FLOAT_MODE_P (<MODE>mode))
4501 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4502 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4503 if (out != operands[0])
4504 emit_move_insn (operands[0], out);
4509 ;; Signed conversion to HImode.
4511 (define_expand "fix_trunc<mode>hi2"
4512 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4513 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4514 (clobber (reg:CC FLAGS_REG))])]
4516 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4520 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4525 ;; Unsigned conversion to SImode.
4527 (define_expand "fixuns_trunc<mode>si2"
4529 [(set (match_operand:SI 0 "register_operand" "")
4531 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4533 (clobber (match_scratch:<ssevecmode> 3 ""))
4534 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4535 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4537 enum machine_mode mode = <MODE>mode;
4538 enum machine_mode vecmode = <ssevecmode>mode;
4539 REAL_VALUE_TYPE TWO31r;
4542 if (optimize_insn_for_size_p ())
4545 real_ldexp (&TWO31r, &dconst1, 31);
4546 two31 = const_double_from_real_value (TWO31r, mode);
4547 two31 = ix86_build_const_vector (vecmode, true, two31);
4548 operands[2] = force_reg (vecmode, two31);
4551 (define_insn_and_split "*fixuns_trunc<mode>_1"
4552 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4554 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4555 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4556 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4557 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4558 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4559 && optimize_function_for_speed_p (cfun)"
4561 "&& reload_completed"
4564 ix86_split_convert_uns_si_sse (operands);
4568 ;; Unsigned conversion to HImode.
4569 ;; Without these patterns, we'll try the unsigned SI conversion which
4570 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4572 (define_expand "fixuns_trunc<mode>hi2"
4574 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4575 (set (match_operand:HI 0 "nonimmediate_operand" "")
4576 (subreg:HI (match_dup 2) 0))]
4577 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4578 "operands[2] = gen_reg_rtx (SImode);")
4580 ;; When SSE is available, it is always faster to use it!
4581 (define_insn "fix_trunc<mode>di_sse"
4582 [(set (match_operand:DI 0 "register_operand" "=r,r")
4583 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4584 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4585 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4586 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4587 [(set_attr "type" "sseicvt")
4588 (set_attr "prefix" "maybe_vex")
4589 (set_attr "prefix_rex" "1")
4590 (set_attr "mode" "<MODE>")
4591 (set_attr "athlon_decode" "double,vector")
4592 (set_attr "amdfam10_decode" "double,double")
4593 (set_attr "bdver1_decode" "double,double")])
4595 (define_insn "fix_trunc<mode>si_sse"
4596 [(set (match_operand:SI 0 "register_operand" "=r,r")
4597 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4598 "SSE_FLOAT_MODE_P (<MODE>mode)
4599 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4600 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4601 [(set_attr "type" "sseicvt")
4602 (set_attr "prefix" "maybe_vex")
4603 (set_attr "mode" "<MODE>")
4604 (set_attr "athlon_decode" "double,vector")
4605 (set_attr "amdfam10_decode" "double,double")
4606 (set_attr "bdver1_decode" "double,double")])
4608 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4610 [(set (match_operand:MODEF 0 "register_operand" "")
4611 (match_operand:MODEF 1 "memory_operand" ""))
4612 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4613 (fix:SSEMODEI24 (match_dup 0)))]
4614 "TARGET_SHORTEN_X87_SSE
4615 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4616 && peep2_reg_dead_p (2, operands[0])"
4617 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4619 ;; Avoid vector decoded forms of the instruction.
4621 [(match_scratch:DF 2 "Y2")
4622 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4623 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4624 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4625 [(set (match_dup 2) (match_dup 1))
4626 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4629 [(match_scratch:SF 2 "x")
4630 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4631 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4632 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4633 [(set (match_dup 2) (match_dup 1))
4634 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4636 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4637 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4638 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4639 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4642 && (TARGET_64BIT || <MODE>mode != DImode))
4644 && can_create_pseudo_p ()"
4649 if (memory_operand (operands[0], VOIDmode))
4650 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4653 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4654 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4660 [(set_attr "type" "fisttp")
4661 (set_attr "mode" "<MODE>")])
4663 (define_insn "fix_trunc<mode>_i387_fisttp"
4664 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4665 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4666 (clobber (match_scratch:XF 2 "=&1f"))]
4667 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && (TARGET_64BIT || <MODE>mode != DImode))
4671 && TARGET_SSE_MATH)"
4672 "* return output_fix_trunc (insn, operands, 1);"
4673 [(set_attr "type" "fisttp")
4674 (set_attr "mode" "<MODE>")])
4676 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4677 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4678 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4679 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4680 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4681 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4683 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4684 && (TARGET_64BIT || <MODE>mode != DImode))
4685 && TARGET_SSE_MATH)"
4687 [(set_attr "type" "fisttp")
4688 (set_attr "mode" "<MODE>")])
4691 [(set (match_operand:X87MODEI 0 "register_operand" "")
4692 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4693 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4694 (clobber (match_scratch 3 ""))]
4696 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4697 (clobber (match_dup 3))])
4698 (set (match_dup 0) (match_dup 2))])
4701 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4702 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4703 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4704 (clobber (match_scratch 3 ""))]
4706 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4707 (clobber (match_dup 3))])])
4709 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4710 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4711 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4712 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4713 ;; function in i386.c.
4714 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4715 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4716 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4717 (clobber (reg:CC FLAGS_REG))]
4718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4721 && (TARGET_64BIT || <MODE>mode != DImode))
4722 && can_create_pseudo_p ()"
4727 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4729 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4730 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4731 if (memory_operand (operands[0], VOIDmode))
4732 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4733 operands[2], operands[3]));
4736 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4737 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4738 operands[2], operands[3],
4743 [(set_attr "type" "fistp")
4744 (set_attr "i387_cw" "trunc")
4745 (set_attr "mode" "<MODE>")])
4747 (define_insn "fix_truncdi_i387"
4748 [(set (match_operand:DI 0 "memory_operand" "=m")
4749 (fix:DI (match_operand 1 "register_operand" "f")))
4750 (use (match_operand:HI 2 "memory_operand" "m"))
4751 (use (match_operand:HI 3 "memory_operand" "m"))
4752 (clobber (match_scratch:XF 4 "=&1f"))]
4753 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4755 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4756 "* return output_fix_trunc (insn, operands, 0);"
4757 [(set_attr "type" "fistp")
4758 (set_attr "i387_cw" "trunc")
4759 (set_attr "mode" "DI")])
4761 (define_insn "fix_truncdi_i387_with_temp"
4762 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4763 (fix:DI (match_operand 1 "register_operand" "f,f")))
4764 (use (match_operand:HI 2 "memory_operand" "m,m"))
4765 (use (match_operand:HI 3 "memory_operand" "m,m"))
4766 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4767 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4768 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4770 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4772 [(set_attr "type" "fistp")
4773 (set_attr "i387_cw" "trunc")
4774 (set_attr "mode" "DI")])
4777 [(set (match_operand:DI 0 "register_operand" "")
4778 (fix:DI (match_operand 1 "register_operand" "")))
4779 (use (match_operand:HI 2 "memory_operand" ""))
4780 (use (match_operand:HI 3 "memory_operand" ""))
4781 (clobber (match_operand:DI 4 "memory_operand" ""))
4782 (clobber (match_scratch 5 ""))]
4784 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4787 (clobber (match_dup 5))])
4788 (set (match_dup 0) (match_dup 4))])
4791 [(set (match_operand:DI 0 "memory_operand" "")
4792 (fix:DI (match_operand 1 "register_operand" "")))
4793 (use (match_operand:HI 2 "memory_operand" ""))
4794 (use (match_operand:HI 3 "memory_operand" ""))
4795 (clobber (match_operand:DI 4 "memory_operand" ""))
4796 (clobber (match_scratch 5 ""))]
4798 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4801 (clobber (match_dup 5))])])
4803 (define_insn "fix_trunc<mode>_i387"
4804 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4805 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4806 (use (match_operand:HI 2 "memory_operand" "m"))
4807 (use (match_operand:HI 3 "memory_operand" "m"))]
4808 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4810 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4811 "* return output_fix_trunc (insn, operands, 0);"
4812 [(set_attr "type" "fistp")
4813 (set_attr "i387_cw" "trunc")
4814 (set_attr "mode" "<MODE>")])
4816 (define_insn "fix_trunc<mode>_i387_with_temp"
4817 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4818 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4819 (use (match_operand:HI 2 "memory_operand" "m,m"))
4820 (use (match_operand:HI 3 "memory_operand" "m,m"))
4821 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4822 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4824 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4826 [(set_attr "type" "fistp")
4827 (set_attr "i387_cw" "trunc")
4828 (set_attr "mode" "<MODE>")])
4831 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4832 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4833 (use (match_operand:HI 2 "memory_operand" ""))
4834 (use (match_operand:HI 3 "memory_operand" ""))
4835 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4837 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4839 (use (match_dup 3))])
4840 (set (match_dup 0) (match_dup 4))])
4843 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4844 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4845 (use (match_operand:HI 2 "memory_operand" ""))
4846 (use (match_operand:HI 3 "memory_operand" ""))
4847 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4849 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4851 (use (match_dup 3))])])
4853 (define_insn "x86_fnstcw_1"
4854 [(set (match_operand:HI 0 "memory_operand" "=m")
4855 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4858 [(set (attr "length")
4859 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4860 (set_attr "mode" "HI")
4861 (set_attr "unit" "i387")
4862 (set_attr "bdver1_decode" "vector")])
4864 (define_insn "x86_fldcw_1"
4865 [(set (reg:HI FPCR_REG)
4866 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4869 [(set (attr "length")
4870 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4871 (set_attr "mode" "HI")
4872 (set_attr "unit" "i387")
4873 (set_attr "athlon_decode" "vector")
4874 (set_attr "amdfam10_decode" "vector")
4875 (set_attr "bdver1_decode" "vector")])
4877 ;; Conversion between fixed point and floating point.
4879 ;; Even though we only accept memory inputs, the backend _really_
4880 ;; wants to be able to do this between registers.
4882 (define_expand "floathi<mode>2"
4883 [(set (match_operand:X87MODEF 0 "register_operand" "")
4884 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4887 || TARGET_MIX_SSE_I387)")
4889 ;; Pre-reload splitter to add memory clobber to the pattern.
4890 (define_insn_and_split "*floathi<mode>2_1"
4891 [(set (match_operand:X87MODEF 0 "register_operand" "")
4892 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4895 || TARGET_MIX_SSE_I387)
4896 && can_create_pseudo_p ()"
4899 [(parallel [(set (match_dup 0)
4900 (float:X87MODEF (match_dup 1)))
4901 (clobber (match_dup 2))])]
4902 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4904 (define_insn "*floathi<mode>2_i387_with_temp"
4905 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4906 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4907 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4910 || TARGET_MIX_SSE_I387)"
4912 [(set_attr "type" "fmov,multi")
4913 (set_attr "mode" "<MODE>")
4914 (set_attr "unit" "*,i387")
4915 (set_attr "fp_int_src" "true")])
4917 (define_insn "*floathi<mode>2_i387"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4919 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4922 || TARGET_MIX_SSE_I387)"
4924 [(set_attr "type" "fmov")
4925 (set_attr "mode" "<MODE>")
4926 (set_attr "fp_int_src" "true")])
4929 [(set (match_operand:X87MODEF 0 "register_operand" "")
4930 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4931 (clobber (match_operand:HI 2 "memory_operand" ""))]
4933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4934 || TARGET_MIX_SSE_I387)
4935 && reload_completed"
4936 [(set (match_dup 2) (match_dup 1))
4937 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4940 [(set (match_operand:X87MODEF 0 "register_operand" "")
4941 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4942 (clobber (match_operand:HI 2 "memory_operand" ""))]
4944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4945 || TARGET_MIX_SSE_I387)
4946 && reload_completed"
4947 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4949 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4950 [(set (match_operand:X87MODEF 0 "register_operand" "")
4952 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4954 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4955 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4957 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4958 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4959 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4961 rtx reg = gen_reg_rtx (XFmode);
4964 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4966 if (<X87MODEF:MODE>mode == SFmode)
4967 insn = gen_truncxfsf2 (operands[0], reg);
4968 else if (<X87MODEF:MODE>mode == DFmode)
4969 insn = gen_truncxfdf2 (operands[0], reg);
4978 ;; Pre-reload splitter to add memory clobber to the pattern.
4979 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4980 [(set (match_operand:X87MODEF 0 "register_operand" "")
4981 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4983 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4984 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4985 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4986 || TARGET_MIX_SSE_I387))
4987 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4988 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4989 && ((<SSEMODEI24:MODE>mode == SImode
4990 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4991 && optimize_function_for_speed_p (cfun)
4992 && flag_trapping_math)
4993 || !(TARGET_INTER_UNIT_CONVERSIONS
4994 || optimize_function_for_size_p (cfun)))))
4995 && can_create_pseudo_p ()"
4998 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4999 (clobber (match_dup 2))])]
5001 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5003 /* Avoid store forwarding (partial memory) stall penalty
5004 by passing DImode value through XMM registers. */
5005 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5006 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5007 && optimize_function_for_speed_p (cfun))
5009 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5016 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5017 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5019 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5020 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5021 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5022 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5024 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5025 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5026 (set_attr "unit" "*,i387,*,*,*")
5027 (set_attr "athlon_decode" "*,*,double,direct,double")
5028 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5029 (set_attr "bdver1_decode" "*,*,double,direct,double")
5030 (set_attr "fp_int_src" "true")])
5032 (define_insn "*floatsi<mode>2_vector_mixed"
5033 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5034 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5035 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5036 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5040 [(set_attr "type" "fmov,sseicvt")
5041 (set_attr "mode" "<MODE>,<ssevecmode>")
5042 (set_attr "unit" "i387,*")
5043 (set_attr "athlon_decode" "*,direct")
5044 (set_attr "amdfam10_decode" "*,double")
5045 (set_attr "bdver1_decode" "*,direct")
5046 (set_attr "fp_int_src" "true")])
5048 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5049 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5051 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5052 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5053 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5054 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5056 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5057 (set_attr "mode" "<MODEF:MODE>")
5058 (set_attr "unit" "*,i387,*,*")
5059 (set_attr "athlon_decode" "*,*,double,direct")
5060 (set_attr "amdfam10_decode" "*,*,vector,double")
5061 (set_attr "bdver1_decode" "*,*,double,direct")
5062 (set_attr "fp_int_src" "true")])
5065 [(set (match_operand:MODEF 0 "register_operand" "")
5066 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5067 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5068 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5069 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5070 && TARGET_INTER_UNIT_CONVERSIONS
5072 && (SSE_REG_P (operands[0])
5073 || (GET_CODE (operands[0]) == SUBREG
5074 && SSE_REG_P (operands[0])))"
5075 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5078 [(set (match_operand:MODEF 0 "register_operand" "")
5079 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5080 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5085 && (SSE_REG_P (operands[0])
5086 || (GET_CODE (operands[0]) == SUBREG
5087 && SSE_REG_P (operands[0])))"
5088 [(set (match_dup 2) (match_dup 1))
5089 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5091 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5092 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5094 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5095 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5096 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5097 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5100 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5101 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5102 [(set_attr "type" "fmov,sseicvt,sseicvt")
5103 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5104 (set_attr "mode" "<MODEF:MODE>")
5105 (set (attr "prefix_rex")
5107 (and (eq_attr "prefix" "maybe_vex")
5108 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5110 (const_string "*")))
5111 (set_attr "unit" "i387,*,*")
5112 (set_attr "athlon_decode" "*,double,direct")
5113 (set_attr "amdfam10_decode" "*,vector,double")
5114 (set_attr "bdver1_decode" "*,double,direct")
5115 (set_attr "fp_int_src" "true")])
5117 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5118 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5120 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5121 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5122 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5123 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5126 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5127 [(set_attr "type" "fmov,sseicvt")
5128 (set_attr "prefix" "orig,maybe_vex")
5129 (set_attr "mode" "<MODEF:MODE>")
5130 (set (attr "prefix_rex")
5132 (and (eq_attr "prefix" "maybe_vex")
5133 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5135 (const_string "*")))
5136 (set_attr "athlon_decode" "*,direct")
5137 (set_attr "amdfam10_decode" "*,double")
5138 (set_attr "bdver1_decode" "*,direct")
5139 (set_attr "fp_int_src" "true")])
5141 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5142 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5144 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5145 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5146 "TARGET_SSE2 && TARGET_SSE_MATH
5147 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5149 [(set_attr "type" "sseicvt")
5150 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5151 (set_attr "athlon_decode" "double,direct,double")
5152 (set_attr "amdfam10_decode" "vector,double,double")
5153 (set_attr "bdver1_decode" "double,direct,double")
5154 (set_attr "fp_int_src" "true")])
5156 (define_insn "*floatsi<mode>2_vector_sse"
5157 [(set (match_operand:MODEF 0 "register_operand" "=x")
5158 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5159 "TARGET_SSE2 && TARGET_SSE_MATH
5160 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5162 [(set_attr "type" "sseicvt")
5163 (set_attr "mode" "<MODE>")
5164 (set_attr "athlon_decode" "direct")
5165 (set_attr "amdfam10_decode" "double")
5166 (set_attr "bdver1_decode" "direct")
5167 (set_attr "fp_int_src" "true")])
5170 [(set (match_operand:MODEF 0 "register_operand" "")
5171 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5172 (clobber (match_operand:SI 2 "memory_operand" ""))]
5173 "TARGET_SSE2 && TARGET_SSE_MATH
5174 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5176 && (SSE_REG_P (operands[0])
5177 || (GET_CODE (operands[0]) == SUBREG
5178 && SSE_REG_P (operands[0])))"
5181 rtx op1 = operands[1];
5183 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5185 if (GET_CODE (op1) == SUBREG)
5186 op1 = SUBREG_REG (op1);
5188 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5190 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5191 emit_insn (gen_sse2_loadld (operands[4],
5192 CONST0_RTX (V4SImode), operands[1]));
5194 /* We can ignore possible trapping value in the
5195 high part of SSE register for non-trapping math. */
5196 else if (SSE_REG_P (op1) && !flag_trapping_math)
5197 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5200 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5201 emit_move_insn (operands[2], operands[1]);
5202 emit_insn (gen_sse2_loadld (operands[4],
5203 CONST0_RTX (V4SImode), operands[2]));
5206 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5211 [(set (match_operand:MODEF 0 "register_operand" "")
5212 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5213 (clobber (match_operand:SI 2 "memory_operand" ""))]
5214 "TARGET_SSE2 && TARGET_SSE_MATH
5215 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (operands[0])))"
5222 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5224 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5226 emit_insn (gen_sse2_loadld (operands[4],
5227 CONST0_RTX (V4SImode), operands[1]));
5229 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5234 [(set (match_operand:MODEF 0 "register_operand" "")
5235 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5236 "TARGET_SSE2 && TARGET_SSE_MATH
5237 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5239 && (SSE_REG_P (operands[0])
5240 || (GET_CODE (operands[0]) == SUBREG
5241 && SSE_REG_P (operands[0])))"
5244 rtx op1 = operands[1];
5246 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5248 if (GET_CODE (op1) == SUBREG)
5249 op1 = SUBREG_REG (op1);
5251 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5253 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5254 emit_insn (gen_sse2_loadld (operands[4],
5255 CONST0_RTX (V4SImode), operands[1]));
5257 /* We can ignore possible trapping value in the
5258 high part of SSE register for non-trapping math. */
5259 else if (SSE_REG_P (op1) && !flag_trapping_math)
5260 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5264 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5269 [(set (match_operand:MODEF 0 "register_operand" "")
5270 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5271 "TARGET_SSE2 && TARGET_SSE_MATH
5272 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5274 && (SSE_REG_P (operands[0])
5275 || (GET_CODE (operands[0]) == SUBREG
5276 && SSE_REG_P (operands[0])))"
5279 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5281 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5283 emit_insn (gen_sse2_loadld (operands[4],
5284 CONST0_RTX (V4SImode), operands[1]));
5286 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5290 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5291 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5293 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5294 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5295 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5296 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5298 [(set_attr "type" "sseicvt")
5299 (set_attr "mode" "<MODEF:MODE>")
5300 (set_attr "athlon_decode" "double,direct")
5301 (set_attr "amdfam10_decode" "vector,double")
5302 (set_attr "bdver1_decode" "double,direct")
5303 (set_attr "fp_int_src" "true")])
5305 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5306 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5308 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5309 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5310 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5311 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5312 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5313 [(set_attr "type" "sseicvt")
5314 (set_attr "prefix" "maybe_vex")
5315 (set_attr "mode" "<MODEF:MODE>")
5316 (set (attr "prefix_rex")
5318 (and (eq_attr "prefix" "maybe_vex")
5319 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5321 (const_string "*")))
5322 (set_attr "athlon_decode" "double,direct")
5323 (set_attr "amdfam10_decode" "vector,double")
5324 (set_attr "bdver1_decode" "double,direct")
5325 (set_attr "fp_int_src" "true")])
5328 [(set (match_operand:MODEF 0 "register_operand" "")
5329 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5330 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5331 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5332 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5333 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5335 && (SSE_REG_P (operands[0])
5336 || (GET_CODE (operands[0]) == SUBREG
5337 && SSE_REG_P (operands[0])))"
5338 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5340 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5341 [(set (match_operand:MODEF 0 "register_operand" "=x")
5343 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5344 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5345 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5346 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5347 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5348 [(set_attr "type" "sseicvt")
5349 (set_attr "prefix" "maybe_vex")
5350 (set_attr "mode" "<MODEF:MODE>")
5351 (set (attr "prefix_rex")
5353 (and (eq_attr "prefix" "maybe_vex")
5354 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5356 (const_string "*")))
5357 (set_attr "athlon_decode" "direct")
5358 (set_attr "amdfam10_decode" "double")
5359 (set_attr "bdver1_decode" "direct")
5360 (set_attr "fp_int_src" "true")])
5363 [(set (match_operand:MODEF 0 "register_operand" "")
5364 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5365 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5366 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5368 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5373 [(set (match_dup 2) (match_dup 1))
5374 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5377 [(set (match_operand:MODEF 0 "register_operand" "")
5378 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5379 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5381 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5383 && (SSE_REG_P (operands[0])
5384 || (GET_CODE (operands[0]) == SUBREG
5385 && SSE_REG_P (operands[0])))"
5386 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5388 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5389 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5391 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5392 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5394 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5398 [(set_attr "type" "fmov,multi")
5399 (set_attr "mode" "<X87MODEF:MODE>")
5400 (set_attr "unit" "*,i387")
5401 (set_attr "fp_int_src" "true")])
5403 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5404 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5406 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5408 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5410 [(set_attr "type" "fmov")
5411 (set_attr "mode" "<X87MODEF:MODE>")
5412 (set_attr "fp_int_src" "true")])
5415 [(set (match_operand:X87MODEF 0 "register_operand" "")
5416 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5417 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5419 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5421 && FP_REG_P (operands[0])"
5422 [(set (match_dup 2) (match_dup 1))
5423 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5426 [(set (match_operand:X87MODEF 0 "register_operand" "")
5427 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5428 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5430 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5432 && FP_REG_P (operands[0])"
5433 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5435 ;; Avoid store forwarding (partial memory) stall penalty
5436 ;; by passing DImode value through XMM registers. */
5438 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5439 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5441 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5442 (clobber (match_scratch:V4SI 3 "=X,x"))
5443 (clobber (match_scratch:V4SI 4 "=X,x"))
5444 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5445 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5446 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5447 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5449 [(set_attr "type" "multi")
5450 (set_attr "mode" "<X87MODEF:MODE>")
5451 (set_attr "unit" "i387")
5452 (set_attr "fp_int_src" "true")])
5455 [(set (match_operand:X87MODEF 0 "register_operand" "")
5456 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5457 (clobber (match_scratch:V4SI 3 ""))
5458 (clobber (match_scratch:V4SI 4 ""))
5459 (clobber (match_operand:DI 2 "memory_operand" ""))]
5460 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5462 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5464 && FP_REG_P (operands[0])"
5465 [(set (match_dup 2) (match_dup 3))
5466 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5468 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5469 Assemble the 64-bit DImode value in an xmm register. */
5470 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5471 gen_rtx_SUBREG (SImode, operands[1], 0)));
5472 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5473 gen_rtx_SUBREG (SImode, operands[1], 4)));
5474 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5477 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5481 [(set (match_operand:X87MODEF 0 "register_operand" "")
5482 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5483 (clobber (match_scratch:V4SI 3 ""))
5484 (clobber (match_scratch:V4SI 4 ""))
5485 (clobber (match_operand:DI 2 "memory_operand" ""))]
5486 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5487 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5488 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5490 && FP_REG_P (operands[0])"
5491 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5493 ;; Avoid store forwarding (partial memory) stall penalty by extending
5494 ;; SImode value to DImode through XMM register instead of pushing two
5495 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5496 ;; targets benefit from this optimization. Also note that fild
5497 ;; loads from memory only.
5499 (define_insn "*floatunssi<mode>2_1"
5500 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5501 (unsigned_float:X87MODEF
5502 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5503 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5504 (clobber (match_scratch:SI 3 "=X,x"))]
5506 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5509 [(set_attr "type" "multi")
5510 (set_attr "mode" "<MODE>")])
5513 [(set (match_operand:X87MODEF 0 "register_operand" "")
5514 (unsigned_float:X87MODEF
5515 (match_operand:SI 1 "register_operand" "")))
5516 (clobber (match_operand:DI 2 "memory_operand" ""))
5517 (clobber (match_scratch:SI 3 ""))]
5519 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5521 && reload_completed"
5522 [(set (match_dup 2) (match_dup 1))
5524 (float:X87MODEF (match_dup 2)))]
5525 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5528 [(set (match_operand:X87MODEF 0 "register_operand" "")
5529 (unsigned_float:X87MODEF
5530 (match_operand:SI 1 "memory_operand" "")))
5531 (clobber (match_operand:DI 2 "memory_operand" ""))
5532 (clobber (match_scratch:SI 3 ""))]
5534 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5536 && reload_completed"
5537 [(set (match_dup 2) (match_dup 3))
5539 (float:X87MODEF (match_dup 2)))]
5541 emit_move_insn (operands[3], operands[1]);
5542 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5545 (define_expand "floatunssi<mode>2"
5547 [(set (match_operand:X87MODEF 0 "register_operand" "")
5548 (unsigned_float:X87MODEF
5549 (match_operand:SI 1 "nonimmediate_operand" "")))
5550 (clobber (match_dup 2))
5551 (clobber (match_scratch:SI 3 ""))])]
5553 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5555 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5557 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5559 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5564 enum ix86_stack_slot slot = (virtuals_instantiated
5567 operands[2] = assign_386_stack_local (DImode, slot);
5571 (define_expand "floatunsdisf2"
5572 [(use (match_operand:SF 0 "register_operand" ""))
5573 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5574 "TARGET_64BIT && TARGET_SSE_MATH"
5575 "x86_emit_floatuns (operands); DONE;")
5577 (define_expand "floatunsdidf2"
5578 [(use (match_operand:DF 0 "register_operand" ""))
5579 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5580 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5581 && TARGET_SSE2 && TARGET_SSE_MATH"
5584 x86_emit_floatuns (operands);
5586 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5592 (define_expand "add<mode>3"
5593 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5594 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5595 (match_operand:SDWIM 2 "<general_operand>" "")))]
5597 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5599 (define_insn_and_split "*add<dwi>3_doubleword"
5600 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5602 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5603 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5604 (clobber (reg:CC FLAGS_REG))]
5605 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5608 [(parallel [(set (reg:CC FLAGS_REG)
5609 (unspec:CC [(match_dup 1) (match_dup 2)]
5612 (plus:DWIH (match_dup 1) (match_dup 2)))])
5613 (parallel [(set (match_dup 3)
5617 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5619 (clobber (reg:CC FLAGS_REG))])]
5620 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5622 (define_insn "*add<mode>3_cc"
5623 [(set (reg:CC FLAGS_REG)
5625 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5626 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5628 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5629 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5630 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5631 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5632 [(set_attr "type" "alu")
5633 (set_attr "mode" "<MODE>")])
5635 (define_insn "addqi3_cc"
5636 [(set (reg:CC FLAGS_REG)
5638 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5639 (match_operand:QI 2 "general_operand" "qn,qm")]
5641 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5642 (plus:QI (match_dup 1) (match_dup 2)))]
5643 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5644 "add{b}\t{%2, %0|%0, %2}"
5645 [(set_attr "type" "alu")
5646 (set_attr "mode" "QI")])
5648 (define_insn "*lea_1"
5649 [(set (match_operand:P 0 "register_operand" "=r")
5650 (match_operand:P 1 "no_seg_address_operand" "p"))]
5652 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5653 [(set_attr "type" "lea")
5654 (set_attr "mode" "<MODE>")])
5656 (define_insn "*lea_2"
5657 [(set (match_operand:SI 0 "register_operand" "=r")
5658 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5660 "lea{l}\t{%a1, %0|%0, %a1}"
5661 [(set_attr "type" "lea")
5662 (set_attr "mode" "SI")])
5664 (define_insn "*lea_2_zext"
5665 [(set (match_operand:DI 0 "register_operand" "=r")
5667 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5669 "lea{l}\t{%a1, %k0|%k0, %a1}"
5670 [(set_attr "type" "lea")
5671 (set_attr "mode" "SI")])
5673 (define_insn "*add<mode>_1"
5674 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5676 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5677 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5678 (clobber (reg:CC FLAGS_REG))]
5679 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5681 switch (get_attr_type (insn))
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (operands[2] == const1_rtx)
5689 return "inc{<imodesuffix>}\t%0";
5692 gcc_assert (operands[2] == constm1_rtx);
5693 return "dec{<imodesuffix>}\t%0";
5697 /* For most processors, ADD is faster than LEA. This alternative
5698 was added to use ADD as much as possible. */
5699 if (which_alternative == 2)
5702 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5707 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5709 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5713 (cond [(eq_attr "alternative" "3")
5714 (const_string "lea")
5715 (match_operand:SWI48 2 "incdec_operand" "")
5716 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723 (const_string "*")))
5724 (set_attr "mode" "<MODE>")])
5726 ;; It may seem that nonimmediate operand is proper one for operand 1.
5727 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5728 ;; we take care in ix86_binary_operator_ok to not allow two memory
5729 ;; operands so proper swapping will be done in reload. This allow
5730 ;; patterns constructed from addsi_1 to match.
5732 (define_insn "*addsi_1_zext"
5733 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5735 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5736 (match_operand:SI 2 "general_operand" "g,0,li"))))
5737 (clobber (reg:CC FLAGS_REG))]
5738 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5740 switch (get_attr_type (insn))
5746 if (operands[2] == const1_rtx)
5747 return "inc{l}\t%k0";
5750 gcc_assert (operands[2] == constm1_rtx);
5751 return "dec{l}\t%k0";
5755 /* For most processors, ADD is faster than LEA. This alternative
5756 was added to use ADD as much as possible. */
5757 if (which_alternative == 1)
5760 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5763 if (x86_maybe_negate_const_int (&operands[2], SImode))
5764 return "sub{l}\t{%2, %k0|%k0, %2}";
5766 return "add{l}\t{%2, %k0|%k0, %2}";
5770 (cond [(eq_attr "alternative" "2")
5771 (const_string "lea")
5772 (match_operand:SI 2 "incdec_operand" "")
5773 (const_string "incdec")
5775 (const_string "alu")))
5776 (set (attr "length_immediate")
5778 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5780 (const_string "*")))
5781 (set_attr "mode" "SI")])
5783 (define_insn "*addhi_1"
5784 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5785 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5786 (match_operand:HI 2 "general_operand" "rn,rm")))
5787 (clobber (reg:CC FLAGS_REG))]
5788 "TARGET_PARTIAL_REG_STALL
5789 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5791 switch (get_attr_type (insn))
5794 if (operands[2] == const1_rtx)
5795 return "inc{w}\t%0";
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{w}\t%0";
5803 if (x86_maybe_negate_const_int (&operands[2], HImode))
5804 return "sub{w}\t{%2, %0|%0, %2}";
5806 return "add{w}\t{%2, %0|%0, %2}";
5810 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5811 (const_string "incdec")
5812 (const_string "alu")))
5813 (set (attr "length_immediate")
5815 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5817 (const_string "*")))
5818 (set_attr "mode" "HI")])
5820 (define_insn "*addhi_1_lea"
5821 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5822 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5823 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5824 (clobber (reg:CC FLAGS_REG))]
5825 "!TARGET_PARTIAL_REG_STALL
5826 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5828 switch (get_attr_type (insn))
5834 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5844 /* For most processors, ADD is faster than LEA. This alternative
5845 was added to use ADD as much as possible. */
5846 if (which_alternative == 2)
5849 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5852 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853 if (x86_maybe_negate_const_int (&operands[2], HImode))
5854 return "sub{w}\t{%2, %0|%0, %2}";
5856 return "add{w}\t{%2, %0|%0, %2}";
5860 (cond [(eq_attr "alternative" "3")
5861 (const_string "lea")
5862 (match_operand:HI 2 "incdec_operand" "")
5863 (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" "HI,HI,HI,SI")])
5873 ;; %%% Potential partial reg stall on alternative 2. What to do?
5874 (define_insn "*addqi_1"
5875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5877 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5882 int widen = (which_alternative == 2);
5883 switch (get_attr_type (insn))
5886 if (operands[2] == const1_rtx)
5887 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5890 gcc_assert (operands[2] == constm1_rtx);
5891 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5895 if (x86_maybe_negate_const_int (&operands[2], QImode))
5898 return "sub{l}\t{%2, %k0|%k0, %2}";
5900 return "sub{b}\t{%2, %0|%0, %2}";
5903 return "add{l}\t{%k2, %k0|%k0, %k2}";
5905 return "add{b}\t{%2, %0|%0, %2}";
5909 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5910 (const_string "incdec")
5911 (const_string "alu")))
5912 (set (attr "length_immediate")
5914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916 (const_string "*")))
5917 (set_attr "mode" "QI,QI,SI")])
5919 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5920 (define_insn "*addqi_1_lea"
5921 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5922 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5923 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5924 (clobber (reg:CC FLAGS_REG))]
5925 "!TARGET_PARTIAL_REG_STALL
5926 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5928 int widen = (which_alternative == 3 || which_alternative == 4);
5930 switch (get_attr_type (insn))
5936 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5937 if (operands[2] == const1_rtx)
5938 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5946 /* For most processors, ADD is faster than LEA. These alternatives
5947 were added to use ADD as much as possible. */
5948 if (which_alternative == 2 || which_alternative == 4)
5951 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5955 if (x86_maybe_negate_const_int (&operands[2], QImode))
5958 return "sub{l}\t{%2, %k0|%k0, %2}";
5960 return "sub{b}\t{%2, %0|%0, %2}";
5963 return "add{l}\t{%k2, %k0|%k0, %k2}";
5965 return "add{b}\t{%2, %0|%0, %2}";
5969 (cond [(eq_attr "alternative" "5")
5970 (const_string "lea")
5971 (match_operand:QI 2 "incdec_operand" "")
5972 (const_string "incdec")
5974 (const_string "alu")))
5975 (set (attr "length_immediate")
5977 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5979 (const_string "*")))
5980 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5982 (define_insn "*addqi_1_slp"
5983 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5984 (plus:QI (match_dup 0)
5985 (match_operand:QI 1 "general_operand" "qn,qnm")))
5986 (clobber (reg:CC FLAGS_REG))]
5987 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5988 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5990 switch (get_attr_type (insn))
5993 if (operands[1] == const1_rtx)
5994 return "inc{b}\t%0";
5997 gcc_assert (operands[1] == constm1_rtx);
5998 return "dec{b}\t%0";
6002 if (x86_maybe_negate_const_int (&operands[1], QImode))
6003 return "sub{b}\t{%1, %0|%0, %1}";
6005 return "add{b}\t{%1, %0|%0, %1}";
6009 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6010 (const_string "incdec")
6011 (const_string "alu1")))
6012 (set (attr "memory")
6013 (if_then_else (match_operand 1 "memory_operand" "")
6014 (const_string "load")
6015 (const_string "none")))
6016 (set_attr "mode" "QI")])
6018 ;; Convert lea to the lea pattern to avoid flags dependency.
6020 [(set (match_operand 0 "register_operand" "")
6021 (plus (match_operand 1 "register_operand" "")
6022 (match_operand 2 "nonmemory_operand" "")))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6028 enum machine_mode mode = GET_MODE (operands[0]);
6030 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6031 may confuse gen_lowpart. */
6034 operands[1] = gen_lowpart (Pmode, operands[1]);
6035 operands[2] = gen_lowpart (Pmode, operands[2]);
6038 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6040 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6041 operands[0] = gen_lowpart (SImode, operands[0]);
6043 if (TARGET_64BIT && mode != Pmode)
6044 pat = gen_rtx_SUBREG (SImode, pat, 0);
6046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6050 ;; Convert lea to the lea pattern to avoid flags dependency.
6051 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6052 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6054 [(set (match_operand:DI 0 "register_operand" "")
6055 (plus:DI (match_operand:DI 1 "register_operand" "")
6056 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6057 (clobber (reg:CC FLAGS_REG))]
6058 "TARGET_64BIT && reload_completed
6059 && true_regnum (operands[0]) != true_regnum (operands[1])"
6061 (plus:DI (match_dup 1) (match_dup 2)))])
6063 ;; Convert lea to the lea pattern to avoid flags dependency.
6065 [(set (match_operand:DI 0 "register_operand" "")
6067 (plus:SI (match_operand:SI 1 "register_operand" "")
6068 (match_operand:SI 2 "nonmemory_operand" ""))))
6069 (clobber (reg:CC FLAGS_REG))]
6070 "TARGET_64BIT && reload_completed
6071 && ix86_lea_for_add_ok (insn, operands)"
6073 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6075 operands[1] = gen_lowpart (DImode, operands[1]);
6076 operands[2] = gen_lowpart (DImode, operands[2]);
6079 (define_insn "*add<mode>_2"
6080 [(set (reg FLAGS_REG)
6083 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6084 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6086 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6087 (plus:SWI (match_dup 1) (match_dup 2)))]
6088 "ix86_match_ccmode (insn, CCGOCmode)
6089 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6091 switch (get_attr_type (insn))
6094 if (operands[2] == const1_rtx)
6095 return "inc{<imodesuffix>}\t%0";
6098 gcc_assert (operands[2] == constm1_rtx);
6099 return "dec{<imodesuffix>}\t%0";
6103 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6104 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6106 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6110 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6111 (const_string "incdec")
6112 (const_string "alu")))
6113 (set (attr "length_immediate")
6115 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6117 (const_string "*")))
6118 (set_attr "mode" "<MODE>")])
6120 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6121 (define_insn "*addsi_2_zext"
6122 [(set (reg FLAGS_REG)
6124 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6125 (match_operand:SI 2 "general_operand" "g"))
6127 (set (match_operand:DI 0 "register_operand" "=r")
6128 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6129 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6130 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6132 switch (get_attr_type (insn))
6135 if (operands[2] == const1_rtx)
6136 return "inc{l}\t%k0";
6139 gcc_assert (operands[2] == constm1_rtx);
6140 return "dec{l}\t%k0";
6144 if (x86_maybe_negate_const_int (&operands[2], SImode))
6145 return "sub{l}\t{%2, %k0|%k0, %2}";
6147 return "add{l}\t{%2, %k0|%k0, %2}";
6151 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6158 (const_string "*")))
6159 (set_attr "mode" "SI")])
6161 (define_insn "*add<mode>_3"
6162 [(set (reg FLAGS_REG)
6164 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6165 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6166 (clobber (match_scratch:SWI 0 "=<r>"))]
6167 "ix86_match_ccmode (insn, CCZmode)
6168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6170 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{<imodesuffix>}\t%0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{<imodesuffix>}\t%0";
6182 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6183 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6185 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6189 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu")))
6192 (set (attr "length_immediate")
6194 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6196 (const_string "*")))
6197 (set_attr "mode" "<MODE>")])
6199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6200 (define_insn "*addsi_3_zext"
6201 [(set (reg FLAGS_REG)
6203 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6204 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6205 (set (match_operand:DI 0 "register_operand" "=r")
6206 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6207 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6208 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6210 switch (get_attr_type (insn))
6213 if (operands[2] == const1_rtx)
6214 return "inc{l}\t%k0";
6217 gcc_assert (operands[2] == constm1_rtx);
6218 return "dec{l}\t%k0";
6222 if (x86_maybe_negate_const_int (&operands[2], SImode))
6223 return "sub{l}\t{%2, %k0|%k0, %2}";
6225 return "add{l}\t{%2, %k0|%k0, %2}";
6229 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu")))
6232 (set (attr "length_immediate")
6234 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6236 (const_string "*")))
6237 (set_attr "mode" "SI")])
6239 ; For comparisons against 1, -1 and 128, we may generate better code
6240 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6241 ; is matched then. We can't accept general immediate, because for
6242 ; case of overflows, the result is messed up.
6243 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6244 ; only for comparisons not depending on it.
6246 (define_insn "*adddi_4"
6247 [(set (reg FLAGS_REG)
6249 (match_operand:DI 1 "nonimmediate_operand" "0")
6250 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6251 (clobber (match_scratch:DI 0 "=rm"))]
6253 && ix86_match_ccmode (insn, CCGCmode)"
6255 switch (get_attr_type (insn))
6258 if (operands[2] == constm1_rtx)
6259 return "inc{q}\t%0";
6262 gcc_assert (operands[2] == const1_rtx);
6263 return "dec{q}\t%0";
6267 if (x86_maybe_negate_const_int (&operands[2], DImode))
6268 return "add{q}\t{%2, %0|%0, %2}";
6270 return "sub{q}\t{%2, %0|%0, %2}";
6274 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6275 (const_string "incdec")
6276 (const_string "alu")))
6277 (set (attr "length_immediate")
6279 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6281 (const_string "*")))
6282 (set_attr "mode" "DI")])
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6286 ; is matched then. We can't accept general immediate, because for
6287 ; case of overflows, the result is messed up.
6288 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6289 ; only for comparisons not depending on it.
6291 (define_insn "*add<mode>_4"
6292 [(set (reg FLAGS_REG)
6294 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6295 (match_operand:SWI124 2 "const_int_operand" "n")))
6296 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6297 "ix86_match_ccmode (insn, CCGCmode)"
6299 switch (get_attr_type (insn))
6302 if (operands[2] == constm1_rtx)
6303 return "inc{<imodesuffix>}\t%0";
6306 gcc_assert (operands[2] == const1_rtx);
6307 return "dec{<imodesuffix>}\t%0";
6311 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6312 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6314 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6318 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6319 (const_string "incdec")
6320 (const_string "alu")))
6321 (set (attr "length_immediate")
6323 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6325 (const_string "*")))
6326 (set_attr "mode" "<MODE>")])
6328 (define_insn "*add<mode>_5"
6329 [(set (reg FLAGS_REG)
6332 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6333 (match_operand:SWI 2 "<general_operand>" "<g>"))
6335 (clobber (match_scratch:SWI 0 "=<r>"))]
6336 "ix86_match_ccmode (insn, CCGOCmode)
6337 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6339 switch (get_attr_type (insn))
6342 if (operands[2] == const1_rtx)
6343 return "inc{<imodesuffix>}\t%0";
6346 gcc_assert (operands[2] == constm1_rtx);
6347 return "dec{<imodesuffix>}\t%0";
6351 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6352 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6354 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6358 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set (attr "length_immediate")
6363 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6365 (const_string "*")))
6366 (set_attr "mode" "<MODE>")])
6368 (define_insn "*addqi_ext_1_rex64"
6369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6374 (match_operand 1 "ext_register_operand" "0")
6377 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6378 (clobber (reg:CC FLAGS_REG))]
6381 switch (get_attr_type (insn))
6384 if (operands[2] == const1_rtx)
6385 return "inc{b}\t%h0";
6388 gcc_assert (operands[2] == constm1_rtx);
6389 return "dec{b}\t%h0";
6393 return "add{b}\t{%2, %h0|%h0, %2}";
6397 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6398 (const_string "incdec")
6399 (const_string "alu")))
6400 (set_attr "modrm" "1")
6401 (set_attr "mode" "QI")])
6403 (define_insn "addqi_ext_1"
6404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6409 (match_operand 1 "ext_register_operand" "0")
6412 (match_operand:QI 2 "general_operand" "Qmn")))
6413 (clobber (reg:CC FLAGS_REG))]
6416 switch (get_attr_type (insn))
6419 if (operands[2] == const1_rtx)
6420 return "inc{b}\t%h0";
6423 gcc_assert (operands[2] == constm1_rtx);
6424 return "dec{b}\t%h0";
6428 return "add{b}\t{%2, %h0|%h0, %2}";
6432 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6433 (const_string "incdec")
6434 (const_string "alu")))
6435 (set_attr "modrm" "1")
6436 (set_attr "mode" "QI")])
6438 (define_insn "*addqi_ext_2"
6439 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6444 (match_operand 1 "ext_register_operand" "%0")
6448 (match_operand 2 "ext_register_operand" "Q")
6451 (clobber (reg:CC FLAGS_REG))]
6453 "add{b}\t{%h2, %h0|%h0, %h2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "mode" "QI")])
6457 ;; The lea patterns for non-Pmodes needs to be matched by
6458 ;; several insns converted to real lea by splitters.
6460 (define_insn_and_split "*lea_general_1"
6461 [(set (match_operand 0 "register_operand" "=r")
6462 (plus (plus (match_operand 1 "index_register_operand" "l")
6463 (match_operand 2 "register_operand" "r"))
6464 (match_operand 3 "immediate_operand" "i")))]
6465 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6466 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6467 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6468 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6469 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6470 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6471 || GET_MODE (operands[3]) == VOIDmode)"
6473 "&& reload_completed"
6477 operands[0] = gen_lowpart (SImode, operands[0]);
6478 operands[1] = gen_lowpart (Pmode, operands[1]);
6479 operands[2] = gen_lowpart (Pmode, operands[2]);
6480 operands[3] = gen_lowpart (Pmode, operands[3]);
6481 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6483 if (Pmode != SImode)
6484 pat = gen_rtx_SUBREG (SImode, pat, 0);
6485 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6488 [(set_attr "type" "lea")
6489 (set_attr "mode" "SI")])
6491 (define_insn_and_split "*lea_general_1_zext"
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6495 (match_operand:SI 1 "index_register_operand" "l")
6496 (match_operand:SI 2 "register_operand" "r"))
6497 (match_operand:SI 3 "immediate_operand" "i"))))]
6500 "&& reload_completed"
6502 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6504 (match_dup 3)) 0)))]
6506 operands[1] = gen_lowpart (Pmode, operands[1]);
6507 operands[2] = gen_lowpart (Pmode, operands[2]);
6508 operands[3] = gen_lowpart (Pmode, operands[3]);
6510 [(set_attr "type" "lea")
6511 (set_attr "mode" "SI")])
6513 (define_insn_and_split "*lea_general_2"
6514 [(set (match_operand 0 "register_operand" "=r")
6515 (plus (mult (match_operand 1 "index_register_operand" "l")
6516 (match_operand 2 "const248_operand" "i"))
6517 (match_operand 3 "nonmemory_operand" "ri")))]
6518 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6519 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6520 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6521 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6522 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6523 || GET_MODE (operands[3]) == VOIDmode)"
6525 "&& reload_completed"
6529 operands[0] = gen_lowpart (SImode, operands[0]);
6530 operands[1] = gen_lowpart (Pmode, operands[1]);
6531 operands[3] = gen_lowpart (Pmode, operands[3]);
6532 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6534 if (Pmode != SImode)
6535 pat = gen_rtx_SUBREG (SImode, pat, 0);
6536 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6539 [(set_attr "type" "lea")
6540 (set_attr "mode" "SI")])
6542 (define_insn_and_split "*lea_general_2_zext"
6543 [(set (match_operand:DI 0 "register_operand" "=r")
6546 (match_operand:SI 1 "index_register_operand" "l")
6547 (match_operand:SI 2 "const248_operand" "n"))
6548 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6551 "&& reload_completed"
6553 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6555 (match_dup 3)) 0)))]
6557 operands[1] = gen_lowpart (Pmode, operands[1]);
6558 operands[3] = gen_lowpart (Pmode, operands[3]);
6560 [(set_attr "type" "lea")
6561 (set_attr "mode" "SI")])
6563 (define_insn_and_split "*lea_general_3"
6564 [(set (match_operand 0 "register_operand" "=r")
6565 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6566 (match_operand 2 "const248_operand" "i"))
6567 (match_operand 3 "register_operand" "r"))
6568 (match_operand 4 "immediate_operand" "i")))]
6569 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6570 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6571 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6572 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6573 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6575 "&& reload_completed"
6579 operands[0] = gen_lowpart (SImode, operands[0]);
6580 operands[1] = gen_lowpart (Pmode, operands[1]);
6581 operands[3] = gen_lowpart (Pmode, operands[3]);
6582 operands[4] = gen_lowpart (Pmode, operands[4]);
6583 pat = gen_rtx_PLUS (Pmode,
6584 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6588 if (Pmode != SImode)
6589 pat = gen_rtx_SUBREG (SImode, pat, 0);
6590 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6593 [(set_attr "type" "lea")
6594 (set_attr "mode" "SI")])
6596 (define_insn_and_split "*lea_general_3_zext"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6601 (match_operand:SI 1 "index_register_operand" "l")
6602 (match_operand:SI 2 "const248_operand" "n"))
6603 (match_operand:SI 3 "register_operand" "r"))
6604 (match_operand:SI 4 "immediate_operand" "i"))))]
6607 "&& reload_completed"
6609 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6612 (match_dup 4)) 0)))]
6614 operands[1] = gen_lowpart (Pmode, operands[1]);
6615 operands[3] = gen_lowpart (Pmode, operands[3]);
6616 operands[4] = gen_lowpart (Pmode, operands[4]);
6618 [(set_attr "type" "lea")
6619 (set_attr "mode" "SI")])
6621 ;; Subtract instructions
6623 (define_expand "sub<mode>3"
6624 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6625 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6626 (match_operand:SDWIM 2 "<general_operand>" "")))]
6628 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6630 (define_insn_and_split "*sub<dwi>3_doubleword"
6631 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6633 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6634 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6635 (clobber (reg:CC FLAGS_REG))]
6636 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6639 [(parallel [(set (reg:CC FLAGS_REG)
6640 (compare:CC (match_dup 1) (match_dup 2)))
6642 (minus:DWIH (match_dup 1) (match_dup 2)))])
6643 (parallel [(set (match_dup 3)
6647 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6649 (clobber (reg:CC FLAGS_REG))])]
6650 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6652 (define_insn "*sub<mode>_1"
6653 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6655 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6656 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6657 (clobber (reg:CC FLAGS_REG))]
6658 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6659 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6660 [(set_attr "type" "alu")
6661 (set_attr "mode" "<MODE>")])
6663 (define_insn "*subsi_1_zext"
6664 [(set (match_operand:DI 0 "register_operand" "=r")
6666 (minus:SI (match_operand:SI 1 "register_operand" "0")
6667 (match_operand:SI 2 "general_operand" "g"))))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6670 "sub{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "SI")])
6674 (define_insn "*subqi_1_slp"
6675 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6676 (minus:QI (match_dup 0)
6677 (match_operand:QI 1 "general_operand" "qn,qm")))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6680 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6681 "sub{b}\t{%1, %0|%0, %1}"
6682 [(set_attr "type" "alu1")
6683 (set_attr "mode" "QI")])
6685 (define_insn "*sub<mode>_2"
6686 [(set (reg FLAGS_REG)
6689 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6690 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6692 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6693 (minus:SWI (match_dup 1) (match_dup 2)))]
6694 "ix86_match_ccmode (insn, CCGOCmode)
6695 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6696 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6697 [(set_attr "type" "alu")
6698 (set_attr "mode" "<MODE>")])
6700 (define_insn "*subsi_2_zext"
6701 [(set (reg FLAGS_REG)
6703 (minus:SI (match_operand:SI 1 "register_operand" "0")
6704 (match_operand:SI 2 "general_operand" "g"))
6706 (set (match_operand:DI 0 "register_operand" "=r")
6708 (minus:SI (match_dup 1)
6710 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6711 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712 "sub{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "mode" "SI")])
6716 (define_insn "*sub<mode>_3"
6717 [(set (reg FLAGS_REG)
6718 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6719 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6720 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6721 (minus:SWI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCmode)
6723 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6724 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6728 (define_insn "*subsi_3_zext"
6729 [(set (reg FLAGS_REG)
6730 (compare (match_operand:SI 1 "register_operand" "0")
6731 (match_operand:SI 2 "general_operand" "g")))
6732 (set (match_operand:DI 0 "register_operand" "=r")
6734 (minus:SI (match_dup 1)
6736 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6737 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6738 "sub{l}\t{%2, %1|%1, %2}"
6739 [(set_attr "type" "alu")
6740 (set_attr "mode" "SI")])
6742 ;; Add with carry and subtract with borrow
6744 (define_expand "<plusminus_insn><mode>3_carry"
6746 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6748 (match_operand:SWI 1 "nonimmediate_operand" "")
6749 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6750 [(match_operand 3 "flags_reg_operand" "")
6752 (match_operand:SWI 2 "<general_operand>" ""))))
6753 (clobber (reg:CC FLAGS_REG))])]
6754 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6756 (define_insn "*<plusminus_insn><mode>3_carry"
6757 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6759 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6761 (match_operator 3 "ix86_carry_flag_operator"
6762 [(reg FLAGS_REG) (const_int 0)])
6763 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6764 (clobber (reg:CC FLAGS_REG))]
6765 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6766 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "use_carry" "1")
6769 (set_attr "pent_pair" "pu")
6770 (set_attr "mode" "<MODE>")])
6772 (define_insn "*addsi3_carry_zext"
6773 [(set (match_operand:DI 0 "register_operand" "=r")
6775 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6776 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6777 [(reg FLAGS_REG) (const_int 0)])
6778 (match_operand:SI 2 "general_operand" "g")))))
6779 (clobber (reg:CC FLAGS_REG))]
6780 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6781 "adc{l}\t{%2, %k0|%k0, %2}"
6782 [(set_attr "type" "alu")
6783 (set_attr "use_carry" "1")
6784 (set_attr "pent_pair" "pu")
6785 (set_attr "mode" "SI")])
6787 (define_insn "*subsi3_carry_zext"
6788 [(set (match_operand:DI 0 "register_operand" "=r")
6790 (minus:SI (match_operand:SI 1 "register_operand" "0")
6791 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6792 [(reg FLAGS_REG) (const_int 0)])
6793 (match_operand:SI 2 "general_operand" "g")))))
6794 (clobber (reg:CC FLAGS_REG))]
6795 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796 "sbb{l}\t{%2, %k0|%k0, %2}"
6797 [(set_attr "type" "alu")
6798 (set_attr "pent_pair" "pu")
6799 (set_attr "mode" "SI")])
6801 ;; Overflow setting add and subtract instructions
6803 (define_insn "*add<mode>3_cconly_overflow"
6804 [(set (reg:CCC FLAGS_REG)
6807 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6808 (match_operand:SWI 2 "<general_operand>" "<g>"))
6810 (clobber (match_scratch:SWI 0 "=<r>"))]
6811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6813 [(set_attr "type" "alu")
6814 (set_attr "mode" "<MODE>")])
6816 (define_insn "*sub<mode>3_cconly_overflow"
6817 [(set (reg:CCC FLAGS_REG)
6820 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6821 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6824 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6825 [(set_attr "type" "icmp")
6826 (set_attr "mode" "<MODE>")])
6828 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6829 [(set (reg:CCC FLAGS_REG)
6832 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6833 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6836 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6837 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6838 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "alu")
6840 (set_attr "mode" "<MODE>")])
6842 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6843 [(set (reg:CCC FLAGS_REG)
6846 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6847 (match_operand:SI 2 "general_operand" "g"))
6849 (set (match_operand:DI 0 "register_operand" "=r")
6850 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6851 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6852 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6853 [(set_attr "type" "alu")
6854 (set_attr "mode" "SI")])
6856 ;; The patterns that match these are at the end of this file.
6858 (define_expand "<plusminus_insn>xf3"
6859 [(set (match_operand:XF 0 "register_operand" "")
6861 (match_operand:XF 1 "register_operand" "")
6862 (match_operand:XF 2 "register_operand" "")))]
6865 (define_expand "<plusminus_insn><mode>3"
6866 [(set (match_operand:MODEF 0 "register_operand" "")
6868 (match_operand:MODEF 1 "register_operand" "")
6869 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6870 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6871 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6873 ;; Multiply instructions
6875 (define_expand "mul<mode>3"
6876 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6878 (match_operand:SWIM248 1 "register_operand" "")
6879 (match_operand:SWIM248 2 "<general_operand>" "")))
6880 (clobber (reg:CC FLAGS_REG))])])
6882 (define_expand "mulqi3"
6883 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6885 (match_operand:QI 1 "register_operand" "")
6886 (match_operand:QI 2 "nonimmediate_operand" "")))
6887 (clobber (reg:CC FLAGS_REG))])]
6888 "TARGET_QIMODE_MATH")
6891 ;; IMUL reg32/64, reg32/64, imm8 Direct
6892 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6893 ;; IMUL reg32/64, reg32/64, imm32 Direct
6894 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6895 ;; IMUL reg32/64, reg32/64 Direct
6896 ;; IMUL reg32/64, mem32/64 Direct
6898 ;; On BDVER1, all above IMULs use DirectPath
6900 (define_insn "*mul<mode>3_1"
6901 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6903 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6904 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6905 (clobber (reg:CC FLAGS_REG))]
6906 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6908 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6909 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6910 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6911 [(set_attr "type" "imul")
6912 (set_attr "prefix_0f" "0,0,1")
6913 (set (attr "athlon_decode")
6914 (cond [(eq_attr "cpu" "athlon")
6915 (const_string "vector")
6916 (eq_attr "alternative" "1")
6917 (const_string "vector")
6918 (and (eq_attr "alternative" "2")
6919 (match_operand 1 "memory_operand" ""))
6920 (const_string "vector")]
6921 (const_string "direct")))
6922 (set (attr "amdfam10_decode")
6923 (cond [(and (eq_attr "alternative" "0,1")
6924 (match_operand 1 "memory_operand" ""))
6925 (const_string "vector")]
6926 (const_string "direct")))
6927 (set_attr "bdver1_decode" "direct")
6928 (set_attr "mode" "<MODE>")])
6930 (define_insn "*mulsi3_1_zext"
6931 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6933 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6934 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6935 (clobber (reg:CC FLAGS_REG))]
6937 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6940 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6941 imul{l}\t{%2, %k0|%k0, %2}"
6942 [(set_attr "type" "imul")
6943 (set_attr "prefix_0f" "0,0,1")
6944 (set (attr "athlon_decode")
6945 (cond [(eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (eq_attr "alternative" "1")
6948 (const_string "vector")
6949 (and (eq_attr "alternative" "2")
6950 (match_operand 1 "memory_operand" ""))
6951 (const_string "vector")]
6952 (const_string "direct")))
6953 (set (attr "amdfam10_decode")
6954 (cond [(and (eq_attr "alternative" "0,1")
6955 (match_operand 1 "memory_operand" ""))
6956 (const_string "vector")]
6957 (const_string "direct")))
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "SI")])
6962 ;; IMUL reg16, reg16, imm8 VectorPath
6963 ;; IMUL reg16, mem16, imm8 VectorPath
6964 ;; IMUL reg16, reg16, imm16 VectorPath
6965 ;; IMUL reg16, mem16, imm16 VectorPath
6966 ;; IMUL reg16, reg16 Direct
6967 ;; IMUL reg16, mem16 Direct
6969 ;; On BDVER1, all HI MULs use DoublePath
6971 (define_insn "*mulhi3_1"
6972 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6973 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6974 (match_operand:HI 2 "general_operand" "K,n,mr")))
6975 (clobber (reg:CC FLAGS_REG))]
6977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6979 imul{w}\t{%2, %1, %0|%0, %1, %2}
6980 imul{w}\t{%2, %1, %0|%0, %1, %2}
6981 imul{w}\t{%2, %0|%0, %2}"
6982 [(set_attr "type" "imul")
6983 (set_attr "prefix_0f" "0,0,1")
6984 (set (attr "athlon_decode")
6985 (cond [(eq_attr "cpu" "athlon")
6986 (const_string "vector")
6987 (eq_attr "alternative" "1,2")
6988 (const_string "vector")]
6989 (const_string "direct")))
6990 (set (attr "amdfam10_decode")
6991 (cond [(eq_attr "alternative" "0,1")
6992 (const_string "vector")]
6993 (const_string "direct")))
6994 (set_attr "bdver1_decode" "double")
6995 (set_attr "mode" "HI")])
6997 ;;On AMDFAM10 and BDVER1
7001 (define_insn "*mulqi3_1"
7002 [(set (match_operand:QI 0 "register_operand" "=a")
7003 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7004 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7005 (clobber (reg:CC FLAGS_REG))]
7007 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 [(set_attr "type" "imul")
7010 (set_attr "length_immediate" "0")
7011 (set (attr "athlon_decode")
7012 (if_then_else (eq_attr "cpu" "athlon")
7013 (const_string "vector")
7014 (const_string "direct")))
7015 (set_attr "amdfam10_decode" "direct")
7016 (set_attr "bdver1_decode" "direct")
7017 (set_attr "mode" "QI")])
7019 (define_expand "<u>mul<mode><dwi>3"
7020 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7023 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7025 (match_operand:DWIH 2 "register_operand" ""))))
7026 (clobber (reg:CC FLAGS_REG))])])
7028 (define_expand "<u>mulqihi3"
7029 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7032 (match_operand:QI 1 "nonimmediate_operand" ""))
7034 (match_operand:QI 2 "register_operand" ""))))
7035 (clobber (reg:CC FLAGS_REG))])]
7036 "TARGET_QIMODE_MATH")
7038 (define_insn "*<u>mul<mode><dwi>3_1"
7039 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7042 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7044 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7045 (clobber (reg:CC FLAGS_REG))]
7046 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047 "<sgnprefix>mul{<imodesuffix>}\t%2"
7048 [(set_attr "type" "imul")
7049 (set_attr "length_immediate" "0")
7050 (set (attr "athlon_decode")
7051 (if_then_else (eq_attr "cpu" "athlon")
7052 (const_string "vector")
7053 (const_string "double")))
7054 (set_attr "amdfam10_decode" "double")
7055 (set_attr "bdver1_decode" "direct")
7056 (set_attr "mode" "<MODE>")])
7058 (define_insn "*<u>mulqihi3_1"
7059 [(set (match_operand:HI 0 "register_operand" "=a")
7062 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7064 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7065 (clobber (reg:CC FLAGS_REG))]
7067 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068 "<sgnprefix>mul{b}\t%2"
7069 [(set_attr "type" "imul")
7070 (set_attr "length_immediate" "0")
7071 (set (attr "athlon_decode")
7072 (if_then_else (eq_attr "cpu" "athlon")
7073 (const_string "vector")
7074 (const_string "direct")))
7075 (set_attr "amdfam10_decode" "direct")
7076 (set_attr "bdver1_decode" "direct")
7077 (set_attr "mode" "QI")])
7079 (define_expand "<s>mul<mode>3_highpart"
7080 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7085 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7087 (match_operand:SWI48 2 "register_operand" "")))
7089 (clobber (match_scratch:SWI48 3 ""))
7090 (clobber (reg:CC FLAGS_REG))])]
7092 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7094 (define_insn "*<s>muldi3_highpart_1"
7095 [(set (match_operand:DI 0 "register_operand" "=d")
7100 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7102 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7104 (clobber (match_scratch:DI 3 "=1"))
7105 (clobber (reg:CC FLAGS_REG))]
7107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7108 "<sgnprefix>mul{q}\t%2"
7109 [(set_attr "type" "imul")
7110 (set_attr "length_immediate" "0")
7111 (set (attr "athlon_decode")
7112 (if_then_else (eq_attr "cpu" "athlon")
7113 (const_string "vector")
7114 (const_string "double")))
7115 (set_attr "amdfam10_decode" "double")
7116 (set_attr "bdver1_decode" "direct")
7117 (set_attr "mode" "DI")])
7119 (define_insn "*<s>mulsi3_highpart_1"
7120 [(set (match_operand:SI 0 "register_operand" "=d")
7125 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7127 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7129 (clobber (match_scratch:SI 3 "=1"))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7132 "<sgnprefix>mul{l}\t%2"
7133 [(set_attr "type" "imul")
7134 (set_attr "length_immediate" "0")
7135 (set (attr "athlon_decode")
7136 (if_then_else (eq_attr "cpu" "athlon")
7137 (const_string "vector")
7138 (const_string "double")))
7139 (set_attr "amdfam10_decode" "double")
7140 (set_attr "bdver1_decode" "direct")
7141 (set_attr "mode" "SI")])
7143 (define_insn "*<s>mulsi3_highpart_zext"
7144 [(set (match_operand:DI 0 "register_operand" "=d")
7145 (zero_extend:DI (truncate:SI
7147 (mult:DI (any_extend:DI
7148 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7150 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7152 (clobber (match_scratch:SI 3 "=1"))
7153 (clobber (reg:CC FLAGS_REG))]
7155 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7156 "<sgnprefix>mul{l}\t%2"
7157 [(set_attr "type" "imul")
7158 (set_attr "length_immediate" "0")
7159 (set (attr "athlon_decode")
7160 (if_then_else (eq_attr "cpu" "athlon")
7161 (const_string "vector")
7162 (const_string "double")))
7163 (set_attr "amdfam10_decode" "double")
7164 (set_attr "bdver1_decode" "direct")
7165 (set_attr "mode" "SI")])
7167 ;; The patterns that match these are at the end of this file.
7169 (define_expand "mulxf3"
7170 [(set (match_operand:XF 0 "register_operand" "")
7171 (mult:XF (match_operand:XF 1 "register_operand" "")
7172 (match_operand:XF 2 "register_operand" "")))]
7175 (define_expand "mul<mode>3"
7176 [(set (match_operand:MODEF 0 "register_operand" "")
7177 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7178 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7179 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7180 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7182 ;; Divide instructions
7184 ;; The patterns that match these are at the end of this file.
7186 (define_expand "divxf3"
7187 [(set (match_operand:XF 0 "register_operand" "")
7188 (div:XF (match_operand:XF 1 "register_operand" "")
7189 (match_operand:XF 2 "register_operand" "")))]
7192 (define_expand "divdf3"
7193 [(set (match_operand:DF 0 "register_operand" "")
7194 (div:DF (match_operand:DF 1 "register_operand" "")
7195 (match_operand:DF 2 "nonimmediate_operand" "")))]
7196 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7197 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7199 (define_expand "divsf3"
7200 [(set (match_operand:SF 0 "register_operand" "")
7201 (div:SF (match_operand:SF 1 "register_operand" "")
7202 (match_operand:SF 2 "nonimmediate_operand" "")))]
7203 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7206 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7207 && flag_finite_math_only && !flag_trapping_math
7208 && flag_unsafe_math_optimizations)
7210 ix86_emit_swdivsf (operands[0], operands[1],
7211 operands[2], SFmode);
7216 ;; Divmod instructions.
7218 (define_expand "divmod<mode>4"
7219 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7221 (match_operand:SWIM248 1 "register_operand" "")
7222 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7223 (set (match_operand:SWIM248 3 "register_operand" "")
7224 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7225 (clobber (reg:CC FLAGS_REG))])])
7227 ;; Split with 8bit unsigned divide:
7228 ;; if (dividend an divisor are in [0-255])
7229 ;; use 8bit unsigned integer divide
7231 ;; use original integer divide
7233 [(set (match_operand:SWI48 0 "register_operand" "")
7234 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7235 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7236 (set (match_operand:SWI48 1 "register_operand" "")
7237 (mod:SWI48 (match_dup 2) (match_dup 3)))
7238 (clobber (reg:CC FLAGS_REG))]
7239 "TARGET_USE_8BIT_IDIV
7240 && TARGET_QIMODE_MATH
7241 && can_create_pseudo_p ()
7242 && !optimize_insn_for_size_p ()"
7244 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7246 (define_insn_and_split "divmod<mode>4_1"
7247 [(set (match_operand:SWI48 0 "register_operand" "=a")
7248 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7249 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7250 (set (match_operand:SWI48 1 "register_operand" "=&d")
7251 (mod:SWI48 (match_dup 2) (match_dup 3)))
7252 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7253 (clobber (reg:CC FLAGS_REG))]
7257 [(parallel [(set (match_dup 1)
7258 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7259 (clobber (reg:CC FLAGS_REG))])
7260 (parallel [(set (match_dup 0)
7261 (div:SWI48 (match_dup 2) (match_dup 3)))
7263 (mod:SWI48 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))])]
7267 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7269 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7270 operands[4] = operands[2];
7273 /* Avoid use of cltd in favor of a mov+shift. */
7274 emit_move_insn (operands[1], operands[2]);
7275 operands[4] = operands[1];
7278 [(set_attr "type" "multi")
7279 (set_attr "mode" "<MODE>")])
7281 (define_insn_and_split "*divmod<mode>4"
7282 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7283 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7284 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7285 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7286 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7287 (clobber (reg:CC FLAGS_REG))]
7291 [(parallel [(set (match_dup 1)
7292 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7293 (clobber (reg:CC FLAGS_REG))])
7294 (parallel [(set (match_dup 0)
7295 (div:SWIM248 (match_dup 2) (match_dup 3)))
7297 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7299 (clobber (reg:CC FLAGS_REG))])]
7301 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7303 if (<MODE>mode != HImode
7304 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7305 operands[4] = operands[2];
7308 /* Avoid use of cltd in favor of a mov+shift. */
7309 emit_move_insn (operands[1], operands[2]);
7310 operands[4] = operands[1];
7313 [(set_attr "type" "multi")
7314 (set_attr "mode" "<MODE>")])
7316 (define_insn "*divmod<mode>4_noext"
7317 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7318 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7319 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7320 (set (match_operand:SWIM248 1 "register_operand" "=d")
7321 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7322 (use (match_operand:SWIM248 4 "register_operand" "1"))
7323 (clobber (reg:CC FLAGS_REG))]
7325 "idiv{<imodesuffix>}\t%3"
7326 [(set_attr "type" "idiv")
7327 (set_attr "mode" "<MODE>")])
7329 (define_expand "divmodqi4"
7330 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7332 (match_operand:QI 1 "register_operand" "")
7333 (match_operand:QI 2 "nonimmediate_operand" "")))
7334 (set (match_operand:QI 3 "register_operand" "")
7335 (mod:QI (match_dup 1) (match_dup 2)))
7336 (clobber (reg:CC FLAGS_REG))])]
7337 "TARGET_QIMODE_MATH"
7342 tmp0 = gen_reg_rtx (HImode);
7343 tmp1 = gen_reg_rtx (HImode);
7345 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7347 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7348 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7350 /* Extract remainder from AH. */
7351 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7352 insn = emit_move_insn (operands[3], tmp1);
7354 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7355 set_unique_reg_note (insn, REG_EQUAL, mod);
7357 /* Extract quotient from AL. */
7358 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7360 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7361 set_unique_reg_note (insn, REG_EQUAL, div);
7366 ;; Divide AX by r/m8, with result stored in
7369 ;; Change div/mod to HImode and extend the second argument to HImode
7370 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7371 ;; combine may fail.
7372 (define_insn "divmodhiqi3"
7373 [(set (match_operand:HI 0 "register_operand" "=a")
7378 (mod:HI (match_operand:HI 1 "register_operand" "0")
7380 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7384 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7385 (clobber (reg:CC FLAGS_REG))]
7386 "TARGET_QIMODE_MATH"
7388 [(set_attr "type" "idiv")
7389 (set_attr "mode" "QI")])
7391 (define_expand "udivmod<mode>4"
7392 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7394 (match_operand:SWIM248 1 "register_operand" "")
7395 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7396 (set (match_operand:SWIM248 3 "register_operand" "")
7397 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7398 (clobber (reg:CC FLAGS_REG))])])
7400 ;; Split with 8bit unsigned divide:
7401 ;; if (dividend an divisor are in [0-255])
7402 ;; use 8bit unsigned integer divide
7404 ;; use original integer divide
7406 [(set (match_operand:SWI48 0 "register_operand" "")
7407 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7408 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7409 (set (match_operand:SWI48 1 "register_operand" "")
7410 (umod:SWI48 (match_dup 2) (match_dup 3)))
7411 (clobber (reg:CC FLAGS_REG))]
7412 "TARGET_USE_8BIT_IDIV
7413 && TARGET_QIMODE_MATH
7414 && can_create_pseudo_p ()
7415 && !optimize_insn_for_size_p ()"
7417 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7419 (define_insn_and_split "udivmod<mode>4_1"
7420 [(set (match_operand:SWI48 0 "register_operand" "=a")
7421 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7422 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7423 (set (match_operand:SWI48 1 "register_operand" "=&d")
7424 (umod:SWI48 (match_dup 2) (match_dup 3)))
7425 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7426 (clobber (reg:CC FLAGS_REG))]
7430 [(set (match_dup 1) (const_int 0))
7431 (parallel [(set (match_dup 0)
7432 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7434 (umod:SWI48 (match_dup 2) (match_dup 3)))
7436 (clobber (reg:CC FLAGS_REG))])]
7438 [(set_attr "type" "multi")
7439 (set_attr "mode" "<MODE>")])
7441 (define_insn_and_split "*udivmod<mode>4"
7442 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7443 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7444 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7445 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7446 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7447 (clobber (reg:CC FLAGS_REG))]
7451 [(set (match_dup 1) (const_int 0))
7452 (parallel [(set (match_dup 0)
7453 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7455 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7457 (clobber (reg:CC FLAGS_REG))])]
7459 [(set_attr "type" "multi")
7460 (set_attr "mode" "<MODE>")])
7462 (define_insn "*udivmod<mode>4_noext"
7463 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7464 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7465 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7466 (set (match_operand:SWIM248 1 "register_operand" "=d")
7467 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7468 (use (match_operand:SWIM248 4 "register_operand" "1"))
7469 (clobber (reg:CC FLAGS_REG))]
7471 "div{<imodesuffix>}\t%3"
7472 [(set_attr "type" "idiv")
7473 (set_attr "mode" "<MODE>")])
7475 (define_expand "udivmodqi4"
7476 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7478 (match_operand:QI 1 "register_operand" "")
7479 (match_operand:QI 2 "nonimmediate_operand" "")))
7480 (set (match_operand:QI 3 "register_operand" "")
7481 (umod:QI (match_dup 1) (match_dup 2)))
7482 (clobber (reg:CC FLAGS_REG))])]
7483 "TARGET_QIMODE_MATH"
7488 tmp0 = gen_reg_rtx (HImode);
7489 tmp1 = gen_reg_rtx (HImode);
7491 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7493 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7494 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7496 /* Extract remainder from AH. */
7497 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7498 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7499 insn = emit_move_insn (operands[3], tmp1);
7501 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7502 set_unique_reg_note (insn, REG_EQUAL, mod);
7504 /* Extract quotient from AL. */
7505 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7507 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7508 set_unique_reg_note (insn, REG_EQUAL, div);
7513 (define_insn "udivmodhiqi3"
7514 [(set (match_operand:HI 0 "register_operand" "=a")
7519 (mod:HI (match_operand:HI 1 "register_operand" "0")
7521 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7525 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7526 (clobber (reg:CC FLAGS_REG))]
7527 "TARGET_QIMODE_MATH"
7529 [(set_attr "type" "idiv")
7530 (set_attr "mode" "QI")])
7532 ;; We cannot use div/idiv for double division, because it causes
7533 ;; "division by zero" on the overflow and that's not what we expect
7534 ;; from truncate. Because true (non truncating) double division is
7535 ;; never generated, we can't create this insn anyway.
7538 ; [(set (match_operand:SI 0 "register_operand" "=a")
7540 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7542 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7543 ; (set (match_operand:SI 3 "register_operand" "=d")
7545 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7546 ; (clobber (reg:CC FLAGS_REG))]
7548 ; "div{l}\t{%2, %0|%0, %2}"
7549 ; [(set_attr "type" "idiv")])
7551 ;;- Logical AND instructions
7553 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7554 ;; Note that this excludes ah.
7556 (define_expand "testsi_ccno_1"
7557 [(set (reg:CCNO FLAGS_REG)
7559 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7560 (match_operand:SI 1 "nonmemory_operand" ""))
7563 (define_expand "testqi_ccz_1"
7564 [(set (reg:CCZ FLAGS_REG)
7565 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7566 (match_operand:QI 1 "nonmemory_operand" ""))
7569 (define_expand "testdi_ccno_1"
7570 [(set (reg:CCNO FLAGS_REG)
7572 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7573 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7575 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7577 (define_insn "*testdi_1"
7578 [(set (reg FLAGS_REG)
7581 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7582 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7584 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7585 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7587 test{l}\t{%k1, %k0|%k0, %k1}
7588 test{l}\t{%k1, %k0|%k0, %k1}
7589 test{q}\t{%1, %0|%0, %1}
7590 test{q}\t{%1, %0|%0, %1}
7591 test{q}\t{%1, %0|%0, %1}"
7592 [(set_attr "type" "test")
7593 (set_attr "modrm" "0,1,0,1,1")
7594 (set_attr "mode" "SI,SI,DI,DI,DI")])
7596 (define_insn "*testqi_1_maybe_si"
7597 [(set (reg FLAGS_REG)
7600 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7601 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7603 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7604 && ix86_match_ccmode (insn,
7605 CONST_INT_P (operands[1])
7606 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7608 if (which_alternative == 3)
7610 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7611 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7612 return "test{l}\t{%1, %k0|%k0, %1}";
7614 return "test{b}\t{%1, %0|%0, %1}";
7616 [(set_attr "type" "test")
7617 (set_attr "modrm" "0,1,1,1")
7618 (set_attr "mode" "QI,QI,QI,SI")
7619 (set_attr "pent_pair" "uv,np,uv,np")])
7621 (define_insn "*test<mode>_1"
7622 [(set (reg FLAGS_REG)
7625 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7626 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7628 "ix86_match_ccmode (insn, CCNOmode)
7629 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7630 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7631 [(set_attr "type" "test")
7632 (set_attr "modrm" "0,1,1")
7633 (set_attr "mode" "<MODE>")
7634 (set_attr "pent_pair" "uv,np,uv")])
7636 (define_expand "testqi_ext_ccno_0"
7637 [(set (reg:CCNO FLAGS_REG)
7641 (match_operand 0 "ext_register_operand" "")
7644 (match_operand 1 "const_int_operand" ""))
7647 (define_insn "*testqi_ext_0"
7648 [(set (reg FLAGS_REG)
7652 (match_operand 0 "ext_register_operand" "Q")
7655 (match_operand 1 "const_int_operand" "n"))
7657 "ix86_match_ccmode (insn, CCNOmode)"
7658 "test{b}\t{%1, %h0|%h0, %1}"
7659 [(set_attr "type" "test")
7660 (set_attr "mode" "QI")
7661 (set_attr "length_immediate" "1")
7662 (set_attr "modrm" "1")
7663 (set_attr "pent_pair" "np")])
7665 (define_insn "*testqi_ext_1_rex64"
7666 [(set (reg FLAGS_REG)
7670 (match_operand 0 "ext_register_operand" "Q")
7674 (match_operand:QI 1 "register_operand" "Q")))
7676 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%1, %h0|%h0, %1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7681 (define_insn "*testqi_ext_1"
7682 [(set (reg FLAGS_REG)
7686 (match_operand 0 "ext_register_operand" "Q")
7690 (match_operand:QI 1 "general_operand" "Qm")))
7692 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7693 "test{b}\t{%1, %h0|%h0, %1}"
7694 [(set_attr "type" "test")
7695 (set_attr "mode" "QI")])
7697 (define_insn "*testqi_ext_2"
7698 [(set (reg FLAGS_REG)
7702 (match_operand 0 "ext_register_operand" "Q")
7706 (match_operand 1 "ext_register_operand" "Q")
7710 "ix86_match_ccmode (insn, CCNOmode)"
7711 "test{b}\t{%h1, %h0|%h0, %h1}"
7712 [(set_attr "type" "test")
7713 (set_attr "mode" "QI")])
7715 (define_insn "*testqi_ext_3_rex64"
7716 [(set (reg FLAGS_REG)
7717 (compare (zero_extract:DI
7718 (match_operand 0 "nonimmediate_operand" "rm")
7719 (match_operand:DI 1 "const_int_operand" "")
7720 (match_operand:DI 2 "const_int_operand" ""))
7723 && ix86_match_ccmode (insn, CCNOmode)
7724 && INTVAL (operands[1]) > 0
7725 && INTVAL (operands[2]) >= 0
7726 /* Ensure that resulting mask is zero or sign extended operand. */
7727 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7728 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7729 && INTVAL (operands[1]) > 32))
7730 && (GET_MODE (operands[0]) == SImode
7731 || GET_MODE (operands[0]) == DImode
7732 || GET_MODE (operands[0]) == HImode
7733 || GET_MODE (operands[0]) == QImode)"
7736 ;; Combine likes to form bit extractions for some tests. Humor it.
7737 (define_insn "*testqi_ext_3"
7738 [(set (reg FLAGS_REG)
7739 (compare (zero_extract:SI
7740 (match_operand 0 "nonimmediate_operand" "rm")
7741 (match_operand:SI 1 "const_int_operand" "")
7742 (match_operand:SI 2 "const_int_operand" ""))
7744 "ix86_match_ccmode (insn, CCNOmode)
7745 && INTVAL (operands[1]) > 0
7746 && INTVAL (operands[2]) >= 0
7747 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7748 && (GET_MODE (operands[0]) == SImode
7749 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7750 || GET_MODE (operands[0]) == HImode
7751 || GET_MODE (operands[0]) == QImode)"
7755 [(set (match_operand 0 "flags_reg_operand" "")
7756 (match_operator 1 "compare_operator"
7758 (match_operand 2 "nonimmediate_operand" "")
7759 (match_operand 3 "const_int_operand" "")
7760 (match_operand 4 "const_int_operand" ""))
7762 "ix86_match_ccmode (insn, CCNOmode)"
7763 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7765 rtx val = operands[2];
7766 HOST_WIDE_INT len = INTVAL (operands[3]);
7767 HOST_WIDE_INT pos = INTVAL (operands[4]);
7769 enum machine_mode mode, submode;
7771 mode = GET_MODE (val);
7774 /* ??? Combine likes to put non-volatile mem extractions in QImode
7775 no matter the size of the test. So find a mode that works. */
7776 if (! MEM_VOLATILE_P (val))
7778 mode = smallest_mode_for_size (pos + len, MODE_INT);
7779 val = adjust_address (val, mode, 0);
7782 else if (GET_CODE (val) == SUBREG
7783 && (submode = GET_MODE (SUBREG_REG (val)),
7784 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7785 && pos + len <= GET_MODE_BITSIZE (submode)
7786 && GET_MODE_CLASS (submode) == MODE_INT)
7788 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7790 val = SUBREG_REG (val);
7792 else if (mode == HImode && pos + len <= 8)
7794 /* Small HImode tests can be converted to QImode. */
7796 val = gen_lowpart (QImode, val);
7799 if (len == HOST_BITS_PER_WIDE_INT)
7802 mask = ((HOST_WIDE_INT)1 << len) - 1;
7805 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7808 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7809 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7810 ;; this is relatively important trick.
7811 ;; Do the conversion only post-reload to avoid limiting of the register class
7814 [(set (match_operand 0 "flags_reg_operand" "")
7815 (match_operator 1 "compare_operator"
7816 [(and (match_operand 2 "register_operand" "")
7817 (match_operand 3 "const_int_operand" ""))
7820 && QI_REG_P (operands[2])
7821 && GET_MODE (operands[2]) != QImode
7822 && ((ix86_match_ccmode (insn, CCZmode)
7823 && !(INTVAL (operands[3]) & ~(255 << 8)))
7824 || (ix86_match_ccmode (insn, CCNOmode)
7825 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7828 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7831 "operands[2] = gen_lowpart (SImode, operands[2]);
7832 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7835 [(set (match_operand 0 "flags_reg_operand" "")
7836 (match_operator 1 "compare_operator"
7837 [(and (match_operand 2 "nonimmediate_operand" "")
7838 (match_operand 3 "const_int_operand" ""))
7841 && GET_MODE (operands[2]) != QImode
7842 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7843 && ((ix86_match_ccmode (insn, CCZmode)
7844 && !(INTVAL (operands[3]) & ~255))
7845 || (ix86_match_ccmode (insn, CCNOmode)
7846 && !(INTVAL (operands[3]) & ~127)))"
7848 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7850 "operands[2] = gen_lowpart (QImode, operands[2]);
7851 operands[3] = gen_lowpart (QImode, operands[3]);")
7853 ;; %%% This used to optimize known byte-wide and operations to memory,
7854 ;; and sometimes to QImode registers. If this is considered useful,
7855 ;; it should be done with splitters.
7857 (define_expand "and<mode>3"
7858 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7859 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7860 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7862 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7864 (define_insn "*anddi_1"
7865 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7867 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7868 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7869 (clobber (reg:CC FLAGS_REG))]
7870 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7872 switch (get_attr_type (insn))
7876 enum machine_mode mode;
7878 gcc_assert (CONST_INT_P (operands[2]));
7879 if (INTVAL (operands[2]) == 0xff)
7883 gcc_assert (INTVAL (operands[2]) == 0xffff);
7887 operands[1] = gen_lowpart (mode, operands[1]);
7889 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7891 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7895 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7896 if (get_attr_mode (insn) == MODE_SI)
7897 return "and{l}\t{%k2, %k0|%k0, %k2}";
7899 return "and{q}\t{%2, %0|%0, %2}";
7902 [(set_attr "type" "alu,alu,alu,imovx")
7903 (set_attr "length_immediate" "*,*,*,0")
7904 (set (attr "prefix_rex")
7906 (and (eq_attr "type" "imovx")
7907 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7908 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7910 (const_string "*")))
7911 (set_attr "mode" "SI,DI,DI,SI")])
7913 (define_insn "*andsi_1"
7914 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7915 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7916 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7917 (clobber (reg:CC FLAGS_REG))]
7918 "ix86_binary_operator_ok (AND, SImode, operands)"
7920 switch (get_attr_type (insn))
7924 enum machine_mode mode;
7926 gcc_assert (CONST_INT_P (operands[2]));
7927 if (INTVAL (operands[2]) == 0xff)
7931 gcc_assert (INTVAL (operands[2]) == 0xffff);
7935 operands[1] = gen_lowpart (mode, operands[1]);
7937 return "movz{bl|x}\t{%1, %0|%0, %1}";
7939 return "movz{wl|x}\t{%1, %0|%0, %1}";
7943 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7944 return "and{l}\t{%2, %0|%0, %2}";
7947 [(set_attr "type" "alu,alu,imovx")
7948 (set (attr "prefix_rex")
7950 (and (eq_attr "type" "imovx")
7951 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7952 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7954 (const_string "*")))
7955 (set_attr "length_immediate" "*,*,0")
7956 (set_attr "mode" "SI")])
7958 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7959 (define_insn "*andsi_1_zext"
7960 [(set (match_operand:DI 0 "register_operand" "=r")
7962 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7963 (match_operand:SI 2 "general_operand" "g"))))
7964 (clobber (reg:CC FLAGS_REG))]
7965 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7966 "and{l}\t{%2, %k0|%k0, %2}"
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "SI")])
7970 (define_insn "*andhi_1"
7971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7972 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7973 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7974 (clobber (reg:CC FLAGS_REG))]
7975 "ix86_binary_operator_ok (AND, HImode, operands)"
7977 switch (get_attr_type (insn))
7980 gcc_assert (CONST_INT_P (operands[2]));
7981 gcc_assert (INTVAL (operands[2]) == 0xff);
7982 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7985 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7987 return "and{w}\t{%2, %0|%0, %2}";
7990 [(set_attr "type" "alu,alu,imovx")
7991 (set_attr "length_immediate" "*,*,0")
7992 (set (attr "prefix_rex")
7994 (and (eq_attr "type" "imovx")
7995 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7997 (const_string "*")))
7998 (set_attr "mode" "HI,HI,SI")])
8000 ;; %%% Potential partial reg stall on alternative 2. What to do?
8001 (define_insn "*andqi_1"
8002 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8003 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8004 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "ix86_binary_operator_ok (AND, QImode, operands)"
8008 and{b}\t{%2, %0|%0, %2}
8009 and{b}\t{%2, %0|%0, %2}
8010 and{l}\t{%k2, %k0|%k0, %k2}"
8011 [(set_attr "type" "alu")
8012 (set_attr "mode" "QI,QI,SI")])
8014 (define_insn "*andqi_1_slp"
8015 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8016 (and:QI (match_dup 0)
8017 (match_operand:QI 1 "general_operand" "qn,qmn")))
8018 (clobber (reg:CC FLAGS_REG))]
8019 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8020 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8021 "and{b}\t{%1, %0|%0, %1}"
8022 [(set_attr "type" "alu1")
8023 (set_attr "mode" "QI")])
8026 [(set (match_operand 0 "register_operand" "")
8028 (const_int -65536)))
8029 (clobber (reg:CC FLAGS_REG))]
8030 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8031 || optimize_function_for_size_p (cfun)"
8032 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8033 "operands[1] = gen_lowpart (HImode, operands[0]);")
8036 [(set (match_operand 0 "ext_register_operand" "")
8039 (clobber (reg:CC FLAGS_REG))]
8040 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8041 && reload_completed"
8042 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8043 "operands[1] = gen_lowpart (QImode, operands[0]);")
8046 [(set (match_operand 0 "ext_register_operand" "")
8048 (const_int -65281)))
8049 (clobber (reg:CC FLAGS_REG))]
8050 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8051 && reload_completed"
8052 [(parallel [(set (zero_extract:SI (match_dup 0)
8056 (zero_extract:SI (match_dup 0)
8059 (zero_extract:SI (match_dup 0)
8062 (clobber (reg:CC FLAGS_REG))])]
8063 "operands[0] = gen_lowpart (SImode, operands[0]);")
8065 (define_insn "*anddi_2"
8066 [(set (reg FLAGS_REG)
8069 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8070 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8072 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8073 (and:DI (match_dup 1) (match_dup 2)))]
8074 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8075 && ix86_binary_operator_ok (AND, DImode, operands)"
8077 and{l}\t{%k2, %k0|%k0, %k2}
8078 and{q}\t{%2, %0|%0, %2}
8079 and{q}\t{%2, %0|%0, %2}"
8080 [(set_attr "type" "alu")
8081 (set_attr "mode" "SI,DI,DI")])
8083 (define_insn "*andqi_2_maybe_si"
8084 [(set (reg FLAGS_REG)
8086 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8087 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8089 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8090 (and:QI (match_dup 1) (match_dup 2)))]
8091 "ix86_binary_operator_ok (AND, QImode, operands)
8092 && ix86_match_ccmode (insn,
8093 CONST_INT_P (operands[2])
8094 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8096 if (which_alternative == 2)
8098 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8099 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8100 return "and{l}\t{%2, %k0|%k0, %2}";
8102 return "and{b}\t{%2, %0|%0, %2}";
8104 [(set_attr "type" "alu")
8105 (set_attr "mode" "QI,QI,SI")])
8107 (define_insn "*and<mode>_2"
8108 [(set (reg FLAGS_REG)
8109 (compare (and:SWI124
8110 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8111 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8113 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8114 (and:SWI124 (match_dup 1) (match_dup 2)))]
8115 "ix86_match_ccmode (insn, CCNOmode)
8116 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8117 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8118 [(set_attr "type" "alu")
8119 (set_attr "mode" "<MODE>")])
8121 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8122 (define_insn "*andsi_2_zext"
8123 [(set (reg FLAGS_REG)
8125 (match_operand:SI 1 "nonimmediate_operand" "%0")
8126 (match_operand:SI 2 "general_operand" "g"))
8128 (set (match_operand:DI 0 "register_operand" "=r")
8129 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8130 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8131 && ix86_binary_operator_ok (AND, SImode, operands)"
8132 "and{l}\t{%2, %k0|%k0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "mode" "SI")])
8136 (define_insn "*andqi_2_slp"
8137 [(set (reg FLAGS_REG)
8139 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8140 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8142 (set (strict_low_part (match_dup 0))
8143 (and:QI (match_dup 0) (match_dup 1)))]
8144 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8145 && ix86_match_ccmode (insn, CCNOmode)
8146 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8147 "and{b}\t{%1, %0|%0, %1}"
8148 [(set_attr "type" "alu1")
8149 (set_attr "mode" "QI")])
8151 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8152 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8153 ;; for a QImode operand, which of course failed.
8154 (define_insn "andqi_ext_0"
8155 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8160 (match_operand 1 "ext_register_operand" "0")
8163 (match_operand 2 "const_int_operand" "n")))
8164 (clobber (reg:CC FLAGS_REG))]
8166 "and{b}\t{%2, %h0|%h0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "length_immediate" "1")
8169 (set_attr "modrm" "1")
8170 (set_attr "mode" "QI")])
8172 ;; Generated by peephole translating test to and. This shows up
8173 ;; often in fp comparisons.
8174 (define_insn "*andqi_ext_0_cc"
8175 [(set (reg FLAGS_REG)
8179 (match_operand 1 "ext_register_operand" "0")
8182 (match_operand 2 "const_int_operand" "n"))
8184 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8193 "ix86_match_ccmode (insn, CCNOmode)"
8194 "and{b}\t{%2, %h0|%h0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "length_immediate" "1")
8197 (set_attr "modrm" "1")
8198 (set_attr "mode" "QI")])
8200 (define_insn "*andqi_ext_1_rex64"
8201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8206 (match_operand 1 "ext_register_operand" "0")
8210 (match_operand 2 "ext_register_operand" "Q"))))
8211 (clobber (reg:CC FLAGS_REG))]
8213 "and{b}\t{%2, %h0|%h0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "length_immediate" "0")
8216 (set_attr "mode" "QI")])
8218 (define_insn "*andqi_ext_1"
8219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8224 (match_operand 1 "ext_register_operand" "0")
8228 (match_operand:QI 2 "general_operand" "Qm"))))
8229 (clobber (reg:CC FLAGS_REG))]
8231 "and{b}\t{%2, %h0|%h0, %2}"
8232 [(set_attr "type" "alu")
8233 (set_attr "length_immediate" "0")
8234 (set_attr "mode" "QI")])
8236 (define_insn "*andqi_ext_2"
8237 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242 (match_operand 1 "ext_register_operand" "%0")
8246 (match_operand 2 "ext_register_operand" "Q")
8249 (clobber (reg:CC FLAGS_REG))]
8251 "and{b}\t{%h2, %h0|%h0, %h2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "length_immediate" "0")
8254 (set_attr "mode" "QI")])
8256 ;; Convert wide AND instructions with immediate operand to shorter QImode
8257 ;; equivalents when possible.
8258 ;; Don't do the splitting with memory operands, since it introduces risk
8259 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8260 ;; for size, but that can (should?) be handled by generic code instead.
8262 [(set (match_operand 0 "register_operand" "")
8263 (and (match_operand 1 "register_operand" "")
8264 (match_operand 2 "const_int_operand" "")))
8265 (clobber (reg:CC FLAGS_REG))]
8267 && QI_REG_P (operands[0])
8268 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8269 && !(~INTVAL (operands[2]) & ~(255 << 8))
8270 && GET_MODE (operands[0]) != QImode"
8271 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8272 (and:SI (zero_extract:SI (match_dup 1)
8273 (const_int 8) (const_int 8))
8275 (clobber (reg:CC FLAGS_REG))])]
8276 "operands[0] = gen_lowpart (SImode, operands[0]);
8277 operands[1] = gen_lowpart (SImode, operands[1]);
8278 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8280 ;; Since AND can be encoded with sign extended immediate, this is only
8281 ;; profitable when 7th bit is not set.
8283 [(set (match_operand 0 "register_operand" "")
8284 (and (match_operand 1 "general_operand" "")
8285 (match_operand 2 "const_int_operand" "")))
8286 (clobber (reg:CC FLAGS_REG))]
8288 && ANY_QI_REG_P (operands[0])
8289 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290 && !(~INTVAL (operands[2]) & ~255)
8291 && !(INTVAL (operands[2]) & 128)
8292 && GET_MODE (operands[0]) != QImode"
8293 [(parallel [(set (strict_low_part (match_dup 0))
8294 (and:QI (match_dup 1)
8296 (clobber (reg:CC FLAGS_REG))])]
8297 "operands[0] = gen_lowpart (QImode, operands[0]);
8298 operands[1] = gen_lowpart (QImode, operands[1]);
8299 operands[2] = gen_lowpart (QImode, operands[2]);")
8301 ;; Logical inclusive and exclusive OR instructions
8303 ;; %%% This used to optimize known byte-wide and operations to memory.
8304 ;; If this is considered useful, it should be done with splitters.
8306 (define_expand "<code><mode>3"
8307 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8308 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8309 (match_operand:SWIM 2 "<general_operand>" "")))]
8311 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8313 (define_insn "*<code><mode>_1"
8314 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8316 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8317 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8320 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "<MODE>")])
8324 ;; %%% Potential partial reg stall on alternative 2. What to do?
8325 (define_insn "*<code>qi_1"
8326 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8327 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8328 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8332 <logic>{b}\t{%2, %0|%0, %2}
8333 <logic>{b}\t{%2, %0|%0, %2}
8334 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8335 [(set_attr "type" "alu")
8336 (set_attr "mode" "QI,QI,SI")])
8338 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8339 (define_insn "*<code>si_1_zext"
8340 [(set (match_operand:DI 0 "register_operand" "=r")
8342 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8343 (match_operand:SI 2 "general_operand" "g"))))
8344 (clobber (reg:CC FLAGS_REG))]
8345 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8346 "<logic>{l}\t{%2, %k0|%k0, %2}"
8347 [(set_attr "type" "alu")
8348 (set_attr "mode" "SI")])
8350 (define_insn "*<code>si_1_zext_imm"
8351 [(set (match_operand:DI 0 "register_operand" "=r")
8353 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8354 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8355 (clobber (reg:CC FLAGS_REG))]
8356 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8357 "<logic>{l}\t{%2, %k0|%k0, %2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "mode" "SI")])
8361 (define_insn "*<code>qi_1_slp"
8362 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8363 (any_or:QI (match_dup 0)
8364 (match_operand:QI 1 "general_operand" "qmn,qn")))
8365 (clobber (reg:CC FLAGS_REG))]
8366 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8367 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8368 "<logic>{b}\t{%1, %0|%0, %1}"
8369 [(set_attr "type" "alu1")
8370 (set_attr "mode" "QI")])
8372 (define_insn "*<code><mode>_2"
8373 [(set (reg FLAGS_REG)
8374 (compare (any_or:SWI
8375 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8376 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8379 (any_or:SWI (match_dup 1) (match_dup 2)))]
8380 "ix86_match_ccmode (insn, CCNOmode)
8381 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8382 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "mode" "<MODE>")])
8386 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8387 ;; ??? Special case for immediate operand is missing - it is tricky.
8388 (define_insn "*<code>si_2_zext"
8389 [(set (reg FLAGS_REG)
8390 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8391 (match_operand:SI 2 "general_operand" "g"))
8393 (set (match_operand:DI 0 "register_operand" "=r")
8394 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8396 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8397 "<logic>{l}\t{%2, %k0|%k0, %2}"
8398 [(set_attr "type" "alu")
8399 (set_attr "mode" "SI")])
8401 (define_insn "*<code>si_2_zext_imm"
8402 [(set (reg FLAGS_REG)
8404 (match_operand:SI 1 "nonimmediate_operand" "%0")
8405 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8407 (set (match_operand:DI 0 "register_operand" "=r")
8408 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8409 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8410 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8411 "<logic>{l}\t{%2, %k0|%k0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "SI")])
8415 (define_insn "*<code>qi_2_slp"
8416 [(set (reg FLAGS_REG)
8417 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8418 (match_operand:QI 1 "general_operand" "qmn,qn"))
8420 (set (strict_low_part (match_dup 0))
8421 (any_or:QI (match_dup 0) (match_dup 1)))]
8422 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8423 && ix86_match_ccmode (insn, CCNOmode)
8424 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425 "<logic>{b}\t{%1, %0|%0, %1}"
8426 [(set_attr "type" "alu1")
8427 (set_attr "mode" "QI")])
8429 (define_insn "*<code><mode>_3"
8430 [(set (reg FLAGS_REG)
8431 (compare (any_or:SWI
8432 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8433 (match_operand:SWI 2 "<general_operand>" "<g>"))
8435 (clobber (match_scratch:SWI 0 "=<r>"))]
8436 "ix86_match_ccmode (insn, CCNOmode)
8437 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8438 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8439 [(set_attr "type" "alu")
8440 (set_attr "mode" "<MODE>")])
8442 (define_insn "*<code>qi_ext_0"
8443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448 (match_operand 1 "ext_register_operand" "0")
8451 (match_operand 2 "const_int_operand" "n")))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454 "<logic>{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "1")
8457 (set_attr "modrm" "1")
8458 (set_attr "mode" "QI")])
8460 (define_insn "*<code>qi_ext_1_rex64"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466 (match_operand 1 "ext_register_operand" "0")
8470 (match_operand 2 "ext_register_operand" "Q"))))
8471 (clobber (reg:CC FLAGS_REG))]
8473 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8474 "<logic>{b}\t{%2, %h0|%h0, %2}"
8475 [(set_attr "type" "alu")
8476 (set_attr "length_immediate" "0")
8477 (set_attr "mode" "QI")])
8479 (define_insn "*<code>qi_ext_1"
8480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485 (match_operand 1 "ext_register_operand" "0")
8489 (match_operand:QI 2 "general_operand" "Qm"))))
8490 (clobber (reg:CC FLAGS_REG))]
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8493 "<logic>{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8498 (define_insn "*<code>qi_ext_2"
8499 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8503 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8506 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8509 (clobber (reg:CC FLAGS_REG))]
8510 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8511 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8512 [(set_attr "type" "alu")
8513 (set_attr "length_immediate" "0")
8514 (set_attr "mode" "QI")])
8517 [(set (match_operand 0 "register_operand" "")
8518 (any_or (match_operand 1 "register_operand" "")
8519 (match_operand 2 "const_int_operand" "")))
8520 (clobber (reg:CC FLAGS_REG))]
8522 && QI_REG_P (operands[0])
8523 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524 && !(INTVAL (operands[2]) & ~(255 << 8))
8525 && GET_MODE (operands[0]) != QImode"
8526 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8527 (any_or:SI (zero_extract:SI (match_dup 1)
8528 (const_int 8) (const_int 8))
8530 (clobber (reg:CC FLAGS_REG))])]
8531 "operands[0] = gen_lowpart (SImode, operands[0]);
8532 operands[1] = gen_lowpart (SImode, operands[1]);
8533 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8535 ;; Since OR can be encoded with sign extended immediate, this is only
8536 ;; profitable when 7th bit is set.
8538 [(set (match_operand 0 "register_operand" "")
8539 (any_or (match_operand 1 "general_operand" "")
8540 (match_operand 2 "const_int_operand" "")))
8541 (clobber (reg:CC FLAGS_REG))]
8543 && ANY_QI_REG_P (operands[0])
8544 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8545 && !(INTVAL (operands[2]) & ~255)
8546 && (INTVAL (operands[2]) & 128)
8547 && GET_MODE (operands[0]) != QImode"
8548 [(parallel [(set (strict_low_part (match_dup 0))
8549 (any_or:QI (match_dup 1)
8551 (clobber (reg:CC FLAGS_REG))])]
8552 "operands[0] = gen_lowpart (QImode, operands[0]);
8553 operands[1] = gen_lowpart (QImode, operands[1]);
8554 operands[2] = gen_lowpart (QImode, operands[2]);")
8556 (define_expand "xorqi_cc_ext_1"
8558 (set (reg:CCNO FLAGS_REG)
8562 (match_operand 1 "ext_register_operand" "")
8565 (match_operand:QI 2 "general_operand" ""))
8567 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8577 (define_insn "*xorqi_cc_ext_1_rex64"
8578 [(set (reg FLAGS_REG)
8582 (match_operand 1 "ext_register_operand" "0")
8585 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8587 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8597 "xor{b}\t{%2, %h0|%h0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "modrm" "1")
8600 (set_attr "mode" "QI")])
8602 (define_insn "*xorqi_cc_ext_1"
8603 [(set (reg FLAGS_REG)
8607 (match_operand 1 "ext_register_operand" "0")
8610 (match_operand:QI 2 "general_operand" "qmn"))
8612 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8622 "xor{b}\t{%2, %h0|%h0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "modrm" "1")
8625 (set_attr "mode" "QI")])
8627 ;; Negation instructions
8629 (define_expand "neg<mode>2"
8630 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8631 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8633 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8635 (define_insn_and_split "*neg<dwi>2_doubleword"
8636 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8637 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8638 (clobber (reg:CC FLAGS_REG))]
8639 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8643 [(set (reg:CCZ FLAGS_REG)
8644 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8645 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8648 (plus:DWIH (match_dup 3)
8649 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8651 (clobber (reg:CC FLAGS_REG))])
8654 (neg:DWIH (match_dup 2)))
8655 (clobber (reg:CC FLAGS_REG))])]
8656 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8658 (define_insn "*neg<mode>2_1"
8659 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8660 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8663 "neg{<imodesuffix>}\t%0"
8664 [(set_attr "type" "negnot")
8665 (set_attr "mode" "<MODE>")])
8667 ;; Combine is quite creative about this pattern.
8668 (define_insn "*negsi2_1_zext"
8669 [(set (match_operand:DI 0 "register_operand" "=r")
8671 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8674 (clobber (reg:CC FLAGS_REG))]
8675 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8677 [(set_attr "type" "negnot")
8678 (set_attr "mode" "SI")])
8680 ;; The problem with neg is that it does not perform (compare x 0),
8681 ;; it really performs (compare 0 x), which leaves us with the zero
8682 ;; flag being the only useful item.
8684 (define_insn "*neg<mode>2_cmpz"
8685 [(set (reg:CCZ FLAGS_REG)
8687 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8689 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8690 (neg:SWI (match_dup 1)))]
8691 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8692 "neg{<imodesuffix>}\t%0"
8693 [(set_attr "type" "negnot")
8694 (set_attr "mode" "<MODE>")])
8696 (define_insn "*negsi2_cmpz_zext"
8697 [(set (reg:CCZ FLAGS_REG)
8701 (match_operand:DI 1 "register_operand" "0")
8705 (set (match_operand:DI 0 "register_operand" "=r")
8706 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8709 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8711 [(set_attr "type" "negnot")
8712 (set_attr "mode" "SI")])
8714 ;; Changing of sign for FP values is doable using integer unit too.
8716 (define_expand "<code><mode>2"
8717 [(set (match_operand:X87MODEF 0 "register_operand" "")
8718 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8719 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8720 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8722 (define_insn "*absneg<mode>2_mixed"
8723 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8724 (match_operator:MODEF 3 "absneg_operator"
8725 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8726 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8727 (clobber (reg:CC FLAGS_REG))]
8728 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8731 (define_insn "*absneg<mode>2_sse"
8732 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8733 (match_operator:MODEF 3 "absneg_operator"
8734 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8735 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8740 (define_insn "*absneg<mode>2_i387"
8741 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8742 (match_operator:X87MODEF 3 "absneg_operator"
8743 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8744 (use (match_operand 2 "" ""))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8749 (define_expand "<code>tf2"
8750 [(set (match_operand:TF 0 "register_operand" "")
8751 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8753 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8755 (define_insn "*absnegtf2_sse"
8756 [(set (match_operand:TF 0 "register_operand" "=x,x")
8757 (match_operator:TF 3 "absneg_operator"
8758 [(match_operand:TF 1 "register_operand" "0,x")]))
8759 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8760 (clobber (reg:CC FLAGS_REG))]
8764 ;; Splitters for fp abs and neg.
8767 [(set (match_operand 0 "fp_register_operand" "")
8768 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8769 (use (match_operand 2 "" ""))
8770 (clobber (reg:CC FLAGS_REG))]
8772 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8775 [(set (match_operand 0 "register_operand" "")
8776 (match_operator 3 "absneg_operator"
8777 [(match_operand 1 "register_operand" "")]))
8778 (use (match_operand 2 "nonimmediate_operand" ""))
8779 (clobber (reg:CC FLAGS_REG))]
8780 "reload_completed && SSE_REG_P (operands[0])"
8781 [(set (match_dup 0) (match_dup 3))]
8783 enum machine_mode mode = GET_MODE (operands[0]);
8784 enum machine_mode vmode = GET_MODE (operands[2]);
8787 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8788 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8789 if (operands_match_p (operands[0], operands[2]))
8792 operands[1] = operands[2];
8795 if (GET_CODE (operands[3]) == ABS)
8796 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8798 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8803 [(set (match_operand:SF 0 "register_operand" "")
8804 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8805 (use (match_operand:V4SF 2 "" ""))
8806 (clobber (reg:CC FLAGS_REG))]
8808 [(parallel [(set (match_dup 0) (match_dup 1))
8809 (clobber (reg:CC FLAGS_REG))])]
8812 operands[0] = gen_lowpart (SImode, operands[0]);
8813 if (GET_CODE (operands[1]) == ABS)
8815 tmp = gen_int_mode (0x7fffffff, SImode);
8816 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8820 tmp = gen_int_mode (0x80000000, SImode);
8821 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 [(set (match_operand:DF 0 "register_operand" "")
8828 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8829 (use (match_operand 2 "" ""))
8830 (clobber (reg:CC FLAGS_REG))]
8832 [(parallel [(set (match_dup 0) (match_dup 1))
8833 (clobber (reg:CC FLAGS_REG))])]
8838 tmp = gen_lowpart (DImode, operands[0]);
8839 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8842 if (GET_CODE (operands[1]) == ABS)
8845 tmp = gen_rtx_NOT (DImode, tmp);
8849 operands[0] = gen_highpart (SImode, operands[0]);
8850 if (GET_CODE (operands[1]) == ABS)
8852 tmp = gen_int_mode (0x7fffffff, SImode);
8853 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8857 tmp = gen_int_mode (0x80000000, SImode);
8858 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8865 [(set (match_operand:XF 0 "register_operand" "")
8866 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8867 (use (match_operand 2 "" ""))
8868 (clobber (reg:CC FLAGS_REG))]
8870 [(parallel [(set (match_dup 0) (match_dup 1))
8871 (clobber (reg:CC FLAGS_REG))])]
8874 operands[0] = gen_rtx_REG (SImode,
8875 true_regnum (operands[0])
8876 + (TARGET_64BIT ? 1 : 2));
8877 if (GET_CODE (operands[1]) == ABS)
8879 tmp = GEN_INT (0x7fff);
8880 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8884 tmp = GEN_INT (0x8000);
8885 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8890 ;; Conditionalize these after reload. If they match before reload, we
8891 ;; lose the clobber and ability to use integer instructions.
8893 (define_insn "*<code><mode>2_1"
8894 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8895 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8897 && (reload_completed
8898 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8899 "f<absneg_mnemonic>"
8900 [(set_attr "type" "fsgn")
8901 (set_attr "mode" "<MODE>")])
8903 (define_insn "*<code>extendsfdf2"
8904 [(set (match_operand:DF 0 "register_operand" "=f")
8905 (absneg:DF (float_extend:DF
8906 (match_operand:SF 1 "register_operand" "0"))))]
8907 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8908 "f<absneg_mnemonic>"
8909 [(set_attr "type" "fsgn")
8910 (set_attr "mode" "DF")])
8912 (define_insn "*<code>extendsfxf2"
8913 [(set (match_operand:XF 0 "register_operand" "=f")
8914 (absneg:XF (float_extend:XF
8915 (match_operand:SF 1 "register_operand" "0"))))]
8917 "f<absneg_mnemonic>"
8918 [(set_attr "type" "fsgn")
8919 (set_attr "mode" "XF")])
8921 (define_insn "*<code>extenddfxf2"
8922 [(set (match_operand:XF 0 "register_operand" "=f")
8923 (absneg:XF (float_extend:XF
8924 (match_operand:DF 1 "register_operand" "0"))))]
8926 "f<absneg_mnemonic>"
8927 [(set_attr "type" "fsgn")
8928 (set_attr "mode" "XF")])
8930 ;; Copysign instructions
8932 (define_mode_iterator CSGNMODE [SF DF TF])
8933 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8935 (define_expand "copysign<mode>3"
8936 [(match_operand:CSGNMODE 0 "register_operand" "")
8937 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8938 (match_operand:CSGNMODE 2 "register_operand" "")]
8939 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8940 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8941 "ix86_expand_copysign (operands); DONE;")
8943 (define_insn_and_split "copysign<mode>3_const"
8944 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8946 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8947 (match_operand:CSGNMODE 2 "register_operand" "0")
8948 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8950 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8951 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8953 "&& reload_completed"
8955 "ix86_split_copysign_const (operands); DONE;")
8957 (define_insn "copysign<mode>3_var"
8958 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8960 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8961 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8962 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8963 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8965 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8966 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8967 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8971 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8973 [(match_operand:CSGNMODE 2 "register_operand" "")
8974 (match_operand:CSGNMODE 3 "register_operand" "")
8975 (match_operand:<CSGNVMODE> 4 "" "")
8976 (match_operand:<CSGNVMODE> 5 "" "")]
8978 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8979 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8980 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8981 && reload_completed"
8983 "ix86_split_copysign_var (operands); DONE;")
8985 ;; One complement instructions
8987 (define_expand "one_cmpl<mode>2"
8988 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8989 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8991 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8993 (define_insn "*one_cmpl<mode>2_1"
8994 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8995 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8996 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8997 "not{<imodesuffix>}\t%0"
8998 [(set_attr "type" "negnot")
8999 (set_attr "mode" "<MODE>")])
9001 ;; %%% Potential partial reg stall on alternative 1. What to do?
9002 (define_insn "*one_cmplqi2_1"
9003 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9004 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9005 "ix86_unary_operator_ok (NOT, QImode, operands)"
9009 [(set_attr "type" "negnot")
9010 (set_attr "mode" "QI,SI")])
9012 ;; ??? Currently never generated - xor is used instead.
9013 (define_insn "*one_cmplsi2_1_zext"
9014 [(set (match_operand:DI 0 "register_operand" "=r")
9016 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9017 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9019 [(set_attr "type" "negnot")
9020 (set_attr "mode" "SI")])
9022 (define_insn "*one_cmpl<mode>2_2"
9023 [(set (reg FLAGS_REG)
9024 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9026 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9027 (not:SWI (match_dup 1)))]
9028 "ix86_match_ccmode (insn, CCNOmode)
9029 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9031 [(set_attr "type" "alu1")
9032 (set_attr "mode" "<MODE>")])
9035 [(set (match_operand 0 "flags_reg_operand" "")
9036 (match_operator 2 "compare_operator"
9037 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9039 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9040 (not:SWI (match_dup 3)))]
9041 "ix86_match_ccmode (insn, CCNOmode)"
9042 [(parallel [(set (match_dup 0)
9043 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9046 (xor:SWI (match_dup 3) (const_int -1)))])])
9048 ;; ??? Currently never generated - xor is used instead.
9049 (define_insn "*one_cmplsi2_2_zext"
9050 [(set (reg FLAGS_REG)
9051 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9053 (set (match_operand:DI 0 "register_operand" "=r")
9054 (zero_extend:DI (not:SI (match_dup 1))))]
9055 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9056 && ix86_unary_operator_ok (NOT, SImode, operands)"
9058 [(set_attr "type" "alu1")
9059 (set_attr "mode" "SI")])
9062 [(set (match_operand 0 "flags_reg_operand" "")
9063 (match_operator 2 "compare_operator"
9064 [(not:SI (match_operand:SI 3 "register_operand" ""))
9066 (set (match_operand:DI 1 "register_operand" "")
9067 (zero_extend:DI (not:SI (match_dup 3))))]
9068 "ix86_match_ccmode (insn, CCNOmode)"
9069 [(parallel [(set (match_dup 0)
9070 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9073 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9075 ;; Shift instructions
9077 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9078 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9079 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9080 ;; from the assembler input.
9082 ;; This instruction shifts the target reg/mem as usual, but instead of
9083 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9084 ;; is a left shift double, bits are taken from the high order bits of
9085 ;; reg, else if the insn is a shift right double, bits are taken from the
9086 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9087 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9089 ;; Since sh[lr]d does not change the `reg' operand, that is done
9090 ;; separately, making all shifts emit pairs of shift double and normal
9091 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9092 ;; support a 63 bit shift, each shift where the count is in a reg expands
9093 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9095 ;; If the shift count is a constant, we need never emit more than one
9096 ;; shift pair, instead using moves and sign extension for counts greater
9099 (define_expand "ashl<mode>3"
9100 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9101 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9102 (match_operand:QI 2 "nonmemory_operand" "")))]
9104 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9106 (define_insn "*ashl<mode>3_doubleword"
9107 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9108 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9109 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9110 (clobber (reg:CC FLAGS_REG))]
9113 [(set_attr "type" "multi")])
9116 [(set (match_operand:DWI 0 "register_operand" "")
9117 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9118 (match_operand:QI 2 "nonmemory_operand" "")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9122 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9124 ;; By default we don't ask for a scratch register, because when DWImode
9125 ;; values are manipulated, registers are already at a premium. But if
9126 ;; we have one handy, we won't turn it away.
9129 [(match_scratch:DWIH 3 "r")
9130 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9132 (match_operand:<DWI> 1 "nonmemory_operand" "")
9133 (match_operand:QI 2 "nonmemory_operand" "")))
9134 (clobber (reg:CC FLAGS_REG))])
9138 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9140 (define_insn "x86_64_shld"
9141 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9142 (ior:DI (ashift:DI (match_dup 0)
9143 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9144 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9145 (minus:QI (const_int 64) (match_dup 2)))))
9146 (clobber (reg:CC FLAGS_REG))]
9148 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9149 [(set_attr "type" "ishift")
9150 (set_attr "prefix_0f" "1")
9151 (set_attr "mode" "DI")
9152 (set_attr "athlon_decode" "vector")
9153 (set_attr "amdfam10_decode" "vector")
9154 (set_attr "bdver1_decode" "vector")])
9156 (define_insn "x86_shld"
9157 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9158 (ior:SI (ashift:SI (match_dup 0)
9159 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9161 (minus:QI (const_int 32) (match_dup 2)))))
9162 (clobber (reg:CC FLAGS_REG))]
9164 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9165 [(set_attr "type" "ishift")
9166 (set_attr "prefix_0f" "1")
9167 (set_attr "mode" "SI")
9168 (set_attr "pent_pair" "np")
9169 (set_attr "athlon_decode" "vector")
9170 (set_attr "amdfam10_decode" "vector")
9171 (set_attr "bdver1_decode" "vector")])
9173 (define_expand "x86_shift<mode>_adj_1"
9174 [(set (reg:CCZ FLAGS_REG)
9175 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9178 (set (match_operand:SWI48 0 "register_operand" "")
9179 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9180 (match_operand:SWI48 1 "register_operand" "")
9183 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9184 (match_operand:SWI48 3 "register_operand" "r")
9187 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9189 (define_expand "x86_shift<mode>_adj_2"
9190 [(use (match_operand:SWI48 0 "register_operand" ""))
9191 (use (match_operand:SWI48 1 "register_operand" ""))
9192 (use (match_operand:QI 2 "register_operand" ""))]
9195 rtx label = gen_label_rtx ();
9198 emit_insn (gen_testqi_ccz_1 (operands[2],
9199 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9201 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9202 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9203 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9204 gen_rtx_LABEL_REF (VOIDmode, label),
9206 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9207 JUMP_LABEL (tmp) = label;
9209 emit_move_insn (operands[0], operands[1]);
9210 ix86_expand_clear (operands[1]);
9213 LABEL_NUSES (label) = 1;
9218 ;; Avoid useless masking of count operand.
9219 (define_insn_and_split "*ashl<mode>3_mask"
9220 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9222 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9225 (match_operand:SI 2 "nonimmediate_operand" "c")
9226 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9229 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9230 == GET_MODE_BITSIZE (<MODE>mode)-1"
9233 [(parallel [(set (match_dup 0)
9234 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9235 (clobber (reg:CC FLAGS_REG))])]
9237 if (can_create_pseudo_p ())
9238 operands [2] = force_reg (SImode, operands[2]);
9240 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9242 [(set_attr "type" "ishift")
9243 (set_attr "mode" "<MODE>")])
9245 (define_insn "*ashl<mode>3_1"
9246 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9247 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9248 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9252 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260 return "add{<imodesuffix>}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{<imodesuffix>}\t%0";
9267 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9271 (cond [(eq_attr "alternative" "1")
9272 (const_string "lea")
9273 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 0 "register_operand" ""))
9276 (match_operand 2 "const1_operand" ""))
9277 (const_string "alu")
9279 (const_string "ishift")))
9280 (set (attr "length_immediate")
9282 (ior (eq_attr "type" "alu")
9283 (and (eq_attr "type" "ishift")
9284 (and (match_operand 2 "const1_operand" "")
9285 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9288 (const_string "*")))
9289 (set_attr "mode" "<MODE>")])
9291 (define_insn "*ashlsi3_1_zext"
9292 [(set (match_operand:DI 0 "register_operand" "=r,r")
9294 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9295 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9299 switch (get_attr_type (insn))
9305 gcc_assert (operands[2] == const1_rtx);
9306 return "add{l}\t%k0, %k0";
9309 if (operands[2] == const1_rtx
9310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 return "sal{l}\t%k0";
9313 return "sal{l}\t{%2, %k0|%k0, %2}";
9317 (cond [(eq_attr "alternative" "1")
9318 (const_string "lea")
9319 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9321 (match_operand 2 "const1_operand" ""))
9322 (const_string "alu")
9324 (const_string "ishift")))
9325 (set (attr "length_immediate")
9327 (ior (eq_attr "type" "alu")
9328 (and (eq_attr "type" "ishift")
9329 (and (match_operand 2 "const1_operand" "")
9330 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9333 (const_string "*")))
9334 (set_attr "mode" "SI")])
9336 (define_insn "*ashlhi3_1"
9337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9338 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9339 (match_operand:QI 2 "nonmemory_operand" "cI")))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "TARGET_PARTIAL_REG_STALL
9342 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9344 switch (get_attr_type (insn))
9347 gcc_assert (operands[2] == const1_rtx);
9348 return "add{w}\t%0, %0";
9351 if (operands[2] == const1_rtx
9352 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9353 return "sal{w}\t%0";
9355 return "sal{w}\t{%2, %0|%0, %2}";
9359 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9361 (match_operand 0 "register_operand" ""))
9362 (match_operand 2 "const1_operand" ""))
9363 (const_string "alu")
9365 (const_string "ishift")))
9366 (set (attr "length_immediate")
9368 (ior (eq_attr "type" "alu")
9369 (and (eq_attr "type" "ishift")
9370 (and (match_operand 2 "const1_operand" "")
9371 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9374 (const_string "*")))
9375 (set_attr "mode" "HI")])
9377 (define_insn "*ashlhi3_1_lea"
9378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9379 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9380 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "!TARGET_PARTIAL_REG_STALL
9383 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9385 switch (get_attr_type (insn))
9391 gcc_assert (operands[2] == const1_rtx);
9392 return "add{w}\t%0, %0";
9395 if (operands[2] == const1_rtx
9396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9397 return "sal{w}\t%0";
9399 return "sal{w}\t{%2, %0|%0, %2}";
9403 (cond [(eq_attr "alternative" "1")
9404 (const_string "lea")
9405 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9407 (match_operand 0 "register_operand" ""))
9408 (match_operand 2 "const1_operand" ""))
9409 (const_string "alu")
9411 (const_string "ishift")))
9412 (set (attr "length_immediate")
9414 (ior (eq_attr "type" "alu")
9415 (and (eq_attr "type" "ishift")
9416 (and (match_operand 2 "const1_operand" "")
9417 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9420 (const_string "*")))
9421 (set_attr "mode" "HI,SI")])
9423 (define_insn "*ashlqi3_1"
9424 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9425 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9426 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_PARTIAL_REG_STALL
9429 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9431 switch (get_attr_type (insn))
9434 gcc_assert (operands[2] == const1_rtx);
9435 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9436 return "add{l}\t%k0, %k0";
9438 return "add{b}\t%0, %0";
9441 if (operands[2] == const1_rtx
9442 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9444 if (get_attr_mode (insn) == MODE_SI)
9445 return "sal{l}\t%k0";
9447 return "sal{b}\t%0";
9451 if (get_attr_mode (insn) == MODE_SI)
9452 return "sal{l}\t{%2, %k0|%k0, %2}";
9454 return "sal{b}\t{%2, %0|%0, %2}";
9459 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9461 (match_operand 0 "register_operand" ""))
9462 (match_operand 2 "const1_operand" ""))
9463 (const_string "alu")
9465 (const_string "ishift")))
9466 (set (attr "length_immediate")
9468 (ior (eq_attr "type" "alu")
9469 (and (eq_attr "type" "ishift")
9470 (and (match_operand 2 "const1_operand" "")
9471 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9474 (const_string "*")))
9475 (set_attr "mode" "QI,SI")])
9477 ;; %%% Potential partial reg stall on alternative 2. What to do?
9478 (define_insn "*ashlqi3_1_lea"
9479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9480 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9481 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9482 (clobber (reg:CC FLAGS_REG))]
9483 "!TARGET_PARTIAL_REG_STALL
9484 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9486 switch (get_attr_type (insn))
9492 gcc_assert (operands[2] == const1_rtx);
9493 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9494 return "add{l}\t%k0, %k0";
9496 return "add{b}\t%0, %0";
9499 if (operands[2] == const1_rtx
9500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502 if (get_attr_mode (insn) == MODE_SI)
9503 return "sal{l}\t%k0";
9505 return "sal{b}\t%0";
9509 if (get_attr_mode (insn) == MODE_SI)
9510 return "sal{l}\t{%2, %k0|%k0, %2}";
9512 return "sal{b}\t{%2, %0|%0, %2}";
9517 (cond [(eq_attr "alternative" "2")
9518 (const_string "lea")
9519 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 0 "register_operand" ""))
9522 (match_operand 2 "const1_operand" ""))
9523 (const_string "alu")
9525 (const_string "ishift")))
9526 (set (attr "length_immediate")
9528 (ior (eq_attr "type" "alu")
9529 (and (eq_attr "type" "ishift")
9530 (and (match_operand 2 "const1_operand" "")
9531 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9534 (const_string "*")))
9535 (set_attr "mode" "QI,SI,SI")])
9537 (define_insn "*ashlqi3_1_slp"
9538 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9539 (ashift:QI (match_dup 0)
9540 (match_operand:QI 1 "nonmemory_operand" "cI")))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "(optimize_function_for_size_p (cfun)
9543 || !TARGET_PARTIAL_FLAG_REG_STALL
9544 || (operands[1] == const1_rtx
9546 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9548 switch (get_attr_type (insn))
9551 gcc_assert (operands[1] == const1_rtx);
9552 return "add{b}\t%0, %0";
9555 if (operands[1] == const1_rtx
9556 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557 return "sal{b}\t%0";
9559 return "sal{b}\t{%1, %0|%0, %1}";
9563 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9565 (match_operand 0 "register_operand" ""))
9566 (match_operand 1 "const1_operand" ""))
9567 (const_string "alu")
9569 (const_string "ishift1")))
9570 (set (attr "length_immediate")
9572 (ior (eq_attr "type" "alu")
9573 (and (eq_attr "type" "ishift1")
9574 (and (match_operand 1 "const1_operand" "")
9575 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578 (const_string "*")))
9579 (set_attr "mode" "QI")])
9581 ;; Convert lea to the lea pattern to avoid flags dependency.
9583 [(set (match_operand 0 "register_operand" "")
9584 (ashift (match_operand 1 "index_register_operand" "")
9585 (match_operand:QI 2 "const_int_operand" "")))
9586 (clobber (reg:CC FLAGS_REG))]
9588 && true_regnum (operands[0]) != true_regnum (operands[1])"
9592 enum machine_mode mode = GET_MODE (operands[0]);
9595 operands[1] = gen_lowpart (Pmode, operands[1]);
9596 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9598 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9600 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9601 operands[0] = gen_lowpart (SImode, operands[0]);
9603 if (TARGET_64BIT && mode != Pmode)
9604 pat = gen_rtx_SUBREG (SImode, pat, 0);
9606 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9610 ;; Convert lea to the lea pattern to avoid flags dependency.
9612 [(set (match_operand:DI 0 "register_operand" "")
9614 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9615 (match_operand:QI 2 "const_int_operand" ""))))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "TARGET_64BIT && reload_completed
9618 && true_regnum (operands[0]) != true_regnum (operands[1])"
9620 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9622 operands[1] = gen_lowpart (DImode, operands[1]);
9623 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9626 ;; This pattern can't accept a variable shift count, since shifts by
9627 ;; zero don't affect the flags. We assume that shifts by constant
9628 ;; zero are optimized away.
9629 (define_insn "*ashl<mode>3_cmp"
9630 [(set (reg FLAGS_REG)
9632 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9633 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9635 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9636 (ashift:SWI (match_dup 1) (match_dup 2)))]
9637 "(optimize_function_for_size_p (cfun)
9638 || !TARGET_PARTIAL_FLAG_REG_STALL
9639 || (operands[2] == const1_rtx
9641 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9642 && ix86_match_ccmode (insn, CCGOCmode)
9643 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9645 switch (get_attr_type (insn))
9648 gcc_assert (operands[2] == const1_rtx);
9649 return "add{<imodesuffix>}\t%0, %0";
9652 if (operands[2] == const1_rtx
9653 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9654 return "sal{<imodesuffix>}\t%0";
9656 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9660 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9662 (match_operand 0 "register_operand" ""))
9663 (match_operand 2 "const1_operand" ""))
9664 (const_string "alu")
9666 (const_string "ishift")))
9667 (set (attr "length_immediate")
9669 (ior (eq_attr "type" "alu")
9670 (and (eq_attr "type" "ishift")
9671 (and (match_operand 2 "const1_operand" "")
9672 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9675 (const_string "*")))
9676 (set_attr "mode" "<MODE>")])
9678 (define_insn "*ashlsi3_cmp_zext"
9679 [(set (reg FLAGS_REG)
9681 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9682 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9684 (set (match_operand:DI 0 "register_operand" "=r")
9685 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9687 && (optimize_function_for_size_p (cfun)
9688 || !TARGET_PARTIAL_FLAG_REG_STALL
9689 || (operands[2] == const1_rtx
9691 || TARGET_DOUBLE_WITH_ADD)))
9692 && ix86_match_ccmode (insn, CCGOCmode)
9693 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9695 switch (get_attr_type (insn))
9698 gcc_assert (operands[2] == const1_rtx);
9699 return "add{l}\t%k0, %k0";
9702 if (operands[2] == const1_rtx
9703 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9704 return "sal{l}\t%k0";
9706 return "sal{l}\t{%2, %k0|%k0, %2}";
9710 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9712 (match_operand 2 "const1_operand" ""))
9713 (const_string "alu")
9715 (const_string "ishift")))
9716 (set (attr "length_immediate")
9718 (ior (eq_attr "type" "alu")
9719 (and (eq_attr "type" "ishift")
9720 (and (match_operand 2 "const1_operand" "")
9721 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9724 (const_string "*")))
9725 (set_attr "mode" "SI")])
9727 (define_insn "*ashl<mode>3_cconly"
9728 [(set (reg FLAGS_REG)
9730 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9731 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9733 (clobber (match_scratch:SWI 0 "=<r>"))]
9734 "(optimize_function_for_size_p (cfun)
9735 || !TARGET_PARTIAL_FLAG_REG_STALL
9736 || (operands[2] == const1_rtx
9738 || TARGET_DOUBLE_WITH_ADD)))
9739 && ix86_match_ccmode (insn, CCGOCmode)"
9741 switch (get_attr_type (insn))
9744 gcc_assert (operands[2] == const1_rtx);
9745 return "add{<imodesuffix>}\t%0, %0";
9748 if (operands[2] == const1_rtx
9749 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9750 return "sal{<imodesuffix>}\t%0";
9752 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9756 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9758 (match_operand 0 "register_operand" ""))
9759 (match_operand 2 "const1_operand" ""))
9760 (const_string "alu")
9762 (const_string "ishift")))
9763 (set (attr "length_immediate")
9765 (ior (eq_attr "type" "alu")
9766 (and (eq_attr "type" "ishift")
9767 (and (match_operand 2 "const1_operand" "")
9768 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9771 (const_string "*")))
9772 (set_attr "mode" "<MODE>")])
9774 ;; See comment above `ashl<mode>3' about how this works.
9776 (define_expand "<shiftrt_insn><mode>3"
9777 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9778 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9779 (match_operand:QI 2 "nonmemory_operand" "")))]
9781 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9783 ;; Avoid useless masking of count operand.
9784 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9785 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9787 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9790 (match_operand:SI 2 "nonimmediate_operand" "c")
9791 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9794 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9795 == GET_MODE_BITSIZE (<MODE>mode)-1"
9798 [(parallel [(set (match_dup 0)
9799 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9800 (clobber (reg:CC FLAGS_REG))])]
9802 if (can_create_pseudo_p ())
9803 operands [2] = force_reg (SImode, operands[2]);
9805 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9807 [(set_attr "type" "ishift")
9808 (set_attr "mode" "<MODE>")])
9810 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9811 [(set (match_operand:DWI 0 "register_operand" "=r")
9812 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9813 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9814 (clobber (reg:CC FLAGS_REG))]
9817 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9819 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9820 [(set_attr "type" "multi")])
9822 ;; By default we don't ask for a scratch register, because when DWImode
9823 ;; values are manipulated, registers are already at a premium. But if
9824 ;; we have one handy, we won't turn it away.
9827 [(match_scratch:DWIH 3 "r")
9828 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9830 (match_operand:<DWI> 1 "register_operand" "")
9831 (match_operand:QI 2 "nonmemory_operand" "")))
9832 (clobber (reg:CC FLAGS_REG))])
9836 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9838 (define_insn "x86_64_shrd"
9839 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9840 (ior:DI (ashiftrt:DI (match_dup 0)
9841 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9842 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9843 (minus:QI (const_int 64) (match_dup 2)))))
9844 (clobber (reg:CC FLAGS_REG))]
9846 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9847 [(set_attr "type" "ishift")
9848 (set_attr "prefix_0f" "1")
9849 (set_attr "mode" "DI")
9850 (set_attr "athlon_decode" "vector")
9851 (set_attr "amdfam10_decode" "vector")
9852 (set_attr "bdver1_decode" "vector")])
9854 (define_insn "x86_shrd"
9855 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9856 (ior:SI (ashiftrt:SI (match_dup 0)
9857 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9858 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9859 (minus:QI (const_int 32) (match_dup 2)))))
9860 (clobber (reg:CC FLAGS_REG))]
9862 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9863 [(set_attr "type" "ishift")
9864 (set_attr "prefix_0f" "1")
9865 (set_attr "mode" "SI")
9866 (set_attr "pent_pair" "np")
9867 (set_attr "athlon_decode" "vector")
9868 (set_attr "amdfam10_decode" "vector")
9869 (set_attr "bdver1_decode" "vector")])
9871 (define_insn "ashrdi3_cvt"
9872 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9873 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9874 (match_operand:QI 2 "const_int_operand" "")))
9875 (clobber (reg:CC FLAGS_REG))]
9876 "TARGET_64BIT && INTVAL (operands[2]) == 63
9877 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9878 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9881 sar{q}\t{%2, %0|%0, %2}"
9882 [(set_attr "type" "imovx,ishift")
9883 (set_attr "prefix_0f" "0,*")
9884 (set_attr "length_immediate" "0,*")
9885 (set_attr "modrm" "0,1")
9886 (set_attr "mode" "DI")])
9888 (define_insn "ashrsi3_cvt"
9889 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9890 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9891 (match_operand:QI 2 "const_int_operand" "")))
9892 (clobber (reg:CC FLAGS_REG))]
9893 "INTVAL (operands[2]) == 31
9894 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9895 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9898 sar{l}\t{%2, %0|%0, %2}"
9899 [(set_attr "type" "imovx,ishift")
9900 (set_attr "prefix_0f" "0,*")
9901 (set_attr "length_immediate" "0,*")
9902 (set_attr "modrm" "0,1")
9903 (set_attr "mode" "SI")])
9905 (define_insn "*ashrsi3_cvt_zext"
9906 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9908 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9909 (match_operand:QI 2 "const_int_operand" ""))))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "TARGET_64BIT && INTVAL (operands[2]) == 31
9912 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9913 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9916 sar{l}\t{%2, %k0|%k0, %2}"
9917 [(set_attr "type" "imovx,ishift")
9918 (set_attr "prefix_0f" "0,*")
9919 (set_attr "length_immediate" "0,*")
9920 (set_attr "modrm" "0,1")
9921 (set_attr "mode" "SI")])
9923 (define_expand "x86_shift<mode>_adj_3"
9924 [(use (match_operand:SWI48 0 "register_operand" ""))
9925 (use (match_operand:SWI48 1 "register_operand" ""))
9926 (use (match_operand:QI 2 "register_operand" ""))]
9929 rtx label = gen_label_rtx ();
9932 emit_insn (gen_testqi_ccz_1 (operands[2],
9933 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9935 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9936 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9937 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9938 gen_rtx_LABEL_REF (VOIDmode, label),
9940 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9941 JUMP_LABEL (tmp) = label;
9943 emit_move_insn (operands[0], operands[1]);
9944 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9945 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9947 LABEL_NUSES (label) = 1;
9952 (define_insn "*<shiftrt_insn><mode>3_1"
9953 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9954 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9955 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9959 if (operands[2] == const1_rtx
9960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961 return "<shiftrt>{<imodesuffix>}\t%0";
9963 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9965 [(set_attr "type" "ishift")
9966 (set (attr "length_immediate")
9968 (and (match_operand 2 "const1_operand" "")
9969 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9972 (const_string "*")))
9973 (set_attr "mode" "<MODE>")])
9975 (define_insn "*<shiftrt_insn>si3_1_zext"
9976 [(set (match_operand:DI 0 "register_operand" "=r")
9978 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9979 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9980 (clobber (reg:CC FLAGS_REG))]
9981 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9983 if (operands[2] == const1_rtx
9984 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985 return "<shiftrt>{l}\t%k0";
9987 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9989 [(set_attr "type" "ishift")
9990 (set (attr "length_immediate")
9992 (and (match_operand 2 "const1_operand" "")
9993 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9996 (const_string "*")))
9997 (set_attr "mode" "SI")])
9999 (define_insn "*<shiftrt_insn>qi3_1_slp"
10000 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10001 (any_shiftrt:QI (match_dup 0)
10002 (match_operand:QI 1 "nonmemory_operand" "cI")))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "(optimize_function_for_size_p (cfun)
10005 || !TARGET_PARTIAL_REG_STALL
10006 || (operands[1] == const1_rtx
10007 && TARGET_SHIFT1))"
10009 if (operands[1] == const1_rtx
10010 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10011 return "<shiftrt>{b}\t%0";
10013 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10015 [(set_attr "type" "ishift1")
10016 (set (attr "length_immediate")
10018 (and (match_operand 1 "const1_operand" "")
10019 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10022 (const_string "*")))
10023 (set_attr "mode" "QI")])
10025 ;; This pattern can't accept a variable shift count, since shifts by
10026 ;; zero don't affect the flags. We assume that shifts by constant
10027 ;; zero are optimized away.
10028 (define_insn "*<shiftrt_insn><mode>3_cmp"
10029 [(set (reg FLAGS_REG)
10032 (match_operand:SWI 1 "nonimmediate_operand" "0")
10033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10035 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10036 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10037 "(optimize_function_for_size_p (cfun)
10038 || !TARGET_PARTIAL_FLAG_REG_STALL
10039 || (operands[2] == const1_rtx
10041 && ix86_match_ccmode (insn, CCGOCmode)
10042 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10044 if (operands[2] == const1_rtx
10045 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10046 return "<shiftrt>{<imodesuffix>}\t%0";
10048 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10050 [(set_attr "type" "ishift")
10051 (set (attr "length_immediate")
10053 (and (match_operand 2 "const1_operand" "")
10054 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10057 (const_string "*")))
10058 (set_attr "mode" "<MODE>")])
10060 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10061 [(set (reg FLAGS_REG)
10063 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10064 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10066 (set (match_operand:DI 0 "register_operand" "=r")
10067 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10069 && (optimize_function_for_size_p (cfun)
10070 || !TARGET_PARTIAL_FLAG_REG_STALL
10071 || (operands[2] == const1_rtx
10073 && ix86_match_ccmode (insn, CCGOCmode)
10074 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10076 if (operands[2] == const1_rtx
10077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078 return "<shiftrt>{l}\t%k0";
10080 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10082 [(set_attr "type" "ishift")
10083 (set (attr "length_immediate")
10085 (and (match_operand 2 "const1_operand" "")
10086 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10089 (const_string "*")))
10090 (set_attr "mode" "SI")])
10092 (define_insn "*<shiftrt_insn><mode>3_cconly"
10093 [(set (reg FLAGS_REG)
10096 (match_operand:SWI 1 "register_operand" "0")
10097 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10099 (clobber (match_scratch:SWI 0 "=<r>"))]
10100 "(optimize_function_for_size_p (cfun)
10101 || !TARGET_PARTIAL_FLAG_REG_STALL
10102 || (operands[2] == const1_rtx
10104 && ix86_match_ccmode (insn, CCGOCmode)"
10106 if (operands[2] == const1_rtx
10107 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108 return "<shiftrt>{<imodesuffix>}\t%0";
10110 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10112 [(set_attr "type" "ishift")
10113 (set (attr "length_immediate")
10115 (and (match_operand 2 "const1_operand" "")
10116 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10122 ;; Rotate instructions
10124 (define_expand "<rotate_insn>ti3"
10125 [(set (match_operand:TI 0 "register_operand" "")
10126 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10127 (match_operand:QI 2 "nonmemory_operand" "")))]
10130 if (const_1_to_63_operand (operands[2], VOIDmode))
10131 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10132 (operands[0], operands[1], operands[2]));
10139 (define_expand "<rotate_insn>di3"
10140 [(set (match_operand:DI 0 "shiftdi_operand" "")
10141 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10142 (match_operand:QI 2 "nonmemory_operand" "")))]
10146 ix86_expand_binary_operator (<CODE>, DImode, operands);
10147 else if (const_1_to_31_operand (operands[2], VOIDmode))
10148 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10149 (operands[0], operands[1], operands[2]));
10156 (define_expand "<rotate_insn><mode>3"
10157 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10158 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10159 (match_operand:QI 2 "nonmemory_operand" "")))]
10161 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10163 ;; Avoid useless masking of count operand.
10164 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10165 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10167 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10170 (match_operand:SI 2 "nonimmediate_operand" "c")
10171 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10172 (clobber (reg:CC FLAGS_REG))]
10173 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10174 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10175 == GET_MODE_BITSIZE (<MODE>mode)-1"
10178 [(parallel [(set (match_dup 0)
10179 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10180 (clobber (reg:CC FLAGS_REG))])]
10182 if (can_create_pseudo_p ())
10183 operands [2] = force_reg (SImode, operands[2]);
10185 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10187 [(set_attr "type" "rotate")
10188 (set_attr "mode" "<MODE>")])
10190 ;; Implement rotation using two double-precision
10191 ;; shift instructions and a scratch register.
10193 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10194 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197 (clobber (reg:CC FLAGS_REG))
10198 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 [(set (match_dup 3) (match_dup 4))
10204 [(set (match_dup 4)
10205 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10206 (lshiftrt:DWIH (match_dup 5)
10207 (minus:QI (match_dup 6) (match_dup 2)))))
10208 (clobber (reg:CC FLAGS_REG))])
10210 [(set (match_dup 5)
10211 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10212 (lshiftrt:DWIH (match_dup 3)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])]
10216 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10222 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225 (clobber (reg:CC FLAGS_REG))
10226 (clobber (match_scratch:DWIH 3 "=&r"))]
10230 [(set (match_dup 3) (match_dup 4))
10232 [(set (match_dup 4)
10233 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10234 (ashift:DWIH (match_dup 5)
10235 (minus:QI (match_dup 6) (match_dup 2)))))
10236 (clobber (reg:CC FLAGS_REG))])
10238 [(set (match_dup 5)
10239 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10240 (ashift:DWIH (match_dup 3)
10241 (minus:QI (match_dup 6) (match_dup 2)))))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10246 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 (define_insn "*<rotate_insn><mode>3_1"
10250 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10251 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10252 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10256 if (operands[2] == const1_rtx
10257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258 return "<rotate>{<imodesuffix>}\t%0";
10260 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10262 [(set_attr "type" "rotate")
10263 (set (attr "length_immediate")
10265 (and (match_operand 2 "const1_operand" "")
10266 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10269 (const_string "*")))
10270 (set_attr "mode" "<MODE>")])
10272 (define_insn "*<rotate_insn>si3_1_zext"
10273 [(set (match_operand:DI 0 "register_operand" "=r")
10275 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10276 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10277 (clobber (reg:CC FLAGS_REG))]
10278 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10280 if (operands[2] == const1_rtx
10281 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10282 return "<rotate>{l}\t%k0";
10284 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10286 [(set_attr "type" "rotate")
10287 (set (attr "length_immediate")
10289 (and (match_operand 2 "const1_operand" "")
10290 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10293 (const_string "*")))
10294 (set_attr "mode" "SI")])
10296 (define_insn "*<rotate_insn>qi3_1_slp"
10297 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10298 (any_rotate:QI (match_dup 0)
10299 (match_operand:QI 1 "nonmemory_operand" "cI")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "(optimize_function_for_size_p (cfun)
10302 || !TARGET_PARTIAL_REG_STALL
10303 || (operands[1] == const1_rtx
10304 && TARGET_SHIFT1))"
10306 if (operands[1] == const1_rtx
10307 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10308 return "<rotate>{b}\t%0";
10310 return "<rotate>{b}\t{%1, %0|%0, %1}";
10312 [(set_attr "type" "rotate1")
10313 (set (attr "length_immediate")
10315 (and (match_operand 1 "const1_operand" "")
10316 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10319 (const_string "*")))
10320 (set_attr "mode" "QI")])
10323 [(set (match_operand:HI 0 "register_operand" "")
10324 (any_rotate:HI (match_dup 0) (const_int 8)))
10325 (clobber (reg:CC FLAGS_REG))]
10327 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10328 [(parallel [(set (strict_low_part (match_dup 0))
10329 (bswap:HI (match_dup 0)))
10330 (clobber (reg:CC FLAGS_REG))])])
10332 ;; Bit set / bit test instructions
10334 (define_expand "extv"
10335 [(set (match_operand:SI 0 "register_operand" "")
10336 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10337 (match_operand:SI 2 "const8_operand" "")
10338 (match_operand:SI 3 "const8_operand" "")))]
10341 /* Handle extractions from %ah et al. */
10342 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10345 /* From mips.md: extract_bit_field doesn't verify that our source
10346 matches the predicate, so check it again here. */
10347 if (! ext_register_operand (operands[1], VOIDmode))
10351 (define_expand "extzv"
10352 [(set (match_operand:SI 0 "register_operand" "")
10353 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10354 (match_operand:SI 2 "const8_operand" "")
10355 (match_operand:SI 3 "const8_operand" "")))]
10358 /* Handle extractions from %ah et al. */
10359 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10362 /* From mips.md: extract_bit_field doesn't verify that our source
10363 matches the predicate, so check it again here. */
10364 if (! ext_register_operand (operands[1], VOIDmode))
10368 (define_expand "insv"
10369 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10370 (match_operand 1 "const8_operand" "")
10371 (match_operand 2 "const8_operand" ""))
10372 (match_operand 3 "register_operand" ""))]
10375 rtx (*gen_mov_insv_1) (rtx, rtx);
10377 /* Handle insertions to %ah et al. */
10378 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10381 /* From mips.md: insert_bit_field doesn't verify that our source
10382 matches the predicate, so check it again here. */
10383 if (! ext_register_operand (operands[0], VOIDmode))
10386 gen_mov_insv_1 = (TARGET_64BIT
10387 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10389 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10393 ;; %%% bts, btr, btc, bt.
10394 ;; In general these instructions are *slow* when applied to memory,
10395 ;; since they enforce atomic operation. When applied to registers,
10396 ;; it depends on the cpu implementation. They're never faster than
10397 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10398 ;; no point. But in 64-bit, we can't hold the relevant immediates
10399 ;; within the instruction itself, so operating on bits in the high
10400 ;; 32-bits of a register becomes easier.
10402 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10403 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10404 ;; negdf respectively, so they can never be disabled entirely.
10406 (define_insn "*btsq"
10407 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10409 (match_operand:DI 1 "const_0_to_63_operand" ""))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10413 "bts{q}\t{%1, %0|%0, %1}"
10414 [(set_attr "type" "alu1")
10415 (set_attr "prefix_0f" "1")
10416 (set_attr "mode" "DI")])
10418 (define_insn "*btrq"
10419 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10421 (match_operand:DI 1 "const_0_to_63_operand" ""))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10425 "btr{q}\t{%1, %0|%0, %1}"
10426 [(set_attr "type" "alu1")
10427 (set_attr "prefix_0f" "1")
10428 (set_attr "mode" "DI")])
10430 (define_insn "*btcq"
10431 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10433 (match_operand:DI 1 "const_0_to_63_operand" ""))
10434 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10437 "btc{q}\t{%1, %0|%0, %1}"
10438 [(set_attr "type" "alu1")
10439 (set_attr "prefix_0f" "1")
10440 (set_attr "mode" "DI")])
10442 ;; Allow Nocona to avoid these instructions if a register is available.
10445 [(match_scratch:DI 2 "r")
10446 (parallel [(set (zero_extract:DI
10447 (match_operand:DI 0 "register_operand" "")
10449 (match_operand:DI 1 "const_0_to_63_operand" ""))
10451 (clobber (reg:CC FLAGS_REG))])]
10452 "TARGET_64BIT && !TARGET_USE_BT"
10455 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10458 if (HOST_BITS_PER_WIDE_INT >= 64)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 else if (i < HOST_BITS_PER_WIDE_INT)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10463 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10465 op1 = immed_double_const (lo, hi, DImode);
10468 emit_move_insn (operands[2], op1);
10472 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10477 [(match_scratch:DI 2 "r")
10478 (parallel [(set (zero_extract:DI
10479 (match_operand:DI 0 "register_operand" "")
10481 (match_operand:DI 1 "const_0_to_63_operand" ""))
10483 (clobber (reg:CC FLAGS_REG))])]
10484 "TARGET_64BIT && !TARGET_USE_BT"
10487 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10490 if (HOST_BITS_PER_WIDE_INT >= 64)
10491 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492 else if (i < HOST_BITS_PER_WIDE_INT)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10495 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10497 op1 = immed_double_const (~lo, ~hi, DImode);
10500 emit_move_insn (operands[2], op1);
10504 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10509 [(match_scratch:DI 2 "r")
10510 (parallel [(set (zero_extract:DI
10511 (match_operand:DI 0 "register_operand" "")
10513 (match_operand:DI 1 "const_0_to_63_operand" ""))
10514 (not:DI (zero_extract:DI
10515 (match_dup 0) (const_int 1) (match_dup 1))))
10516 (clobber (reg:CC FLAGS_REG))])]
10517 "TARGET_64BIT && !TARGET_USE_BT"
10520 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10523 if (HOST_BITS_PER_WIDE_INT >= 64)
10524 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 else if (i < HOST_BITS_PER_WIDE_INT)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10528 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10530 op1 = immed_double_const (lo, hi, DImode);
10533 emit_move_insn (operands[2], op1);
10537 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10541 (define_insn "*bt<mode>"
10542 [(set (reg:CCC FLAGS_REG)
10544 (zero_extract:SWI48
10545 (match_operand:SWI48 0 "register_operand" "r")
10547 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10549 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10550 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10551 [(set_attr "type" "alu1")
10552 (set_attr "prefix_0f" "1")
10553 (set_attr "mode" "<MODE>")])
10555 ;; Store-flag instructions.
10557 ;; For all sCOND expanders, also expand the compare or test insn that
10558 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10560 (define_insn_and_split "*setcc_di_1"
10561 [(set (match_operand:DI 0 "register_operand" "=q")
10562 (match_operator:DI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))]
10564 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10566 "&& reload_completed"
10567 [(set (match_dup 2) (match_dup 1))
10568 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10570 PUT_MODE (operands[1], QImode);
10571 operands[2] = gen_lowpart (QImode, operands[0]);
10574 (define_insn_and_split "*setcc_si_1_and"
10575 [(set (match_operand:SI 0 "register_operand" "=q")
10576 (match_operator:SI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "!TARGET_PARTIAL_REG_STALL
10580 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10582 "&& reload_completed"
10583 [(set (match_dup 2) (match_dup 1))
10584 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10585 (clobber (reg:CC FLAGS_REG))])]
10587 PUT_MODE (operands[1], QImode);
10588 operands[2] = gen_lowpart (QImode, operands[0]);
10591 (define_insn_and_split "*setcc_si_1_movzbl"
10592 [(set (match_operand:SI 0 "register_operand" "=q")
10593 (match_operator:SI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10595 "!TARGET_PARTIAL_REG_STALL
10596 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10598 "&& reload_completed"
10599 [(set (match_dup 2) (match_dup 1))
10600 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10602 PUT_MODE (operands[1], QImode);
10603 operands[2] = gen_lowpart (QImode, operands[0]);
10606 (define_insn "*setcc_qi"
10607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10608 (match_operator:QI 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)]))]
10612 [(set_attr "type" "setcc")
10613 (set_attr "mode" "QI")])
10615 (define_insn "*setcc_qi_slp"
10616 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10617 (match_operator:QI 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)]))]
10621 [(set_attr "type" "setcc")
10622 (set_attr "mode" "QI")])
10624 ;; In general it is not safe to assume too much about CCmode registers,
10625 ;; so simplify-rtx stops when it sees a second one. Under certain
10626 ;; conditions this is safe on x86, so help combine not create
10633 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10634 (ne:QI (match_operator 1 "ix86_comparison_operator"
10635 [(reg FLAGS_REG) (const_int 0)])
10638 [(set (match_dup 0) (match_dup 1))]
10639 "PUT_MODE (operands[1], QImode);")
10642 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10643 (ne:QI (match_operator 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)])
10647 [(set (match_dup 0) (match_dup 1))]
10648 "PUT_MODE (operands[1], QImode);")
10651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10652 (eq:QI (match_operator 1 "ix86_comparison_operator"
10653 [(reg FLAGS_REG) (const_int 0)])
10656 [(set (match_dup 0) (match_dup 1))]
10658 rtx new_op1 = copy_rtx (operands[1]);
10659 operands[1] = new_op1;
10660 PUT_MODE (new_op1, QImode);
10661 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10662 GET_MODE (XEXP (new_op1, 0))));
10664 /* Make sure that (a) the CCmode we have for the flags is strong
10665 enough for the reversed compare or (b) we have a valid FP compare. */
10666 if (! ix86_comparison_operator (new_op1, VOIDmode))
10671 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10672 (eq:QI (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10676 [(set (match_dup 0) (match_dup 1))]
10678 rtx new_op1 = copy_rtx (operands[1]);
10679 operands[1] = new_op1;
10680 PUT_MODE (new_op1, QImode);
10681 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10682 GET_MODE (XEXP (new_op1, 0))));
10684 /* Make sure that (a) the CCmode we have for the flags is strong
10685 enough for the reversed compare or (b) we have a valid FP compare. */
10686 if (! ix86_comparison_operator (new_op1, VOIDmode))
10690 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10691 ;; subsequent logical operations are used to imitate conditional moves.
10692 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10695 (define_insn "*avx_setcc<mode>"
10696 [(set (match_operand:MODEF 0 "register_operand" "=x")
10697 (match_operator:MODEF 1 "avx_comparison_float_operator"
10698 [(match_operand:MODEF 2 "register_operand" "x")
10699 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10701 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10702 [(set_attr "type" "ssecmp")
10703 (set_attr "prefix" "vex")
10704 (set_attr "length_immediate" "1")
10705 (set_attr "mode" "<MODE>")])
10707 (define_insn "*sse_setcc<mode>"
10708 [(set (match_operand:MODEF 0 "register_operand" "=x")
10709 (match_operator:MODEF 1 "sse_comparison_operator"
10710 [(match_operand:MODEF 2 "register_operand" "0")
10711 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10712 "SSE_FLOAT_MODE_P (<MODE>mode)"
10713 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10714 [(set_attr "type" "ssecmp")
10715 (set_attr "length_immediate" "1")
10716 (set_attr "mode" "<MODE>")])
10718 ;; Basic conditional jump instructions.
10719 ;; We ignore the overflow flag for signed branch instructions.
10721 (define_insn "*jcc_1"
10723 (if_then_else (match_operator 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)])
10725 (label_ref (match_operand 0 "" ""))
10729 [(set_attr "type" "ibr")
10730 (set_attr "modrm" "0")
10731 (set (attr "length")
10732 (if_then_else (and (ge (minus (match_dup 0) (pc))
10734 (lt (minus (match_dup 0) (pc))
10739 (define_insn "*jcc_2"
10741 (if_then_else (match_operator 1 "ix86_comparison_operator"
10742 [(reg FLAGS_REG) (const_int 0)])
10744 (label_ref (match_operand 0 "" ""))))]
10747 [(set_attr "type" "ibr")
10748 (set_attr "modrm" "0")
10749 (set (attr "length")
10750 (if_then_else (and (ge (minus (match_dup 0) (pc))
10752 (lt (minus (match_dup 0) (pc))
10757 ;; In general it is not safe to assume too much about CCmode registers,
10758 ;; so simplify-rtx stops when it sees a second one. Under certain
10759 ;; conditions this is safe on x86, so help combine not create
10767 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10768 [(reg FLAGS_REG) (const_int 0)])
10770 (label_ref (match_operand 1 "" ""))
10774 (if_then_else (match_dup 0)
10775 (label_ref (match_dup 1))
10777 "PUT_MODE (operands[0], VOIDmode);")
10781 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10782 [(reg FLAGS_REG) (const_int 0)])
10784 (label_ref (match_operand 1 "" ""))
10788 (if_then_else (match_dup 0)
10789 (label_ref (match_dup 1))
10792 rtx new_op0 = copy_rtx (operands[0]);
10793 operands[0] = new_op0;
10794 PUT_MODE (new_op0, VOIDmode);
10795 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10796 GET_MODE (XEXP (new_op0, 0))));
10798 /* Make sure that (a) the CCmode we have for the flags is strong
10799 enough for the reversed compare or (b) we have a valid FP compare. */
10800 if (! ix86_comparison_operator (new_op0, VOIDmode))
10804 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10805 ;; pass generates from shift insn with QImode operand. Actually, the mode
10806 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10807 ;; appropriate modulo of the bit offset value.
10809 (define_insn_and_split "*jcc_bt<mode>"
10811 (if_then_else (match_operator 0 "bt_comparison_operator"
10812 [(zero_extract:SWI48
10813 (match_operand:SWI48 1 "register_operand" "r")
10816 (match_operand:QI 2 "register_operand" "r")))
10818 (label_ref (match_operand 3 "" ""))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10824 [(set (reg:CCC FLAGS_REG)
10826 (zero_extract:SWI48
10832 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10833 (label_ref (match_dup 3))
10836 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10838 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10841 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10842 ;; also for DImode, this is what combine produces.
10843 (define_insn_and_split "*jcc_bt<mode>_mask"
10845 (if_then_else (match_operator 0 "bt_comparison_operator"
10846 [(zero_extract:SWI48
10847 (match_operand:SWI48 1 "register_operand" "r")
10850 (match_operand:SI 2 "register_operand" "r")
10851 (match_operand:SI 3 "const_int_operand" "n")))])
10852 (label_ref (match_operand 4 "" ""))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10856 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10857 == GET_MODE_BITSIZE (<MODE>mode)-1"
10860 [(set (reg:CCC FLAGS_REG)
10862 (zero_extract:SWI48
10868 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10869 (label_ref (match_dup 4))
10872 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10874 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10877 (define_insn_and_split "*jcc_btsi_1"
10879 (if_then_else (match_operator 0 "bt_comparison_operator"
10882 (match_operand:SI 1 "register_operand" "r")
10883 (match_operand:QI 2 "register_operand" "r"))
10886 (label_ref (match_operand 3 "" ""))
10888 (clobber (reg:CC FLAGS_REG))]
10889 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10892 [(set (reg:CCC FLAGS_REG)
10900 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10901 (label_ref (match_dup 3))
10904 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10906 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10909 ;; avoid useless masking of bit offset operand
10910 (define_insn_and_split "*jcc_btsi_mask_1"
10913 (match_operator 0 "bt_comparison_operator"
10916 (match_operand:SI 1 "register_operand" "r")
10919 (match_operand:SI 2 "register_operand" "r")
10920 (match_operand:SI 3 "const_int_operand" "n")) 0))
10923 (label_ref (match_operand 4 "" ""))
10925 (clobber (reg:CC FLAGS_REG))]
10926 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10927 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10930 [(set (reg:CCC FLAGS_REG)
10938 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939 (label_ref (match_dup 4))
10941 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10943 ;; Define combination compare-and-branch fp compare instructions to help
10946 (define_insn "*fp_jcc_1_387"
10948 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10949 [(match_operand 1 "register_operand" "f")
10950 (match_operand 2 "nonimmediate_operand" "fm")])
10951 (label_ref (match_operand 3 "" ""))
10953 (clobber (reg:CCFP FPSR_REG))
10954 (clobber (reg:CCFP FLAGS_REG))
10955 (clobber (match_scratch:HI 4 "=a"))]
10957 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10958 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10959 && SELECT_CC_MODE (GET_CODE (operands[0]),
10960 operands[1], operands[2]) == CCFPmode
10964 (define_insn "*fp_jcc_1r_387"
10966 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10967 [(match_operand 1 "register_operand" "f")
10968 (match_operand 2 "nonimmediate_operand" "fm")])
10970 (label_ref (match_operand 3 "" ""))))
10971 (clobber (reg:CCFP FPSR_REG))
10972 (clobber (reg:CCFP FLAGS_REG))
10973 (clobber (match_scratch:HI 4 "=a"))]
10975 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10977 && SELECT_CC_MODE (GET_CODE (operands[0]),
10978 operands[1], operands[2]) == CCFPmode
10982 (define_insn "*fp_jcc_2_387"
10984 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10985 [(match_operand 1 "register_operand" "f")
10986 (match_operand 2 "register_operand" "f")])
10987 (label_ref (match_operand 3 "" ""))
10989 (clobber (reg:CCFP FPSR_REG))
10990 (clobber (reg:CCFP FLAGS_REG))
10991 (clobber (match_scratch:HI 4 "=a"))]
10992 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10993 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10997 (define_insn "*fp_jcc_2r_387"
10999 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11000 [(match_operand 1 "register_operand" "f")
11001 (match_operand 2 "register_operand" "f")])
11003 (label_ref (match_operand 3 "" ""))))
11004 (clobber (reg:CCFP FPSR_REG))
11005 (clobber (reg:CCFP FLAGS_REG))
11006 (clobber (match_scratch:HI 4 "=a"))]
11007 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11008 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11012 (define_insn "*fp_jcc_3_387"
11014 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015 [(match_operand 1 "register_operand" "f")
11016 (match_operand 2 "const0_operand" "")])
11017 (label_ref (match_operand 3 "" ""))
11019 (clobber (reg:CCFP FPSR_REG))
11020 (clobber (reg:CCFP FLAGS_REG))
11021 (clobber (match_scratch:HI 4 "=a"))]
11022 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11023 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11024 && SELECT_CC_MODE (GET_CODE (operands[0]),
11025 operands[1], operands[2]) == CCFPmode
11031 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11032 [(match_operand 1 "register_operand" "")
11033 (match_operand 2 "nonimmediate_operand" "")])
11034 (match_operand 3 "" "")
11035 (match_operand 4 "" "")))
11036 (clobber (reg:CCFP FPSR_REG))
11037 (clobber (reg:CCFP FLAGS_REG))]
11041 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11042 operands[3], operands[4], NULL_RTX, NULL_RTX);
11048 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11049 [(match_operand 1 "register_operand" "")
11050 (match_operand 2 "general_operand" "")])
11051 (match_operand 3 "" "")
11052 (match_operand 4 "" "")))
11053 (clobber (reg:CCFP FPSR_REG))
11054 (clobber (reg:CCFP FLAGS_REG))
11055 (clobber (match_scratch:HI 5 "=a"))]
11059 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11060 operands[3], operands[4], operands[5], NULL_RTX);
11064 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11065 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11066 ;; with a precedence over other operators and is always put in the first
11067 ;; place. Swap condition and operands to match ficom instruction.
11069 (define_insn "*fp_jcc_4_<mode>_387"
11072 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11073 [(match_operator 1 "float_operator"
11074 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11075 (match_operand 3 "register_operand" "f,f")])
11076 (label_ref (match_operand 4 "" ""))
11078 (clobber (reg:CCFP FPSR_REG))
11079 (clobber (reg:CCFP FLAGS_REG))
11080 (clobber (match_scratch:HI 5 "=a,a"))]
11081 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11082 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11083 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11084 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11091 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11092 [(match_operator 1 "float_operator"
11093 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11094 (match_operand 3 "register_operand" "")])
11095 (match_operand 4 "" "")
11096 (match_operand 5 "" "")))
11097 (clobber (reg:CCFP FPSR_REG))
11098 (clobber (reg:CCFP FLAGS_REG))
11099 (clobber (match_scratch:HI 6 "=a"))]
11103 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11105 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11106 operands[3], operands[7],
11107 operands[4], operands[5], operands[6], NULL_RTX);
11111 ;; %%% Kill this when reload knows how to do it.
11115 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11116 [(match_operator 1 "float_operator"
11117 [(match_operand:X87MODEI12 2 "register_operand" "")])
11118 (match_operand 3 "register_operand" "")])
11119 (match_operand 4 "" "")
11120 (match_operand 5 "" "")))
11121 (clobber (reg:CCFP FPSR_REG))
11122 (clobber (reg:CCFP FLAGS_REG))
11123 (clobber (match_scratch:HI 6 "=a"))]
11127 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11128 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11130 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11131 operands[3], operands[7],
11132 operands[4], operands[5], operands[6], operands[2]);
11136 ;; Unconditional and other jump instructions
11138 (define_insn "jump"
11140 (label_ref (match_operand 0 "" "")))]
11143 [(set_attr "type" "ibr")
11144 (set (attr "length")
11145 (if_then_else (and (ge (minus (match_dup 0) (pc))
11147 (lt (minus (match_dup 0) (pc))
11151 (set_attr "modrm" "0")])
11153 (define_expand "indirect_jump"
11154 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11158 (define_insn "*indirect_jump"
11159 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11162 [(set_attr "type" "ibr")
11163 (set_attr "length_immediate" "0")])
11165 (define_expand "tablejump"
11166 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11167 (use (label_ref (match_operand 1 "" "")))])]
11170 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11171 relative. Convert the relative address to an absolute address. */
11175 enum rtx_code code;
11177 /* We can't use @GOTOFF for text labels on VxWorks;
11178 see gotoff_operand. */
11179 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11183 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11185 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11189 op1 = pic_offset_table_rtx;
11194 op0 = pic_offset_table_rtx;
11198 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11203 (define_insn "*tablejump_1"
11204 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11205 (use (label_ref (match_operand 1 "" "")))]
11208 [(set_attr "type" "ibr")
11209 (set_attr "length_immediate" "0")])
11211 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11214 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215 (set (match_operand:QI 1 "register_operand" "")
11216 (match_operator:QI 2 "ix86_comparison_operator"
11217 [(reg FLAGS_REG) (const_int 0)]))
11218 (set (match_operand 3 "q_regs_operand" "")
11219 (zero_extend (match_dup 1)))]
11220 "(peep2_reg_dead_p (3, operands[1])
11221 || operands_match_p (operands[1], operands[3]))
11222 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11223 [(set (match_dup 4) (match_dup 0))
11224 (set (strict_low_part (match_dup 5))
11227 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11228 operands[5] = gen_lowpart (QImode, operands[3]);
11229 ix86_expand_clear (operands[3]);
11232 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11235 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11236 (set (match_operand:QI 1 "register_operand" "")
11237 (match_operator:QI 2 "ix86_comparison_operator"
11238 [(reg FLAGS_REG) (const_int 0)]))
11239 (parallel [(set (match_operand 3 "q_regs_operand" "")
11240 (zero_extend (match_dup 1)))
11241 (clobber (reg:CC FLAGS_REG))])]
11242 "(peep2_reg_dead_p (3, operands[1])
11243 || operands_match_p (operands[1], operands[3]))
11244 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11245 [(set (match_dup 4) (match_dup 0))
11246 (set (strict_low_part (match_dup 5))
11249 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11250 operands[5] = gen_lowpart (QImode, operands[3]);
11251 ix86_expand_clear (operands[3]);
11254 ;; Call instructions.
11256 ;; The predicates normally associated with named expanders are not properly
11257 ;; checked for calls. This is a bug in the generic code, but it isn't that
11258 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11260 ;; P6 processors will jump to the address after the decrement when %esp
11261 ;; is used as a call operand, so they will execute return address as a code.
11262 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11264 ;; Call subroutine returning no value.
11266 (define_expand "call_pop"
11267 [(parallel [(call (match_operand:QI 0 "" "")
11268 (match_operand:SI 1 "" ""))
11269 (set (reg:SI SP_REG)
11270 (plus:SI (reg:SI SP_REG)
11271 (match_operand:SI 3 "" "")))])]
11274 ix86_expand_call (NULL, operands[0], operands[1],
11275 operands[2], operands[3], 0);
11279 (define_insn_and_split "*call_pop_0_vzeroupper"
11281 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11282 (match_operand:SI 1 "" ""))
11283 (set (reg:SI SP_REG)
11284 (plus:SI (reg:SI SP_REG)
11285 (match_operand:SI 2 "immediate_operand" "")))])
11286 (unspec [(match_operand 3 "const_int_operand" "")]
11287 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11288 "TARGET_VZEROUPPER && !TARGET_64BIT"
11290 "&& reload_completed"
11292 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11293 [(set_attr "type" "call")])
11295 (define_insn "*call_pop_0"
11296 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11297 (match_operand:SI 1 "" ""))
11298 (set (reg:SI SP_REG)
11299 (plus:SI (reg:SI SP_REG)
11300 (match_operand:SI 2 "immediate_operand" "")))]
11303 if (SIBLING_CALL_P (insn))
11306 return "call\t%P0";
11308 [(set_attr "type" "call")])
11310 (define_insn_and_split "*call_pop_1_vzeroupper"
11312 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11313 (match_operand:SI 1 "" ""))
11314 (set (reg:SI SP_REG)
11315 (plus:SI (reg:SI SP_REG)
11316 (match_operand:SI 2 "immediate_operand" "i")))])
11317 (unspec [(match_operand 3 "const_int_operand" "")]
11318 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11321 "&& reload_completed"
11323 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11324 [(set_attr "type" "call")])
11326 (define_insn "*call_pop_1"
11327 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11328 (match_operand:SI 1 "" ""))
11329 (set (reg:SI SP_REG)
11330 (plus:SI (reg:SI SP_REG)
11331 (match_operand:SI 2 "immediate_operand" "i")))]
11332 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11334 if (constant_call_address_operand (operands[0], Pmode))
11335 return "call\t%P0";
11336 return "call\t%A0";
11338 [(set_attr "type" "call")])
11340 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11342 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11343 (match_operand:SI 1 "" ""))
11344 (set (reg:SI SP_REG)
11345 (plus:SI (reg:SI SP_REG)
11346 (match_operand:SI 2 "immediate_operand" "i,i")))])
11347 (unspec [(match_operand 3 "const_int_operand" "")]
11348 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11351 "&& reload_completed"
11353 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11354 [(set_attr "type" "call")])
11356 (define_insn "*sibcall_pop_1"
11357 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11358 (match_operand:SI 1 "" ""))
11359 (set (reg:SI SP_REG)
11360 (plus:SI (reg:SI SP_REG)
11361 (match_operand:SI 2 "immediate_operand" "i,i")))]
11362 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11366 [(set_attr "type" "call")])
11368 (define_expand "call"
11369 [(call (match_operand:QI 0 "" "")
11370 (match_operand 1 "" ""))
11371 (use (match_operand 2 "" ""))]
11374 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11378 (define_expand "sibcall"
11379 [(call (match_operand:QI 0 "" "")
11380 (match_operand 1 "" ""))
11381 (use (match_operand 2 "" ""))]
11384 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11388 (define_insn_and_split "*call_0_vzeroupper"
11389 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11390 (match_operand 1 "" ""))
11391 (unspec [(match_operand 2 "const_int_operand" "")]
11392 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11393 "TARGET_VZEROUPPER"
11395 "&& reload_completed"
11397 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11398 [(set_attr "type" "call")])
11400 (define_insn "*call_0"
11401 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11402 (match_operand 1 "" ""))]
11404 { return ix86_output_call_insn (insn, operands[0], 0); }
11405 [(set_attr "type" "call")])
11407 (define_insn_and_split "*call_1_vzeroupper"
11408 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11409 (match_operand 1 "" ""))
11410 (unspec [(match_operand 2 "const_int_operand" "")]
11411 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11414 "&& reload_completed"
11416 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11417 [(set_attr "type" "call")])
11419 (define_insn "*call_1"
11420 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11421 (match_operand 1 "" ""))]
11422 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11423 { return ix86_output_call_insn (insn, operands[0], 0); }
11424 [(set_attr "type" "call")])
11426 (define_insn_and_split "*sibcall_1_vzeroupper"
11427 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11428 (match_operand 1 "" ""))
11429 (unspec [(match_operand 2 "const_int_operand" "")]
11430 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11431 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11433 "&& reload_completed"
11435 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11436 [(set_attr "type" "call")])
11438 (define_insn "*sibcall_1"
11439 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11440 (match_operand 1 "" ""))]
11441 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11442 { return ix86_output_call_insn (insn, operands[0], 0); }
11443 [(set_attr "type" "call")])
11445 (define_insn_and_split "*call_1_rex64_vzeroupper"
11446 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11447 (match_operand 1 "" ""))
11448 (unspec [(match_operand 2 "const_int_operand" "")]
11449 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11451 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11453 "&& reload_completed"
11455 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11456 [(set_attr "type" "call")])
11458 (define_insn "*call_1_rex64"
11459 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11460 (match_operand 1 "" ""))]
11461 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11462 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11463 { return ix86_output_call_insn (insn, operands[0], 0); }
11464 [(set_attr "type" "call")])
11466 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11468 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11469 (match_operand 1 "" ""))
11470 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11471 (clobber (reg:TI XMM6_REG))
11472 (clobber (reg:TI XMM7_REG))
11473 (clobber (reg:TI XMM8_REG))
11474 (clobber (reg:TI XMM9_REG))
11475 (clobber (reg:TI XMM10_REG))
11476 (clobber (reg:TI XMM11_REG))
11477 (clobber (reg:TI XMM12_REG))
11478 (clobber (reg:TI XMM13_REG))
11479 (clobber (reg:TI XMM14_REG))
11480 (clobber (reg:TI XMM15_REG))
11481 (clobber (reg:DI SI_REG))
11482 (clobber (reg:DI DI_REG))])
11483 (unspec [(match_operand 2 "const_int_operand" "")]
11484 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11485 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11487 "&& reload_completed"
11489 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11490 [(set_attr "type" "call")])
11492 (define_insn "*call_1_rex64_ms_sysv"
11493 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11494 (match_operand 1 "" ""))
11495 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11496 (clobber (reg:TI XMM6_REG))
11497 (clobber (reg:TI XMM7_REG))
11498 (clobber (reg:TI XMM8_REG))
11499 (clobber (reg:TI XMM9_REG))
11500 (clobber (reg:TI XMM10_REG))
11501 (clobber (reg:TI XMM11_REG))
11502 (clobber (reg:TI XMM12_REG))
11503 (clobber (reg:TI XMM13_REG))
11504 (clobber (reg:TI XMM14_REG))
11505 (clobber (reg:TI XMM15_REG))
11506 (clobber (reg:DI SI_REG))
11507 (clobber (reg:DI DI_REG))]
11508 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11509 { return ix86_output_call_insn (insn, operands[0], 0); }
11510 [(set_attr "type" "call")])
11512 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11513 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11514 (match_operand 1 "" ""))
11515 (unspec [(match_operand 2 "const_int_operand" "")]
11516 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11517 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519 "&& reload_completed"
11521 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11522 [(set_attr "type" "call")])
11524 (define_insn "*call_1_rex64_large"
11525 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11526 (match_operand 1 "" ""))]
11527 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528 { return ix86_output_call_insn (insn, operands[0], 0); }
11529 [(set_attr "type" "call")])
11531 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11532 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11533 (match_operand 1 "" ""))
11534 (unspec [(match_operand 2 "const_int_operand" "")]
11535 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11536 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11538 "&& reload_completed"
11540 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11541 [(set_attr "type" "call")])
11543 (define_insn "*sibcall_1_rex64"
11544 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11545 (match_operand 1 "" ""))]
11546 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11547 { return ix86_output_call_insn (insn, operands[0], 0); }
11548 [(set_attr "type" "call")])
11550 ;; Call subroutine, returning value in operand 0
11551 (define_expand "call_value_pop"
11552 [(parallel [(set (match_operand 0 "" "")
11553 (call (match_operand:QI 1 "" "")
11554 (match_operand:SI 2 "" "")))
11555 (set (reg:SI SP_REG)
11556 (plus:SI (reg:SI SP_REG)
11557 (match_operand:SI 4 "" "")))])]
11560 ix86_expand_call (operands[0], operands[1], operands[2],
11561 operands[3], operands[4], 0);
11565 (define_expand "call_value"
11566 [(set (match_operand 0 "" "")
11567 (call (match_operand:QI 1 "" "")
11568 (match_operand:SI 2 "" "")))
11569 (use (match_operand:SI 3 "" ""))]
11570 ;; Operand 3 is not used on the i386.
11573 ix86_expand_call (operands[0], operands[1], operands[2],
11574 operands[3], NULL, 0);
11578 (define_expand "sibcall_value"
11579 [(set (match_operand 0 "" "")
11580 (call (match_operand:QI 1 "" "")
11581 (match_operand:SI 2 "" "")))
11582 (use (match_operand:SI 3 "" ""))]
11583 ;; Operand 3 is not used on the i386.
11586 ix86_expand_call (operands[0], operands[1], operands[2],
11587 operands[3], NULL, 1);
11591 ;; Call subroutine returning any type.
11593 (define_expand "untyped_call"
11594 [(parallel [(call (match_operand 0 "" "")
11596 (match_operand 1 "" "")
11597 (match_operand 2 "" "")])]
11602 /* In order to give reg-stack an easier job in validating two
11603 coprocessor registers as containing a possible return value,
11604 simply pretend the untyped call returns a complex long double
11607 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11608 and should have the default ABI. */
11610 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11611 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11612 operands[0], const0_rtx,
11613 GEN_INT ((TARGET_64BIT
11614 ? (ix86_abi == SYSV_ABI
11615 ? X86_64_SSE_REGPARM_MAX
11616 : X86_64_MS_SSE_REGPARM_MAX)
11617 : X86_32_SSE_REGPARM_MAX)
11621 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11623 rtx set = XVECEXP (operands[2], 0, i);
11624 emit_move_insn (SET_DEST (set), SET_SRC (set));
11627 /* The optimizer does not know that the call sets the function value
11628 registers we stored in the result block. We avoid problems by
11629 claiming that all hard registers are used and clobbered at this
11631 emit_insn (gen_blockage ());
11636 ;; Prologue and epilogue instructions
11638 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11639 ;; all of memory. This blocks insns from being moved across this point.
11641 (define_insn "blockage"
11642 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11645 [(set_attr "length" "0")])
11647 ;; Do not schedule instructions accessing memory across this point.
11649 (define_expand "memory_blockage"
11650 [(set (match_dup 0)
11651 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11654 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11655 MEM_VOLATILE_P (operands[0]) = 1;
11658 (define_insn "*memory_blockage"
11659 [(set (match_operand:BLK 0 "" "")
11660 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11663 [(set_attr "length" "0")])
11665 ;; As USE insns aren't meaningful after reload, this is used instead
11666 ;; to prevent deleting instructions setting registers for PIC code
11667 (define_insn "prologue_use"
11668 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11671 [(set_attr "length" "0")])
11673 ;; Insn emitted into the body of a function to return from a function.
11674 ;; This is only done if the function's epilogue is known to be simple.
11675 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11677 (define_expand "return"
11679 "ix86_can_use_return_insn_p ()"
11681 if (crtl->args.pops_args)
11683 rtx popc = GEN_INT (crtl->args.pops_args);
11684 emit_jump_insn (gen_return_pop_internal (popc));
11689 (define_insn "return_internal"
11693 [(set_attr "length" "1")
11694 (set_attr "atom_unit" "jeu")
11695 (set_attr "length_immediate" "0")
11696 (set_attr "modrm" "0")])
11698 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11699 ;; instruction Athlon and K8 have.
11701 (define_insn "return_internal_long"
11703 (unspec [(const_int 0)] UNSPEC_REP)]
11706 [(set_attr "length" "2")
11707 (set_attr "atom_unit" "jeu")
11708 (set_attr "length_immediate" "0")
11709 (set_attr "prefix_rep" "1")
11710 (set_attr "modrm" "0")])
11712 (define_insn "return_pop_internal"
11714 (use (match_operand:SI 0 "const_int_operand" ""))]
11717 [(set_attr "length" "3")
11718 (set_attr "atom_unit" "jeu")
11719 (set_attr "length_immediate" "2")
11720 (set_attr "modrm" "0")])
11722 (define_insn "return_indirect_internal"
11724 (use (match_operand:SI 0 "register_operand" "r"))]
11727 [(set_attr "type" "ibr")
11728 (set_attr "length_immediate" "0")])
11734 [(set_attr "length" "1")
11735 (set_attr "length_immediate" "0")
11736 (set_attr "modrm" "0")])
11738 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11739 (define_insn "nops"
11740 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11744 int num = INTVAL (operands[0]);
11746 gcc_assert (num >= 1 && num <= 8);
11749 fputs ("\tnop\n", asm_out_file);
11753 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11754 (set_attr "length_immediate" "0")
11755 (set_attr "modrm" "0")])
11757 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11758 ;; branch prediction penalty for the third jump in a 16-byte
11762 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11765 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11766 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11768 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11769 The align insn is used to avoid 3 jump instructions in the row to improve
11770 branch prediction and the benefits hardly outweigh the cost of extra 8
11771 nops on the average inserted by full alignment pseudo operation. */
11775 [(set_attr "length" "16")])
11777 (define_expand "prologue"
11780 "ix86_expand_prologue (); DONE;")
11782 (define_insn "set_got"
11783 [(set (match_operand:SI 0 "register_operand" "=r")
11784 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11785 (clobber (reg:CC FLAGS_REG))]
11787 "* return output_set_got (operands[0], NULL_RTX);"
11788 [(set_attr "type" "multi")
11789 (set_attr "length" "12")])
11791 (define_insn "set_got_labelled"
11792 [(set (match_operand:SI 0 "register_operand" "=r")
11793 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11795 (clobber (reg:CC FLAGS_REG))]
11797 "* return output_set_got (operands[0], operands[1]);"
11798 [(set_attr "type" "multi")
11799 (set_attr "length" "12")])
11801 (define_insn "set_got_rex64"
11802 [(set (match_operand:DI 0 "register_operand" "=r")
11803 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11805 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11806 [(set_attr "type" "lea")
11807 (set_attr "length_address" "4")
11808 (set_attr "mode" "DI")])
11810 (define_insn "set_rip_rex64"
11811 [(set (match_operand:DI 0 "register_operand" "=r")
11812 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11814 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11815 [(set_attr "type" "lea")
11816 (set_attr "length_address" "4")
11817 (set_attr "mode" "DI")])
11819 (define_insn "set_got_offset_rex64"
11820 [(set (match_operand:DI 0 "register_operand" "=r")
11822 [(label_ref (match_operand 1 "" ""))]
11823 UNSPEC_SET_GOT_OFFSET))]
11825 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11826 [(set_attr "type" "imov")
11827 (set_attr "length_immediate" "0")
11828 (set_attr "length_address" "8")
11829 (set_attr "mode" "DI")])
11831 (define_expand "epilogue"
11834 "ix86_expand_epilogue (1); DONE;")
11836 (define_expand "sibcall_epilogue"
11839 "ix86_expand_epilogue (0); DONE;")
11841 (define_expand "eh_return"
11842 [(use (match_operand 0 "register_operand" ""))]
11845 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11847 /* Tricky bit: we write the address of the handler to which we will
11848 be returning into someone else's stack frame, one word below the
11849 stack address we wish to restore. */
11850 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11851 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11852 tmp = gen_rtx_MEM (Pmode, tmp);
11853 emit_move_insn (tmp, ra);
11855 emit_jump_insn (gen_eh_return_internal ());
11860 (define_insn_and_split "eh_return_internal"
11864 "epilogue_completed"
11866 "ix86_expand_epilogue (2); DONE;")
11868 (define_insn "leave"
11869 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11870 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11871 (clobber (mem:BLK (scratch)))]
11874 [(set_attr "type" "leave")])
11876 (define_insn "leave_rex64"
11877 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11878 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11879 (clobber (mem:BLK (scratch)))]
11882 [(set_attr "type" "leave")])
11884 ;; Handle -fsplit-stack.
11886 (define_expand "split_stack_prologue"
11890 ix86_expand_split_stack_prologue ();
11894 ;; In order to support the call/return predictor, we use a return
11895 ;; instruction which the middle-end doesn't see.
11896 (define_insn "split_stack_return"
11897 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11898 UNSPECV_SPLIT_STACK_RETURN)]
11901 if (operands[0] == const0_rtx)
11906 [(set_attr "atom_unit" "jeu")
11907 (set_attr "modrm" "0")
11908 (set (attr "length")
11909 (if_then_else (match_operand:SI 0 "const0_operand" "")
11912 (set (attr "length_immediate")
11913 (if_then_else (match_operand:SI 0 "const0_operand" "")
11917 ;; If there are operand 0 bytes available on the stack, jump to
11920 (define_expand "split_stack_space_check"
11921 [(set (pc) (if_then_else
11922 (ltu (minus (reg SP_REG)
11923 (match_operand 0 "register_operand" ""))
11924 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11925 (label_ref (match_operand 1 "" ""))
11929 rtx reg, size, limit;
11931 reg = gen_reg_rtx (Pmode);
11932 size = force_reg (Pmode, operands[0]);
11933 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11934 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11935 UNSPEC_STACK_CHECK);
11936 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11937 ix86_expand_branch (GEU, reg, limit, operands[1]);
11942 ;; Bit manipulation instructions.
11944 (define_expand "ffs<mode>2"
11945 [(set (match_dup 2) (const_int -1))
11946 (parallel [(set (reg:CCZ FLAGS_REG)
11948 (match_operand:SWI48 1 "nonimmediate_operand" "")
11950 (set (match_operand:SWI48 0 "register_operand" "")
11951 (ctz:SWI48 (match_dup 1)))])
11952 (set (match_dup 0) (if_then_else:SWI48
11953 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11956 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11957 (clobber (reg:CC FLAGS_REG))])]
11960 if (<MODE>mode == SImode && !TARGET_CMOVE)
11962 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11965 operands[2] = gen_reg_rtx (<MODE>mode);
11968 (define_insn_and_split "ffssi2_no_cmove"
11969 [(set (match_operand:SI 0 "register_operand" "=r")
11970 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11971 (clobber (match_scratch:SI 2 "=&q"))
11972 (clobber (reg:CC FLAGS_REG))]
11975 "&& reload_completed"
11976 [(parallel [(set (reg:CCZ FLAGS_REG)
11977 (compare:CCZ (match_dup 1) (const_int 0)))
11978 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11979 (set (strict_low_part (match_dup 3))
11980 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11981 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11982 (clobber (reg:CC FLAGS_REG))])
11983 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11984 (clobber (reg:CC FLAGS_REG))])
11985 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11986 (clobber (reg:CC FLAGS_REG))])]
11988 operands[3] = gen_lowpart (QImode, operands[2]);
11989 ix86_expand_clear (operands[2]);
11992 (define_insn "*ffs<mode>_1"
11993 [(set (reg:CCZ FLAGS_REG)
11994 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11996 (set (match_operand:SWI48 0 "register_operand" "=r")
11997 (ctz:SWI48 (match_dup 1)))]
11999 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12000 [(set_attr "type" "alu1")
12001 (set_attr "prefix_0f" "1")
12002 (set_attr "mode" "<MODE>")])
12004 (define_insn "ctz<mode>2"
12005 [(set (match_operand:SWI248 0 "register_operand" "=r")
12006 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12007 (clobber (reg:CC FLAGS_REG))]
12011 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12013 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12015 [(set_attr "type" "alu1")
12016 (set_attr "prefix_0f" "1")
12017 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12018 (set_attr "mode" "<MODE>")])
12020 (define_expand "clz<mode>2"
12022 [(set (match_operand:SWI248 0 "register_operand" "")
12025 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12026 (clobber (reg:CC FLAGS_REG))])
12028 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12029 (clobber (reg:CC FLAGS_REG))])]
12034 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12037 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12040 (define_insn "clz<mode>2_abm"
12041 [(set (match_operand:SWI248 0 "register_operand" "=r")
12042 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "TARGET_ABM || TARGET_BMI"
12045 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12046 [(set_attr "prefix_rep" "1")
12047 (set_attr "type" "bitmanip")
12048 (set_attr "mode" "<MODE>")])
12050 ;; BMI instructions.
12051 (define_insn "*bmi_andn_<mode>"
12052 [(set (match_operand:SWI48 0 "register_operand" "=r")
12055 (match_operand:SWI48 1 "register_operand" "r"))
12056 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12057 (clobber (reg:CC FLAGS_REG))]
12059 "andn\t{%2, %1, %0|%0, %1, %2}"
12060 [(set_attr "type" "bitmanip")
12061 (set_attr "mode" "<MODE>")])
12063 (define_insn "bmi_bextr_<mode>"
12064 [(set (match_operand:SWI48 0 "register_operand" "=r")
12065 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066 (match_operand:SWI48 2 "register_operand" "r")]
12068 (clobber (reg:CC FLAGS_REG))]
12070 "bextr\t{%2, %1, %0|%0, %1, %2}"
12071 [(set_attr "type" "bitmanip")
12072 (set_attr "mode" "<MODE>")])
12074 (define_insn "*bmi_blsi_<mode>"
12075 [(set (match_operand:SWI48 0 "register_operand" "=r")
12078 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12080 (clobber (reg:CC FLAGS_REG))]
12082 "blsi\t{%1, %0|%0, %1}"
12083 [(set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12086 (define_insn "*bmi_blsmsk_<mode>"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12090 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12093 (clobber (reg:CC FLAGS_REG))]
12095 "blsmsk\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 (define_insn "*bmi_blsr_<mode>"
12100 [(set (match_operand:SWI48 0 "register_operand" "=r")
12103 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12106 (clobber (reg:CC FLAGS_REG))]
12108 "blsr\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 ;; TBM instructions.
12113 (define_insn "tbm_bextri_<mode>"
12114 [(set (match_operand:SWI48 0 "register_operand" "=r")
12115 (zero_extract:SWI48
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12118 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12119 (clobber (reg:CC FLAGS_REG))]
12122 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12123 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12125 [(set_attr "type" "bitmanip")
12126 (set_attr "mode" "<MODE>")])
12128 (define_insn "*tbm_blcfill_<mode>"
12129 [(set (match_operand:SWI48 0 "register_operand" "=r")
12132 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12135 (clobber (reg:CC FLAGS_REG))]
12137 "blcfill\t{%1, %0|%0, %1}"
12138 [(set_attr "type" "bitmanip")
12139 (set_attr "mode" "<MODE>")])
12141 (define_insn "*tbm_blci_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12146 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12149 (clobber (reg:CC FLAGS_REG))]
12151 "blci\t{%1, %0|%0, %1}"
12152 [(set_attr "type" "bitmanip")
12153 (set_attr "mode" "<MODE>")])
12155 (define_insn "*tbm_blcic_<mode>"
12156 [(set (match_operand:SWI48 0 "register_operand" "=r")
12159 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12163 (clobber (reg:CC FLAGS_REG))]
12165 "blcic\t{%1, %0|%0, %1}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "mode" "<MODE>")])
12169 (define_insn "*tbm_blcmsk_<mode>"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12173 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12176 (clobber (reg:CC FLAGS_REG))]
12178 "blcmsk\t{%1, %0|%0, %1}"
12179 [(set_attr "type" "bitmanip")
12180 (set_attr "mode" "<MODE>")])
12182 (define_insn "*tbm_blcs_<mode>"
12183 [(set (match_operand:SWI48 0 "register_operand" "=r")
12186 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (clobber (reg:CC FLAGS_REG))]
12191 "blcs\t{%1, %0|%0, %1}"
12192 [(set_attr "type" "bitmanip")
12193 (set_attr "mode" "<MODE>")])
12195 (define_insn "*tbm_blsfill_<mode>"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202 (clobber (reg:CC FLAGS_REG))]
12204 "blsfill\t{%1, %0|%0, %1}"
12205 [(set_attr "type" "bitmanip")
12206 (set_attr "mode" "<MODE>")])
12208 (define_insn "*tbm_blsic_<mode>"
12209 [(set (match_operand:SWI48 0 "register_operand" "=r")
12212 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12216 (clobber (reg:CC FLAGS_REG))]
12218 "blsic\t{%1, %0|%0, %1}"
12219 [(set_attr "type" "bitmanip")
12220 (set_attr "mode" "<MODE>")])
12222 (define_insn "*tbm_t1mskc_<mode>"
12223 [(set (match_operand:SWI48 0 "register_operand" "=r")
12226 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12230 (clobber (reg:CC FLAGS_REG))]
12232 "t1mskc\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "bitmanip")
12234 (set_attr "mode" "<MODE>")])
12236 (define_insn "*tbm_tzmsk_<mode>"
12237 [(set (match_operand:SWI48 0 "register_operand" "=r")
12240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244 (clobber (reg:CC FLAGS_REG))]
12246 "tzmsk\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12250 (define_insn "bsr_rex64"
12251 [(set (match_operand:DI 0 "register_operand" "=r")
12252 (minus:DI (const_int 63)
12253 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12254 (clobber (reg:CC FLAGS_REG))]
12256 "bsr{q}\t{%1, %0|%0, %1}"
12257 [(set_attr "type" "alu1")
12258 (set_attr "prefix_0f" "1")
12259 (set_attr "mode" "DI")])
12262 [(set (match_operand:SI 0 "register_operand" "=r")
12263 (minus:SI (const_int 31)
12264 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12265 (clobber (reg:CC FLAGS_REG))]
12267 "bsr{l}\t{%1, %0|%0, %1}"
12268 [(set_attr "type" "alu1")
12269 (set_attr "prefix_0f" "1")
12270 (set_attr "mode" "SI")])
12272 (define_insn "*bsrhi"
12273 [(set (match_operand:HI 0 "register_operand" "=r")
12274 (minus:HI (const_int 15)
12275 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12276 (clobber (reg:CC FLAGS_REG))]
12278 "bsr{w}\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "alu1")
12280 (set_attr "prefix_0f" "1")
12281 (set_attr "mode" "HI")])
12283 (define_insn "popcount<mode>2"
12284 [(set (match_operand:SWI248 0 "register_operand" "=r")
12286 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12287 (clobber (reg:CC FLAGS_REG))]
12291 return "popcnt\t{%1, %0|%0, %1}";
12293 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12296 [(set_attr "prefix_rep" "1")
12297 (set_attr "type" "bitmanip")
12298 (set_attr "mode" "<MODE>")])
12300 (define_insn "*popcount<mode>2_cmp"
12301 [(set (reg FLAGS_REG)
12304 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12306 (set (match_operand:SWI248 0 "register_operand" "=r")
12307 (popcount:SWI248 (match_dup 1)))]
12308 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12311 return "popcnt\t{%1, %0|%0, %1}";
12313 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12316 [(set_attr "prefix_rep" "1")
12317 (set_attr "type" "bitmanip")
12318 (set_attr "mode" "<MODE>")])
12320 (define_insn "*popcountsi2_cmp_zext"
12321 [(set (reg FLAGS_REG)
12323 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12325 (set (match_operand:DI 0 "register_operand" "=r")
12326 (zero_extend:DI(popcount:SI (match_dup 1))))]
12327 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12330 return "popcnt\t{%1, %0|%0, %1}";
12332 return "popcnt{l}\t{%1, %0|%0, %1}";
12335 [(set_attr "prefix_rep" "1")
12336 (set_attr "type" "bitmanip")
12337 (set_attr "mode" "SI")])
12339 (define_expand "bswap<mode>2"
12340 [(set (match_operand:SWI48 0 "register_operand" "")
12341 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12344 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12346 rtx x = operands[0];
12348 emit_move_insn (x, operands[1]);
12349 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12350 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12351 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12356 (define_insn "*bswap<mode>2_movbe"
12357 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12358 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12360 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12363 movbe\t{%1, %0|%0, %1}
12364 movbe\t{%1, %0|%0, %1}"
12365 [(set_attr "type" "bitmanip,imov,imov")
12366 (set_attr "modrm" "0,1,1")
12367 (set_attr "prefix_0f" "*,1,1")
12368 (set_attr "prefix_extra" "*,1,1")
12369 (set_attr "mode" "<MODE>")])
12371 (define_insn "*bswap<mode>2_1"
12372 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12376 [(set_attr "type" "bitmanip")
12377 (set_attr "modrm" "0")
12378 (set_attr "mode" "<MODE>")])
12380 (define_insn "*bswaphi_lowpart_1"
12381 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12382 (bswap:HI (match_dup 0)))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12386 xchg{b}\t{%h0, %b0|%b0, %h0}
12387 rol{w}\t{$8, %0|%0, 8}"
12388 [(set_attr "length" "2,4")
12389 (set_attr "mode" "QI,HI")])
12391 (define_insn "bswaphi_lowpart"
12392 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12393 (bswap:HI (match_dup 0)))
12394 (clobber (reg:CC FLAGS_REG))]
12396 "rol{w}\t{$8, %0|%0, 8}"
12397 [(set_attr "length" "4")
12398 (set_attr "mode" "HI")])
12400 (define_expand "paritydi2"
12401 [(set (match_operand:DI 0 "register_operand" "")
12402 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12405 rtx scratch = gen_reg_rtx (QImode);
12408 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12409 NULL_RTX, operands[1]));
12411 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12412 gen_rtx_REG (CCmode, FLAGS_REG),
12414 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12417 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12420 rtx tmp = gen_reg_rtx (SImode);
12422 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12423 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12428 (define_expand "paritysi2"
12429 [(set (match_operand:SI 0 "register_operand" "")
12430 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12433 rtx scratch = gen_reg_rtx (QImode);
12436 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12438 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12439 gen_rtx_REG (CCmode, FLAGS_REG),
12441 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12443 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12447 (define_insn_and_split "paritydi2_cmp"
12448 [(set (reg:CC FLAGS_REG)
12449 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12451 (clobber (match_scratch:DI 0 "=r"))
12452 (clobber (match_scratch:SI 1 "=&r"))
12453 (clobber (match_scratch:HI 2 "=Q"))]
12456 "&& reload_completed"
12458 [(set (match_dup 1)
12459 (xor:SI (match_dup 1) (match_dup 4)))
12460 (clobber (reg:CC FLAGS_REG))])
12462 [(set (reg:CC FLAGS_REG)
12463 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12464 (clobber (match_dup 1))
12465 (clobber (match_dup 2))])]
12467 operands[4] = gen_lowpart (SImode, operands[3]);
12471 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12472 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12475 operands[1] = gen_highpart (SImode, operands[3]);
12478 (define_insn_and_split "paritysi2_cmp"
12479 [(set (reg:CC FLAGS_REG)
12480 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12482 (clobber (match_scratch:SI 0 "=r"))
12483 (clobber (match_scratch:HI 1 "=&Q"))]
12486 "&& reload_completed"
12488 [(set (match_dup 1)
12489 (xor:HI (match_dup 1) (match_dup 3)))
12490 (clobber (reg:CC FLAGS_REG))])
12492 [(set (reg:CC FLAGS_REG)
12493 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12494 (clobber (match_dup 1))])]
12496 operands[3] = gen_lowpart (HImode, operands[2]);
12498 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12499 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12502 (define_insn "*parityhi2_cmp"
12503 [(set (reg:CC FLAGS_REG)
12504 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12506 (clobber (match_scratch:HI 0 "=Q"))]
12508 "xor{b}\t{%h0, %b0|%b0, %h0}"
12509 [(set_attr "length" "2")
12510 (set_attr "mode" "HI")])
12512 ;; Thread-local storage patterns for ELF.
12514 ;; Note that these code sequences must appear exactly as shown
12515 ;; in order to allow linker relaxation.
12517 (define_insn "*tls_global_dynamic_32_gnu"
12518 [(set (match_operand:SI 0 "register_operand" "=a")
12519 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12520 (match_operand:SI 2 "tls_symbolic_operand" "")
12521 (match_operand:SI 3 "call_insn_operand" "")]
12523 (clobber (match_scratch:SI 4 "=d"))
12524 (clobber (match_scratch:SI 5 "=c"))
12525 (clobber (reg:CC FLAGS_REG))]
12526 "!TARGET_64BIT && TARGET_GNU_TLS"
12527 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12528 [(set_attr "type" "multi")
12529 (set_attr "length" "12")])
12531 (define_expand "tls_global_dynamic_32"
12532 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12535 (match_operand:SI 1 "tls_symbolic_operand" "")
12538 (clobber (match_scratch:SI 4 ""))
12539 (clobber (match_scratch:SI 5 ""))
12540 (clobber (reg:CC FLAGS_REG))])]
12544 operands[2] = pic_offset_table_rtx;
12547 operands[2] = gen_reg_rtx (Pmode);
12548 emit_insn (gen_set_got (operands[2]));
12550 if (TARGET_GNU2_TLS)
12552 emit_insn (gen_tls_dynamic_gnu2_32
12553 (operands[0], operands[1], operands[2]));
12556 operands[3] = ix86_tls_get_addr ();
12559 (define_insn "*tls_global_dynamic_64"
12560 [(set (match_operand:DI 0 "register_operand" "=a")
12561 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12562 (match_operand:DI 3 "" "")))
12563 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12566 { 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"; }
12567 [(set_attr "type" "multi")
12568 (set_attr "length" "16")])
12570 (define_expand "tls_global_dynamic_64"
12571 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12572 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12573 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12577 if (TARGET_GNU2_TLS)
12579 emit_insn (gen_tls_dynamic_gnu2_64
12580 (operands[0], operands[1]));
12583 operands[2] = ix86_tls_get_addr ();
12586 (define_insn "*tls_local_dynamic_base_32_gnu"
12587 [(set (match_operand:SI 0 "register_operand" "=a")
12588 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12589 (match_operand:SI 2 "call_insn_operand" "")]
12590 UNSPEC_TLS_LD_BASE))
12591 (clobber (match_scratch:SI 3 "=d"))
12592 (clobber (match_scratch:SI 4 "=c"))
12593 (clobber (reg:CC FLAGS_REG))]
12594 "!TARGET_64BIT && TARGET_GNU_TLS"
12595 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12596 [(set_attr "type" "multi")
12597 (set_attr "length" "11")])
12599 (define_expand "tls_local_dynamic_base_32"
12600 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12601 (unspec:SI [(match_dup 1) (match_dup 2)]
12602 UNSPEC_TLS_LD_BASE))
12603 (clobber (match_scratch:SI 3 ""))
12604 (clobber (match_scratch:SI 4 ""))
12605 (clobber (reg:CC FLAGS_REG))])]
12609 operands[1] = pic_offset_table_rtx;
12612 operands[1] = gen_reg_rtx (Pmode);
12613 emit_insn (gen_set_got (operands[1]));
12615 if (TARGET_GNU2_TLS)
12617 emit_insn (gen_tls_dynamic_gnu2_32
12618 (operands[0], ix86_tls_module_base (), operands[1]));
12621 operands[2] = ix86_tls_get_addr ();
12624 (define_insn "*tls_local_dynamic_base_64"
12625 [(set (match_operand:DI 0 "register_operand" "=a")
12626 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12627 (match_operand:DI 2 "" "")))
12628 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12630 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12631 [(set_attr "type" "multi")
12632 (set_attr "length" "12")])
12634 (define_expand "tls_local_dynamic_base_64"
12635 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12636 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12637 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12640 if (TARGET_GNU2_TLS)
12642 emit_insn (gen_tls_dynamic_gnu2_64
12643 (operands[0], ix86_tls_module_base ()));
12646 operands[1] = ix86_tls_get_addr ();
12649 ;; Local dynamic of a single variable is a lose. Show combine how
12650 ;; to convert that back to global dynamic.
12652 (define_insn_and_split "*tls_local_dynamic_32_once"
12653 [(set (match_operand:SI 0 "register_operand" "=a")
12654 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12655 (match_operand:SI 2 "call_insn_operand" "")]
12656 UNSPEC_TLS_LD_BASE)
12657 (const:SI (unspec:SI
12658 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12660 (clobber (match_scratch:SI 4 "=d"))
12661 (clobber (match_scratch:SI 5 "=c"))
12662 (clobber (reg:CC FLAGS_REG))]
12666 [(parallel [(set (match_dup 0)
12667 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12669 (clobber (match_dup 4))
12670 (clobber (match_dup 5))
12671 (clobber (reg:CC FLAGS_REG))])])
12673 ;; Segment register for the thread base ptr load
12674 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12676 ;; Load and add the thread base pointer from %gs:0.
12677 (define_insn "*load_tp_<mode>"
12678 [(set (match_operand:P 0 "register_operand" "=r")
12679 (unspec:P [(const_int 0)] UNSPEC_TP))]
12681 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12682 [(set_attr "type" "imov")
12683 (set_attr "modrm" "0")
12684 (set_attr "length" "7")
12685 (set_attr "memory" "load")
12686 (set_attr "imm_disp" "false")])
12688 (define_insn "*add_tp_<mode>"
12689 [(set (match_operand:P 0 "register_operand" "=r")
12690 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12691 (match_operand:P 1 "register_operand" "0")))
12692 (clobber (reg:CC FLAGS_REG))]
12694 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12695 [(set_attr "type" "alu")
12696 (set_attr "modrm" "0")
12697 (set_attr "length" "7")
12698 (set_attr "memory" "load")
12699 (set_attr "imm_disp" "false")])
12701 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12702 ;; %rax as destination of the initial executable code sequence.
12703 (define_insn "tls_initial_exec_64_sun"
12704 [(set (match_operand:DI 0 "register_operand" "=a")
12706 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12707 UNSPEC_TLS_IE_SUN))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "TARGET_64BIT && TARGET_SUN_TLS"
12710 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12711 [(set_attr "type" "multi")])
12713 ;; GNU2 TLS patterns can be split.
12715 (define_expand "tls_dynamic_gnu2_32"
12716 [(set (match_dup 3)
12717 (plus:SI (match_operand:SI 2 "register_operand" "")
12719 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12722 [(set (match_operand:SI 0 "register_operand" "")
12723 (unspec:SI [(match_dup 1) (match_dup 3)
12724 (match_dup 2) (reg:SI SP_REG)]
12726 (clobber (reg:CC FLAGS_REG))])]
12727 "!TARGET_64BIT && TARGET_GNU2_TLS"
12729 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12730 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12733 (define_insn "*tls_dynamic_lea_32"
12734 [(set (match_operand:SI 0 "register_operand" "=r")
12735 (plus:SI (match_operand:SI 1 "register_operand" "b")
12737 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12738 UNSPEC_TLSDESC))))]
12739 "!TARGET_64BIT && TARGET_GNU2_TLS"
12740 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12741 [(set_attr "type" "lea")
12742 (set_attr "mode" "SI")
12743 (set_attr "length" "6")
12744 (set_attr "length_address" "4")])
12746 (define_insn "*tls_dynamic_call_32"
12747 [(set (match_operand:SI 0 "register_operand" "=a")
12748 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12749 (match_operand:SI 2 "register_operand" "0")
12750 ;; we have to make sure %ebx still points to the GOT
12751 (match_operand:SI 3 "register_operand" "b")
12754 (clobber (reg:CC FLAGS_REG))]
12755 "!TARGET_64BIT && TARGET_GNU2_TLS"
12756 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12757 [(set_attr "type" "call")
12758 (set_attr "length" "2")
12759 (set_attr "length_address" "0")])
12761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12762 [(set (match_operand:SI 0 "register_operand" "=&a")
12764 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12765 (match_operand:SI 4 "" "")
12766 (match_operand:SI 2 "register_operand" "b")
12769 (const:SI (unspec:SI
12770 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12772 (clobber (reg:CC FLAGS_REG))]
12773 "!TARGET_64BIT && TARGET_GNU2_TLS"
12776 [(set (match_dup 0) (match_dup 5))]
12778 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12779 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12782 (define_expand "tls_dynamic_gnu2_64"
12783 [(set (match_dup 2)
12784 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12787 [(set (match_operand:DI 0 "register_operand" "")
12788 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12790 (clobber (reg:CC FLAGS_REG))])]
12791 "TARGET_64BIT && TARGET_GNU2_TLS"
12793 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12794 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12797 (define_insn "*tls_dynamic_lea_64"
12798 [(set (match_operand:DI 0 "register_operand" "=r")
12799 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12801 "TARGET_64BIT && TARGET_GNU2_TLS"
12802 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12803 [(set_attr "type" "lea")
12804 (set_attr "mode" "DI")
12805 (set_attr "length" "7")
12806 (set_attr "length_address" "4")])
12808 (define_insn "*tls_dynamic_call_64"
12809 [(set (match_operand:DI 0 "register_operand" "=a")
12810 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12811 (match_operand:DI 2 "register_operand" "0")
12814 (clobber (reg:CC FLAGS_REG))]
12815 "TARGET_64BIT && TARGET_GNU2_TLS"
12816 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12817 [(set_attr "type" "call")
12818 (set_attr "length" "2")
12819 (set_attr "length_address" "0")])
12821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12822 [(set (match_operand:DI 0 "register_operand" "=&a")
12824 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12825 (match_operand:DI 3 "" "")
12828 (const:DI (unspec:DI
12829 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12831 (clobber (reg:CC FLAGS_REG))]
12832 "TARGET_64BIT && TARGET_GNU2_TLS"
12835 [(set (match_dup 0) (match_dup 4))]
12837 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12838 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12841 ;; These patterns match the binary 387 instructions for addM3, subM3,
12842 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12843 ;; SFmode. The first is the normal insn, the second the same insn but
12844 ;; with one operand a conversion, and the third the same insn but with
12845 ;; the other operand a conversion. The conversion may be SFmode or
12846 ;; SImode if the target mode DFmode, but only SImode if the target mode
12849 ;; Gcc is slightly more smart about handling normal two address instructions
12850 ;; so use special patterns for add and mull.
12852 (define_insn "*fop_<mode>_comm_mixed_avx"
12853 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12854 (match_operator:MODEF 3 "binary_fp_operator"
12855 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12856 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12857 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12858 && COMMUTATIVE_ARITH_P (operands[3])
12859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12860 "* return output_387_binary_op (insn, operands);"
12861 [(set (attr "type")
12862 (if_then_else (eq_attr "alternative" "1")
12863 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12864 (const_string "ssemul")
12865 (const_string "sseadd"))
12866 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12867 (const_string "fmul")
12868 (const_string "fop"))))
12869 (set_attr "prefix" "orig,maybe_vex")
12870 (set_attr "mode" "<MODE>")])
12872 (define_insn "*fop_<mode>_comm_mixed"
12873 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12874 (match_operator:MODEF 3 "binary_fp_operator"
12875 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12876 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12877 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12878 && COMMUTATIVE_ARITH_P (operands[3])
12879 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12880 "* return output_387_binary_op (insn, operands);"
12881 [(set (attr "type")
12882 (if_then_else (eq_attr "alternative" "1")
12883 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12884 (const_string "ssemul")
12885 (const_string "sseadd"))
12886 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12887 (const_string "fmul")
12888 (const_string "fop"))))
12889 (set_attr "mode" "<MODE>")])
12891 (define_insn "*fop_<mode>_comm_avx"
12892 [(set (match_operand:MODEF 0 "register_operand" "=x")
12893 (match_operator:MODEF 3 "binary_fp_operator"
12894 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12895 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12896 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12897 && COMMUTATIVE_ARITH_P (operands[3])
12898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12899 "* return output_387_binary_op (insn, operands);"
12900 [(set (attr "type")
12901 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12902 (const_string "ssemul")
12903 (const_string "sseadd")))
12904 (set_attr "prefix" "vex")
12905 (set_attr "mode" "<MODE>")])
12907 (define_insn "*fop_<mode>_comm_sse"
12908 [(set (match_operand:MODEF 0 "register_operand" "=x")
12909 (match_operator:MODEF 3 "binary_fp_operator"
12910 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12911 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12912 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12913 && COMMUTATIVE_ARITH_P (operands[3])
12914 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12915 "* return output_387_binary_op (insn, operands);"
12916 [(set (attr "type")
12917 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12918 (const_string "ssemul")
12919 (const_string "sseadd")))
12920 (set_attr "mode" "<MODE>")])
12922 (define_insn "*fop_<mode>_comm_i387"
12923 [(set (match_operand:MODEF 0 "register_operand" "=f")
12924 (match_operator:MODEF 3 "binary_fp_operator"
12925 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12926 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12927 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12928 && COMMUTATIVE_ARITH_P (operands[3])
12929 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12930 "* return output_387_binary_op (insn, operands);"
12931 [(set (attr "type")
12932 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12933 (const_string "fmul")
12934 (const_string "fop")))
12935 (set_attr "mode" "<MODE>")])
12937 (define_insn "*fop_<mode>_1_mixed_avx"
12938 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12939 (match_operator:MODEF 3 "binary_fp_operator"
12940 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12941 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12942 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12943 && !COMMUTATIVE_ARITH_P (operands[3])
12944 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12945 "* return output_387_binary_op (insn, operands);"
12946 [(set (attr "type")
12947 (cond [(and (eq_attr "alternative" "2")
12948 (match_operand:MODEF 3 "mult_operator" ""))
12949 (const_string "ssemul")
12950 (and (eq_attr "alternative" "2")
12951 (match_operand:MODEF 3 "div_operator" ""))
12952 (const_string "ssediv")
12953 (eq_attr "alternative" "2")
12954 (const_string "sseadd")
12955 (match_operand:MODEF 3 "mult_operator" "")
12956 (const_string "fmul")
12957 (match_operand:MODEF 3 "div_operator" "")
12958 (const_string "fdiv")
12960 (const_string "fop")))
12961 (set_attr "prefix" "orig,orig,maybe_vex")
12962 (set_attr "mode" "<MODE>")])
12964 (define_insn "*fop_<mode>_1_mixed"
12965 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12966 (match_operator:MODEF 3 "binary_fp_operator"
12967 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12968 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12969 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970 && !COMMUTATIVE_ARITH_P (operands[3])
12971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972 "* return output_387_binary_op (insn, operands);"
12973 [(set (attr "type")
12974 (cond [(and (eq_attr "alternative" "2")
12975 (match_operand:MODEF 3 "mult_operator" ""))
12976 (const_string "ssemul")
12977 (and (eq_attr "alternative" "2")
12978 (match_operand:MODEF 3 "div_operator" ""))
12979 (const_string "ssediv")
12980 (eq_attr "alternative" "2")
12981 (const_string "sseadd")
12982 (match_operand:MODEF 3 "mult_operator" "")
12983 (const_string "fmul")
12984 (match_operand:MODEF 3 "div_operator" "")
12985 (const_string "fdiv")
12987 (const_string "fop")))
12988 (set_attr "mode" "<MODE>")])
12990 (define_insn "*rcpsf2_sse"
12991 [(set (match_operand:SF 0 "register_operand" "=x")
12992 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12995 "%vrcpss\t{%1, %d0|%d0, %1}"
12996 [(set_attr "type" "sse")
12997 (set_attr "atom_sse_attr" "rcp")
12998 (set_attr "prefix" "maybe_vex")
12999 (set_attr "mode" "SF")])
13001 (define_insn "*fop_<mode>_1_avx"
13002 [(set (match_operand:MODEF 0 "register_operand" "=x")
13003 (match_operator:MODEF 3 "binary_fp_operator"
13004 [(match_operand:MODEF 1 "register_operand" "x")
13005 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13006 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13007 && !COMMUTATIVE_ARITH_P (operands[3])"
13008 "* return output_387_binary_op (insn, operands);"
13009 [(set (attr "type")
13010 (cond [(match_operand:MODEF 3 "mult_operator" "")
13011 (const_string "ssemul")
13012 (match_operand:MODEF 3 "div_operator" "")
13013 (const_string "ssediv")
13015 (const_string "sseadd")))
13016 (set_attr "prefix" "vex")
13017 (set_attr "mode" "<MODE>")])
13019 (define_insn "*fop_<mode>_1_sse"
13020 [(set (match_operand:MODEF 0 "register_operand" "=x")
13021 (match_operator:MODEF 3 "binary_fp_operator"
13022 [(match_operand:MODEF 1 "register_operand" "0")
13023 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13024 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13025 && !COMMUTATIVE_ARITH_P (operands[3])"
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(match_operand:MODEF 3 "mult_operator" "")
13029 (const_string "ssemul")
13030 (match_operand:MODEF 3 "div_operator" "")
13031 (const_string "ssediv")
13033 (const_string "sseadd")))
13034 (set_attr "mode" "<MODE>")])
13036 ;; This pattern is not fully shadowed by the pattern above.
13037 (define_insn "*fop_<mode>_1_i387"
13038 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13039 (match_operator:MODEF 3 "binary_fp_operator"
13040 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13041 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13042 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13043 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13044 && !COMMUTATIVE_ARITH_P (operands[3])
13045 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13046 "* return output_387_binary_op (insn, operands);"
13047 [(set (attr "type")
13048 (cond [(match_operand:MODEF 3 "mult_operator" "")
13049 (const_string "fmul")
13050 (match_operand:MODEF 3 "div_operator" "")
13051 (const_string "fdiv")
13053 (const_string "fop")))
13054 (set_attr "mode" "<MODE>")])
13056 ;; ??? Add SSE splitters for these!
13057 (define_insn "*fop_<MODEF:mode>_2_i387"
13058 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13059 (match_operator:MODEF 3 "binary_fp_operator"
13061 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13062 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13063 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13064 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13065 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13066 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13067 [(set (attr "type")
13068 (cond [(match_operand:MODEF 3 "mult_operator" "")
13069 (const_string "fmul")
13070 (match_operand:MODEF 3 "div_operator" "")
13071 (const_string "fdiv")
13073 (const_string "fop")))
13074 (set_attr "fp_int_src" "true")
13075 (set_attr "mode" "<X87MODEI12:MODE>")])
13077 (define_insn "*fop_<MODEF:mode>_3_i387"
13078 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079 (match_operator:MODEF 3 "binary_fp_operator"
13080 [(match_operand:MODEF 1 "register_operand" "0,0")
13082 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13083 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13084 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13085 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13086 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13087 [(set (attr "type")
13088 (cond [(match_operand:MODEF 3 "mult_operator" "")
13089 (const_string "fmul")
13090 (match_operand:MODEF 3 "div_operator" "")
13091 (const_string "fdiv")
13093 (const_string "fop")))
13094 (set_attr "fp_int_src" "true")
13095 (set_attr "mode" "<MODE>")])
13097 (define_insn "*fop_df_4_i387"
13098 [(set (match_operand:DF 0 "register_operand" "=f,f")
13099 (match_operator:DF 3 "binary_fp_operator"
13101 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13102 (match_operand:DF 2 "register_operand" "0,f")]))]
13103 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13105 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13106 "* return output_387_binary_op (insn, operands);"
13107 [(set (attr "type")
13108 (cond [(match_operand:DF 3 "mult_operator" "")
13109 (const_string "fmul")
13110 (match_operand:DF 3 "div_operator" "")
13111 (const_string "fdiv")
13113 (const_string "fop")))
13114 (set_attr "mode" "SF")])
13116 (define_insn "*fop_df_5_i387"
13117 [(set (match_operand:DF 0 "register_operand" "=f,f")
13118 (match_operator:DF 3 "binary_fp_operator"
13119 [(match_operand:DF 1 "register_operand" "0,f")
13121 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13122 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13123 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13124 "* return output_387_binary_op (insn, operands);"
13125 [(set (attr "type")
13126 (cond [(match_operand:DF 3 "mult_operator" "")
13127 (const_string "fmul")
13128 (match_operand:DF 3 "div_operator" "")
13129 (const_string "fdiv")
13131 (const_string "fop")))
13132 (set_attr "mode" "SF")])
13134 (define_insn "*fop_df_6_i387"
13135 [(set (match_operand:DF 0 "register_operand" "=f,f")
13136 (match_operator:DF 3 "binary_fp_operator"
13138 (match_operand:SF 1 "register_operand" "0,f"))
13140 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13141 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13142 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13143 "* return output_387_binary_op (insn, operands);"
13144 [(set (attr "type")
13145 (cond [(match_operand:DF 3 "mult_operator" "")
13146 (const_string "fmul")
13147 (match_operand:DF 3 "div_operator" "")
13148 (const_string "fdiv")
13150 (const_string "fop")))
13151 (set_attr "mode" "SF")])
13153 (define_insn "*fop_xf_comm_i387"
13154 [(set (match_operand:XF 0 "register_operand" "=f")
13155 (match_operator:XF 3 "binary_fp_operator"
13156 [(match_operand:XF 1 "register_operand" "%0")
13157 (match_operand:XF 2 "register_operand" "f")]))]
13159 && COMMUTATIVE_ARITH_P (operands[3])"
13160 "* return output_387_binary_op (insn, operands);"
13161 [(set (attr "type")
13162 (if_then_else (match_operand:XF 3 "mult_operator" "")
13163 (const_string "fmul")
13164 (const_string "fop")))
13165 (set_attr "mode" "XF")])
13167 (define_insn "*fop_xf_1_i387"
13168 [(set (match_operand:XF 0 "register_operand" "=f,f")
13169 (match_operator:XF 3 "binary_fp_operator"
13170 [(match_operand:XF 1 "register_operand" "0,f")
13171 (match_operand:XF 2 "register_operand" "f,0")]))]
13173 && !COMMUTATIVE_ARITH_P (operands[3])"
13174 "* return output_387_binary_op (insn, operands);"
13175 [(set (attr "type")
13176 (cond [(match_operand:XF 3 "mult_operator" "")
13177 (const_string "fmul")
13178 (match_operand:XF 3 "div_operator" "")
13179 (const_string "fdiv")
13181 (const_string "fop")))
13182 (set_attr "mode" "XF")])
13184 (define_insn "*fop_xf_2_i387"
13185 [(set (match_operand:XF 0 "register_operand" "=f,f")
13186 (match_operator:XF 3 "binary_fp_operator"
13188 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13189 (match_operand:XF 2 "register_operand" "0,0")]))]
13190 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13191 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13192 [(set (attr "type")
13193 (cond [(match_operand:XF 3 "mult_operator" "")
13194 (const_string "fmul")
13195 (match_operand:XF 3 "div_operator" "")
13196 (const_string "fdiv")
13198 (const_string "fop")))
13199 (set_attr "fp_int_src" "true")
13200 (set_attr "mode" "<MODE>")])
13202 (define_insn "*fop_xf_3_i387"
13203 [(set (match_operand:XF 0 "register_operand" "=f,f")
13204 (match_operator:XF 3 "binary_fp_operator"
13205 [(match_operand:XF 1 "register_operand" "0,0")
13207 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13208 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13209 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13210 [(set (attr "type")
13211 (cond [(match_operand:XF 3 "mult_operator" "")
13212 (const_string "fmul")
13213 (match_operand:XF 3 "div_operator" "")
13214 (const_string "fdiv")
13216 (const_string "fop")))
13217 (set_attr "fp_int_src" "true")
13218 (set_attr "mode" "<MODE>")])
13220 (define_insn "*fop_xf_4_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f,f")
13222 (match_operator:XF 3 "binary_fp_operator"
13224 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13225 (match_operand:XF 2 "register_operand" "0,f")]))]
13227 "* return output_387_binary_op (insn, operands);"
13228 [(set (attr "type")
13229 (cond [(match_operand:XF 3 "mult_operator" "")
13230 (const_string "fmul")
13231 (match_operand:XF 3 "div_operator" "")
13232 (const_string "fdiv")
13234 (const_string "fop")))
13235 (set_attr "mode" "<MODE>")])
13237 (define_insn "*fop_xf_5_i387"
13238 [(set (match_operand:XF 0 "register_operand" "=f,f")
13239 (match_operator:XF 3 "binary_fp_operator"
13240 [(match_operand:XF 1 "register_operand" "0,f")
13242 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13244 "* return output_387_binary_op (insn, operands);"
13245 [(set (attr "type")
13246 (cond [(match_operand:XF 3 "mult_operator" "")
13247 (const_string "fmul")
13248 (match_operand:XF 3 "div_operator" "")
13249 (const_string "fdiv")
13251 (const_string "fop")))
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_xf_6_i387"
13255 [(set (match_operand:XF 0 "register_operand" "=f,f")
13256 (match_operator:XF 3 "binary_fp_operator"
13258 (match_operand:MODEF 1 "register_operand" "0,f"))
13260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13262 "* return output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (cond [(match_operand:XF 3 "mult_operator" "")
13265 (const_string "fmul")
13266 (match_operand:XF 3 "div_operator" "")
13267 (const_string "fdiv")
13269 (const_string "fop")))
13270 (set_attr "mode" "<MODE>")])
13273 [(set (match_operand 0 "register_operand" "")
13274 (match_operator 3 "binary_fp_operator"
13275 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13276 (match_operand 2 "register_operand" "")]))]
13278 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13279 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13282 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13283 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13284 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13285 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13286 GET_MODE (operands[3]),
13289 ix86_free_from_memory (GET_MODE (operands[1]));
13294 [(set (match_operand 0 "register_operand" "")
13295 (match_operator 3 "binary_fp_operator"
13296 [(match_operand 1 "register_operand" "")
13297 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13299 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13300 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13303 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13304 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13305 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13306 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13307 GET_MODE (operands[3]),
13310 ix86_free_from_memory (GET_MODE (operands[2]));
13314 ;; FPU special functions.
13316 ;; This pattern implements a no-op XFmode truncation for
13317 ;; all fancy i386 XFmode math functions.
13319 (define_insn "truncxf<mode>2_i387_noop_unspec"
13320 [(set (match_operand:MODEF 0 "register_operand" "=f")
13321 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13322 UNSPEC_TRUNC_NOOP))]
13323 "TARGET_USE_FANCY_MATH_387"
13324 "* return output_387_reg_move (insn, operands);"
13325 [(set_attr "type" "fmov")
13326 (set_attr "mode" "<MODE>")])
13328 (define_insn "sqrtxf2"
13329 [(set (match_operand:XF 0 "register_operand" "=f")
13330 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13331 "TARGET_USE_FANCY_MATH_387"
13333 [(set_attr "type" "fpspc")
13334 (set_attr "mode" "XF")
13335 (set_attr "athlon_decode" "direct")
13336 (set_attr "amdfam10_decode" "direct")
13337 (set_attr "bdver1_decode" "direct")])
13339 (define_insn "sqrt_extend<mode>xf2_i387"
13340 [(set (match_operand:XF 0 "register_operand" "=f")
13343 (match_operand:MODEF 1 "register_operand" "0"))))]
13344 "TARGET_USE_FANCY_MATH_387"
13346 [(set_attr "type" "fpspc")
13347 (set_attr "mode" "XF")
13348 (set_attr "athlon_decode" "direct")
13349 (set_attr "amdfam10_decode" "direct")
13350 (set_attr "bdver1_decode" "direct")])
13352 (define_insn "*rsqrtsf2_sse"
13353 [(set (match_operand:SF 0 "register_operand" "=x")
13354 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13357 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13358 [(set_attr "type" "sse")
13359 (set_attr "atom_sse_attr" "rcp")
13360 (set_attr "prefix" "maybe_vex")
13361 (set_attr "mode" "SF")])
13363 (define_expand "rsqrtsf2"
13364 [(set (match_operand:SF 0 "register_operand" "")
13365 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13369 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13373 (define_insn "*sqrt<mode>2_sse"
13374 [(set (match_operand:MODEF 0 "register_operand" "=x")
13376 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13378 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13379 [(set_attr "type" "sse")
13380 (set_attr "atom_sse_attr" "sqrt")
13381 (set_attr "prefix" "maybe_vex")
13382 (set_attr "mode" "<MODE>")
13383 (set_attr "athlon_decode" "*")
13384 (set_attr "amdfam10_decode" "*")
13385 (set_attr "bdver1_decode" "*")])
13387 (define_expand "sqrt<mode>2"
13388 [(set (match_operand:MODEF 0 "register_operand" "")
13390 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13391 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13392 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13394 if (<MODE>mode == SFmode
13395 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13396 && flag_finite_math_only && !flag_trapping_math
13397 && flag_unsafe_math_optimizations)
13399 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13403 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13405 rtx op0 = gen_reg_rtx (XFmode);
13406 rtx op1 = force_reg (<MODE>mode, operands[1]);
13408 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13409 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13414 (define_insn "fpremxf4_i387"
13415 [(set (match_operand:XF 0 "register_operand" "=f")
13416 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13417 (match_operand:XF 3 "register_operand" "1")]
13419 (set (match_operand:XF 1 "register_operand" "=u")
13420 (unspec:XF [(match_dup 2) (match_dup 3)]
13422 (set (reg:CCFP FPSR_REG)
13423 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13425 "TARGET_USE_FANCY_MATH_387"
13427 [(set_attr "type" "fpspc")
13428 (set_attr "mode" "XF")])
13430 (define_expand "fmodxf3"
13431 [(use (match_operand:XF 0 "register_operand" ""))
13432 (use (match_operand:XF 1 "general_operand" ""))
13433 (use (match_operand:XF 2 "general_operand" ""))]
13434 "TARGET_USE_FANCY_MATH_387"
13436 rtx label = gen_label_rtx ();
13438 rtx op1 = gen_reg_rtx (XFmode);
13439 rtx op2 = gen_reg_rtx (XFmode);
13441 emit_move_insn (op2, operands[2]);
13442 emit_move_insn (op1, operands[1]);
13444 emit_label (label);
13445 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13446 ix86_emit_fp_unordered_jump (label);
13447 LABEL_NUSES (label) = 1;
13449 emit_move_insn (operands[0], op1);
13453 (define_expand "fmod<mode>3"
13454 [(use (match_operand:MODEF 0 "register_operand" ""))
13455 (use (match_operand:MODEF 1 "general_operand" ""))
13456 (use (match_operand:MODEF 2 "general_operand" ""))]
13457 "TARGET_USE_FANCY_MATH_387"
13459 rtx (*gen_truncxf) (rtx, rtx);
13461 rtx label = gen_label_rtx ();
13463 rtx op1 = gen_reg_rtx (XFmode);
13464 rtx op2 = gen_reg_rtx (XFmode);
13466 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13469 emit_label (label);
13470 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13471 ix86_emit_fp_unordered_jump (label);
13472 LABEL_NUSES (label) = 1;
13474 /* Truncate the result properly for strict SSE math. */
13475 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13476 && !TARGET_MIX_SSE_I387)
13477 gen_truncxf = gen_truncxf<mode>2;
13479 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13481 emit_insn (gen_truncxf (operands[0], op1));
13485 (define_insn "fprem1xf4_i387"
13486 [(set (match_operand:XF 0 "register_operand" "=f")
13487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13488 (match_operand:XF 3 "register_operand" "1")]
13490 (set (match_operand:XF 1 "register_operand" "=u")
13491 (unspec:XF [(match_dup 2) (match_dup 3)]
13493 (set (reg:CCFP FPSR_REG)
13494 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13496 "TARGET_USE_FANCY_MATH_387"
13498 [(set_attr "type" "fpspc")
13499 (set_attr "mode" "XF")])
13501 (define_expand "remainderxf3"
13502 [(use (match_operand:XF 0 "register_operand" ""))
13503 (use (match_operand:XF 1 "general_operand" ""))
13504 (use (match_operand:XF 2 "general_operand" ""))]
13505 "TARGET_USE_FANCY_MATH_387"
13507 rtx label = gen_label_rtx ();
13509 rtx op1 = gen_reg_rtx (XFmode);
13510 rtx op2 = gen_reg_rtx (XFmode);
13512 emit_move_insn (op2, operands[2]);
13513 emit_move_insn (op1, operands[1]);
13515 emit_label (label);
13516 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13517 ix86_emit_fp_unordered_jump (label);
13518 LABEL_NUSES (label) = 1;
13520 emit_move_insn (operands[0], op1);
13524 (define_expand "remainder<mode>3"
13525 [(use (match_operand:MODEF 0 "register_operand" ""))
13526 (use (match_operand:MODEF 1 "general_operand" ""))
13527 (use (match_operand:MODEF 2 "general_operand" ""))]
13528 "TARGET_USE_FANCY_MATH_387"
13530 rtx (*gen_truncxf) (rtx, rtx);
13532 rtx label = gen_label_rtx ();
13534 rtx op1 = gen_reg_rtx (XFmode);
13535 rtx op2 = gen_reg_rtx (XFmode);
13537 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13540 emit_label (label);
13542 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13543 ix86_emit_fp_unordered_jump (label);
13544 LABEL_NUSES (label) = 1;
13546 /* Truncate the result properly for strict SSE math. */
13547 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13548 && !TARGET_MIX_SSE_I387)
13549 gen_truncxf = gen_truncxf<mode>2;
13551 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13553 emit_insn (gen_truncxf (operands[0], op1));
13557 (define_insn "*sinxf2_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && flag_unsafe_math_optimizations"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_insn "*sin_extend<mode>xf2_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(float_extend:XF
13569 (match_operand:MODEF 1 "register_operand" "0"))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13573 || TARGET_MIX_SSE_I387)
13574 && flag_unsafe_math_optimizations"
13576 [(set_attr "type" "fpspc")
13577 (set_attr "mode" "XF")])
13579 (define_insn "*cosxf2_i387"
13580 [(set (match_operand:XF 0 "register_operand" "=f")
13581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13582 "TARGET_USE_FANCY_MATH_387
13583 && flag_unsafe_math_optimizations"
13585 [(set_attr "type" "fpspc")
13586 (set_attr "mode" "XF")])
13588 (define_insn "*cos_extend<mode>xf2_i387"
13589 [(set (match_operand:XF 0 "register_operand" "=f")
13590 (unspec:XF [(float_extend:XF
13591 (match_operand:MODEF 1 "register_operand" "0"))]
13593 "TARGET_USE_FANCY_MATH_387
13594 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13595 || TARGET_MIX_SSE_I387)
13596 && flag_unsafe_math_optimizations"
13598 [(set_attr "type" "fpspc")
13599 (set_attr "mode" "XF")])
13601 ;; When sincos pattern is defined, sin and cos builtin functions will be
13602 ;; expanded to sincos pattern with one of its outputs left unused.
13603 ;; CSE pass will figure out if two sincos patterns can be combined,
13604 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13605 ;; depending on the unused output.
13607 (define_insn "sincosxf3"
13608 [(set (match_operand:XF 0 "register_operand" "=f")
13609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13610 UNSPEC_SINCOS_COS))
13611 (set (match_operand:XF 1 "register_operand" "=u")
13612 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && flag_unsafe_math_optimizations"
13616 [(set_attr "type" "fpspc")
13617 (set_attr "mode" "XF")])
13620 [(set (match_operand:XF 0 "register_operand" "")
13621 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13622 UNSPEC_SINCOS_COS))
13623 (set (match_operand:XF 1 "register_operand" "")
13624 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13625 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13626 && !(reload_completed || reload_in_progress)"
13627 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13630 [(set (match_operand:XF 0 "register_operand" "")
13631 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13632 UNSPEC_SINCOS_COS))
13633 (set (match_operand:XF 1 "register_operand" "")
13634 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13635 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13636 && !(reload_completed || reload_in_progress)"
13637 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13639 (define_insn "sincos_extend<mode>xf3_i387"
13640 [(set (match_operand:XF 0 "register_operand" "=f")
13641 (unspec:XF [(float_extend:XF
13642 (match_operand:MODEF 2 "register_operand" "0"))]
13643 UNSPEC_SINCOS_COS))
13644 (set (match_operand:XF 1 "register_operand" "=u")
13645 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13646 "TARGET_USE_FANCY_MATH_387
13647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13648 || TARGET_MIX_SSE_I387)
13649 && flag_unsafe_math_optimizations"
13651 [(set_attr "type" "fpspc")
13652 (set_attr "mode" "XF")])
13655 [(set (match_operand:XF 0 "register_operand" "")
13656 (unspec:XF [(float_extend:XF
13657 (match_operand:MODEF 2 "register_operand" ""))]
13658 UNSPEC_SINCOS_COS))
13659 (set (match_operand:XF 1 "register_operand" "")
13660 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13661 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13662 && !(reload_completed || reload_in_progress)"
13663 [(set (match_dup 1)
13664 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13667 [(set (match_operand:XF 0 "register_operand" "")
13668 (unspec:XF [(float_extend:XF
13669 (match_operand:MODEF 2 "register_operand" ""))]
13670 UNSPEC_SINCOS_COS))
13671 (set (match_operand:XF 1 "register_operand" "")
13672 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13673 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13674 && !(reload_completed || reload_in_progress)"
13675 [(set (match_dup 0)
13676 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13678 (define_expand "sincos<mode>3"
13679 [(use (match_operand:MODEF 0 "register_operand" ""))
13680 (use (match_operand:MODEF 1 "register_operand" ""))
13681 (use (match_operand:MODEF 2 "register_operand" ""))]
13682 "TARGET_USE_FANCY_MATH_387
13683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13684 || TARGET_MIX_SSE_I387)
13685 && flag_unsafe_math_optimizations"
13687 rtx op0 = gen_reg_rtx (XFmode);
13688 rtx op1 = gen_reg_rtx (XFmode);
13690 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13691 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13692 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13696 (define_insn "fptanxf4_i387"
13697 [(set (match_operand:XF 0 "register_operand" "=f")
13698 (match_operand:XF 3 "const_double_operand" "F"))
13699 (set (match_operand:XF 1 "register_operand" "=u")
13700 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13702 "TARGET_USE_FANCY_MATH_387
13703 && flag_unsafe_math_optimizations
13704 && standard_80387_constant_p (operands[3]) == 2"
13706 [(set_attr "type" "fpspc")
13707 (set_attr "mode" "XF")])
13709 (define_insn "fptan_extend<mode>xf4_i387"
13710 [(set (match_operand:MODEF 0 "register_operand" "=f")
13711 (match_operand:MODEF 3 "const_double_operand" "F"))
13712 (set (match_operand:XF 1 "register_operand" "=u")
13713 (unspec:XF [(float_extend:XF
13714 (match_operand:MODEF 2 "register_operand" "0"))]
13716 "TARGET_USE_FANCY_MATH_387
13717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718 || TARGET_MIX_SSE_I387)
13719 && flag_unsafe_math_optimizations
13720 && standard_80387_constant_p (operands[3]) == 2"
13722 [(set_attr "type" "fpspc")
13723 (set_attr "mode" "XF")])
13725 (define_expand "tanxf2"
13726 [(use (match_operand:XF 0 "register_operand" ""))
13727 (use (match_operand:XF 1 "register_operand" ""))]
13728 "TARGET_USE_FANCY_MATH_387
13729 && flag_unsafe_math_optimizations"
13731 rtx one = gen_reg_rtx (XFmode);
13732 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13734 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13738 (define_expand "tan<mode>2"
13739 [(use (match_operand:MODEF 0 "register_operand" ""))
13740 (use (match_operand:MODEF 1 "register_operand" ""))]
13741 "TARGET_USE_FANCY_MATH_387
13742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13743 || TARGET_MIX_SSE_I387)
13744 && flag_unsafe_math_optimizations"
13746 rtx op0 = gen_reg_rtx (XFmode);
13748 rtx one = gen_reg_rtx (<MODE>mode);
13749 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13751 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13752 operands[1], op2));
13753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13757 (define_insn "*fpatanxf3_i387"
13758 [(set (match_operand:XF 0 "register_operand" "=f")
13759 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13760 (match_operand:XF 2 "register_operand" "u")]
13762 (clobber (match_scratch:XF 3 "=2"))]
13763 "TARGET_USE_FANCY_MATH_387
13764 && flag_unsafe_math_optimizations"
13766 [(set_attr "type" "fpspc")
13767 (set_attr "mode" "XF")])
13769 (define_insn "fpatan_extend<mode>xf3_i387"
13770 [(set (match_operand:XF 0 "register_operand" "=f")
13771 (unspec:XF [(float_extend:XF
13772 (match_operand:MODEF 1 "register_operand" "0"))
13774 (match_operand:MODEF 2 "register_operand" "u"))]
13776 (clobber (match_scratch:XF 3 "=2"))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13779 || TARGET_MIX_SSE_I387)
13780 && flag_unsafe_math_optimizations"
13782 [(set_attr "type" "fpspc")
13783 (set_attr "mode" "XF")])
13785 (define_expand "atan2xf3"
13786 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13787 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13788 (match_operand:XF 1 "register_operand" "")]
13790 (clobber (match_scratch:XF 3 ""))])]
13791 "TARGET_USE_FANCY_MATH_387
13792 && flag_unsafe_math_optimizations")
13794 (define_expand "atan2<mode>3"
13795 [(use (match_operand:MODEF 0 "register_operand" ""))
13796 (use (match_operand:MODEF 1 "register_operand" ""))
13797 (use (match_operand:MODEF 2 "register_operand" ""))]
13798 "TARGET_USE_FANCY_MATH_387
13799 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13800 || TARGET_MIX_SSE_I387)
13801 && flag_unsafe_math_optimizations"
13803 rtx op0 = gen_reg_rtx (XFmode);
13805 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13810 (define_expand "atanxf2"
13811 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13812 (unspec:XF [(match_dup 2)
13813 (match_operand:XF 1 "register_operand" "")]
13815 (clobber (match_scratch:XF 3 ""))])]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations"
13819 operands[2] = gen_reg_rtx (XFmode);
13820 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13823 (define_expand "atan<mode>2"
13824 [(use (match_operand:MODEF 0 "register_operand" ""))
13825 (use (match_operand:MODEF 1 "register_operand" ""))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations"
13831 rtx op0 = gen_reg_rtx (XFmode);
13833 rtx op2 = gen_reg_rtx (<MODE>mode);
13834 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13836 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13841 (define_expand "asinxf2"
13842 [(set (match_dup 2)
13843 (mult:XF (match_operand:XF 1 "register_operand" "")
13845 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13846 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13847 (parallel [(set (match_operand:XF 0 "register_operand" "")
13848 (unspec:XF [(match_dup 5) (match_dup 1)]
13850 (clobber (match_scratch:XF 6 ""))])]
13851 "TARGET_USE_FANCY_MATH_387
13852 && flag_unsafe_math_optimizations"
13856 if (optimize_insn_for_size_p ())
13859 for (i = 2; i < 6; i++)
13860 operands[i] = gen_reg_rtx (XFmode);
13862 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13865 (define_expand "asin<mode>2"
13866 [(use (match_operand:MODEF 0 "register_operand" ""))
13867 (use (match_operand:MODEF 1 "general_operand" ""))]
13868 "TARGET_USE_FANCY_MATH_387
13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870 || TARGET_MIX_SSE_I387)
13871 && flag_unsafe_math_optimizations"
13873 rtx op0 = gen_reg_rtx (XFmode);
13874 rtx op1 = gen_reg_rtx (XFmode);
13876 if (optimize_insn_for_size_p ())
13879 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13880 emit_insn (gen_asinxf2 (op0, op1));
13881 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13885 (define_expand "acosxf2"
13886 [(set (match_dup 2)
13887 (mult:XF (match_operand:XF 1 "register_operand" "")
13889 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13890 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13891 (parallel [(set (match_operand:XF 0 "register_operand" "")
13892 (unspec:XF [(match_dup 1) (match_dup 5)]
13894 (clobber (match_scratch:XF 6 ""))])]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13900 if (optimize_insn_for_size_p ())
13903 for (i = 2; i < 6; i++)
13904 operands[i] = gen_reg_rtx (XFmode);
13906 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13909 (define_expand "acos<mode>2"
13910 [(use (match_operand:MODEF 0 "register_operand" ""))
13911 (use (match_operand:MODEF 1 "general_operand" ""))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914 || TARGET_MIX_SSE_I387)
13915 && flag_unsafe_math_optimizations"
13917 rtx op0 = gen_reg_rtx (XFmode);
13918 rtx op1 = gen_reg_rtx (XFmode);
13920 if (optimize_insn_for_size_p ())
13923 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13924 emit_insn (gen_acosxf2 (op0, op1));
13925 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13929 (define_insn "fyl2xxf3_i387"
13930 [(set (match_operand:XF 0 "register_operand" "=f")
13931 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13932 (match_operand:XF 2 "register_operand" "u")]
13934 (clobber (match_scratch:XF 3 "=2"))]
13935 "TARGET_USE_FANCY_MATH_387
13936 && flag_unsafe_math_optimizations"
13938 [(set_attr "type" "fpspc")
13939 (set_attr "mode" "XF")])
13941 (define_insn "fyl2x_extend<mode>xf3_i387"
13942 [(set (match_operand:XF 0 "register_operand" "=f")
13943 (unspec:XF [(float_extend:XF
13944 (match_operand:MODEF 1 "register_operand" "0"))
13945 (match_operand:XF 2 "register_operand" "u")]
13947 (clobber (match_scratch:XF 3 "=2"))]
13948 "TARGET_USE_FANCY_MATH_387
13949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13950 || TARGET_MIX_SSE_I387)
13951 && flag_unsafe_math_optimizations"
13953 [(set_attr "type" "fpspc")
13954 (set_attr "mode" "XF")])
13956 (define_expand "logxf2"
13957 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13958 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13959 (match_dup 2)] UNSPEC_FYL2X))
13960 (clobber (match_scratch:XF 3 ""))])]
13961 "TARGET_USE_FANCY_MATH_387
13962 && flag_unsafe_math_optimizations"
13964 operands[2] = gen_reg_rtx (XFmode);
13965 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13968 (define_expand "log<mode>2"
13969 [(use (match_operand:MODEF 0 "register_operand" ""))
13970 (use (match_operand:MODEF 1 "register_operand" ""))]
13971 "TARGET_USE_FANCY_MATH_387
13972 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13973 || TARGET_MIX_SSE_I387)
13974 && flag_unsafe_math_optimizations"
13976 rtx op0 = gen_reg_rtx (XFmode);
13978 rtx op2 = gen_reg_rtx (XFmode);
13979 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13981 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13982 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13986 (define_expand "log10xf2"
13987 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13988 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13989 (match_dup 2)] UNSPEC_FYL2X))
13990 (clobber (match_scratch:XF 3 ""))])]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13994 operands[2] = gen_reg_rtx (XFmode);
13995 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13998 (define_expand "log10<mode>2"
13999 [(use (match_operand:MODEF 0 "register_operand" ""))
14000 (use (match_operand:MODEF 1 "register_operand" ""))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003 || TARGET_MIX_SSE_I387)
14004 && flag_unsafe_math_optimizations"
14006 rtx op0 = gen_reg_rtx (XFmode);
14008 rtx op2 = gen_reg_rtx (XFmode);
14009 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14011 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14012 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14016 (define_expand "log2xf2"
14017 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14018 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14019 (match_dup 2)] UNSPEC_FYL2X))
14020 (clobber (match_scratch:XF 3 ""))])]
14021 "TARGET_USE_FANCY_MATH_387
14022 && flag_unsafe_math_optimizations"
14024 operands[2] = gen_reg_rtx (XFmode);
14025 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14028 (define_expand "log2<mode>2"
14029 [(use (match_operand:MODEF 0 "register_operand" ""))
14030 (use (match_operand:MODEF 1 "register_operand" ""))]
14031 "TARGET_USE_FANCY_MATH_387
14032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14033 || TARGET_MIX_SSE_I387)
14034 && flag_unsafe_math_optimizations"
14036 rtx op0 = gen_reg_rtx (XFmode);
14038 rtx op2 = gen_reg_rtx (XFmode);
14039 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14041 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14042 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14046 (define_insn "fyl2xp1xf3_i387"
14047 [(set (match_operand:XF 0 "register_operand" "=f")
14048 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14049 (match_operand:XF 2 "register_operand" "u")]
14051 (clobber (match_scratch:XF 3 "=2"))]
14052 "TARGET_USE_FANCY_MATH_387
14053 && flag_unsafe_math_optimizations"
14055 [(set_attr "type" "fpspc")
14056 (set_attr "mode" "XF")])
14058 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14059 [(set (match_operand:XF 0 "register_operand" "=f")
14060 (unspec:XF [(float_extend:XF
14061 (match_operand:MODEF 1 "register_operand" "0"))
14062 (match_operand:XF 2 "register_operand" "u")]
14064 (clobber (match_scratch:XF 3 "=2"))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067 || TARGET_MIX_SSE_I387)
14068 && flag_unsafe_math_optimizations"
14070 [(set_attr "type" "fpspc")
14071 (set_attr "mode" "XF")])
14073 (define_expand "log1pxf2"
14074 [(use (match_operand:XF 0 "register_operand" ""))
14075 (use (match_operand:XF 1 "register_operand" ""))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14079 if (optimize_insn_for_size_p ())
14082 ix86_emit_i387_log1p (operands[0], operands[1]);
14086 (define_expand "log1p<mode>2"
14087 [(use (match_operand:MODEF 0 "register_operand" ""))
14088 (use (match_operand:MODEF 1 "register_operand" ""))]
14089 "TARGET_USE_FANCY_MATH_387
14090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091 || TARGET_MIX_SSE_I387)
14092 && flag_unsafe_math_optimizations"
14096 if (optimize_insn_for_size_p ())
14099 op0 = gen_reg_rtx (XFmode);
14101 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14103 ix86_emit_i387_log1p (op0, operands[1]);
14104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108 (define_insn "fxtractxf3_i387"
14109 [(set (match_operand:XF 0 "register_operand" "=f")
14110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14111 UNSPEC_XTRACT_FRACT))
14112 (set (match_operand:XF 1 "register_operand" "=u")
14113 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && flag_unsafe_math_optimizations"
14117 [(set_attr "type" "fpspc")
14118 (set_attr "mode" "XF")])
14120 (define_insn "fxtract_extend<mode>xf3_i387"
14121 [(set (match_operand:XF 0 "register_operand" "=f")
14122 (unspec:XF [(float_extend:XF
14123 (match_operand:MODEF 2 "register_operand" "0"))]
14124 UNSPEC_XTRACT_FRACT))
14125 (set (match_operand:XF 1 "register_operand" "=u")
14126 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14127 "TARGET_USE_FANCY_MATH_387
14128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14129 || TARGET_MIX_SSE_I387)
14130 && flag_unsafe_math_optimizations"
14132 [(set_attr "type" "fpspc")
14133 (set_attr "mode" "XF")])
14135 (define_expand "logbxf2"
14136 [(parallel [(set (match_dup 2)
14137 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14138 UNSPEC_XTRACT_FRACT))
14139 (set (match_operand:XF 0 "register_operand" "")
14140 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14141 "TARGET_USE_FANCY_MATH_387
14142 && flag_unsafe_math_optimizations"
14143 "operands[2] = gen_reg_rtx (XFmode);")
14145 (define_expand "logb<mode>2"
14146 [(use (match_operand:MODEF 0 "register_operand" ""))
14147 (use (match_operand:MODEF 1 "register_operand" ""))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations"
14153 rtx op0 = gen_reg_rtx (XFmode);
14154 rtx op1 = gen_reg_rtx (XFmode);
14156 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14161 (define_expand "ilogbxf2"
14162 [(use (match_operand:SI 0 "register_operand" ""))
14163 (use (match_operand:XF 1 "register_operand" ""))]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14169 if (optimize_insn_for_size_p ())
14172 op0 = gen_reg_rtx (XFmode);
14173 op1 = gen_reg_rtx (XFmode);
14175 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14176 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14180 (define_expand "ilogb<mode>2"
14181 [(use (match_operand:SI 0 "register_operand" ""))
14182 (use (match_operand:MODEF 1 "register_operand" ""))]
14183 "TARGET_USE_FANCY_MATH_387
14184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14185 || TARGET_MIX_SSE_I387)
14186 && flag_unsafe_math_optimizations"
14190 if (optimize_insn_for_size_p ())
14193 op0 = gen_reg_rtx (XFmode);
14194 op1 = gen_reg_rtx (XFmode);
14196 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14197 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14201 (define_insn "*f2xm1xf2_i387"
14202 [(set (match_operand:XF 0 "register_operand" "=f")
14203 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14205 "TARGET_USE_FANCY_MATH_387
14206 && flag_unsafe_math_optimizations"
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "XF")])
14211 (define_insn "*fscalexf4_i387"
14212 [(set (match_operand:XF 0 "register_operand" "=f")
14213 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14214 (match_operand:XF 3 "register_operand" "1")]
14215 UNSPEC_FSCALE_FRACT))
14216 (set (match_operand:XF 1 "register_operand" "=u")
14217 (unspec:XF [(match_dup 2) (match_dup 3)]
14218 UNSPEC_FSCALE_EXP))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14222 [(set_attr "type" "fpspc")
14223 (set_attr "mode" "XF")])
14225 (define_expand "expNcorexf3"
14226 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14227 (match_operand:XF 2 "register_operand" "")))
14228 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14229 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14230 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14231 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14232 (parallel [(set (match_operand:XF 0 "register_operand" "")
14233 (unspec:XF [(match_dup 8) (match_dup 4)]
14234 UNSPEC_FSCALE_FRACT))
14236 (unspec:XF [(match_dup 8) (match_dup 4)]
14237 UNSPEC_FSCALE_EXP))])]
14238 "TARGET_USE_FANCY_MATH_387
14239 && flag_unsafe_math_optimizations"
14243 if (optimize_insn_for_size_p ())
14246 for (i = 3; i < 10; i++)
14247 operands[i] = gen_reg_rtx (XFmode);
14249 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14252 (define_expand "expxf2"
14253 [(use (match_operand:XF 0 "register_operand" ""))
14254 (use (match_operand:XF 1 "register_operand" ""))]
14255 "TARGET_USE_FANCY_MATH_387
14256 && flag_unsafe_math_optimizations"
14260 if (optimize_insn_for_size_p ())
14263 op2 = gen_reg_rtx (XFmode);
14264 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14266 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14270 (define_expand "exp<mode>2"
14271 [(use (match_operand:MODEF 0 "register_operand" ""))
14272 (use (match_operand:MODEF 1 "general_operand" ""))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14275 || TARGET_MIX_SSE_I387)
14276 && flag_unsafe_math_optimizations"
14280 if (optimize_insn_for_size_p ())
14283 op0 = gen_reg_rtx (XFmode);
14284 op1 = gen_reg_rtx (XFmode);
14286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287 emit_insn (gen_expxf2 (op0, op1));
14288 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292 (define_expand "exp10xf2"
14293 [(use (match_operand:XF 0 "register_operand" ""))
14294 (use (match_operand:XF 1 "register_operand" ""))]
14295 "TARGET_USE_FANCY_MATH_387
14296 && flag_unsafe_math_optimizations"
14300 if (optimize_insn_for_size_p ())
14303 op2 = gen_reg_rtx (XFmode);
14304 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14306 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14310 (define_expand "exp10<mode>2"
14311 [(use (match_operand:MODEF 0 "register_operand" ""))
14312 (use (match_operand:MODEF 1 "general_operand" ""))]
14313 "TARGET_USE_FANCY_MATH_387
14314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315 || TARGET_MIX_SSE_I387)
14316 && flag_unsafe_math_optimizations"
14320 if (optimize_insn_for_size_p ())
14323 op0 = gen_reg_rtx (XFmode);
14324 op1 = gen_reg_rtx (XFmode);
14326 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14327 emit_insn (gen_exp10xf2 (op0, op1));
14328 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14332 (define_expand "exp2xf2"
14333 [(use (match_operand:XF 0 "register_operand" ""))
14334 (use (match_operand:XF 1 "register_operand" ""))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && flag_unsafe_math_optimizations"
14340 if (optimize_insn_for_size_p ())
14343 op2 = gen_reg_rtx (XFmode);
14344 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14346 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14350 (define_expand "exp2<mode>2"
14351 [(use (match_operand:MODEF 0 "register_operand" ""))
14352 (use (match_operand:MODEF 1 "general_operand" ""))]
14353 "TARGET_USE_FANCY_MATH_387
14354 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14355 || TARGET_MIX_SSE_I387)
14356 && flag_unsafe_math_optimizations"
14360 if (optimize_insn_for_size_p ())
14363 op0 = gen_reg_rtx (XFmode);
14364 op1 = gen_reg_rtx (XFmode);
14366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367 emit_insn (gen_exp2xf2 (op0, op1));
14368 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14372 (define_expand "expm1xf2"
14373 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14375 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14376 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14377 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14378 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14379 (parallel [(set (match_dup 7)
14380 (unspec:XF [(match_dup 6) (match_dup 4)]
14381 UNSPEC_FSCALE_FRACT))
14383 (unspec:XF [(match_dup 6) (match_dup 4)]
14384 UNSPEC_FSCALE_EXP))])
14385 (parallel [(set (match_dup 10)
14386 (unspec:XF [(match_dup 9) (match_dup 8)]
14387 UNSPEC_FSCALE_FRACT))
14388 (set (match_dup 11)
14389 (unspec:XF [(match_dup 9) (match_dup 8)]
14390 UNSPEC_FSCALE_EXP))])
14391 (set (match_dup 12) (minus:XF (match_dup 10)
14392 (float_extend:XF (match_dup 13))))
14393 (set (match_operand:XF 0 "register_operand" "")
14394 (plus:XF (match_dup 12) (match_dup 7)))]
14395 "TARGET_USE_FANCY_MATH_387
14396 && flag_unsafe_math_optimizations"
14400 if (optimize_insn_for_size_p ())
14403 for (i = 2; i < 13; i++)
14404 operands[i] = gen_reg_rtx (XFmode);
14407 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14409 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14412 (define_expand "expm1<mode>2"
14413 [(use (match_operand:MODEF 0 "register_operand" ""))
14414 (use (match_operand:MODEF 1 "general_operand" ""))]
14415 "TARGET_USE_FANCY_MATH_387
14416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417 || TARGET_MIX_SSE_I387)
14418 && flag_unsafe_math_optimizations"
14422 if (optimize_insn_for_size_p ())
14425 op0 = gen_reg_rtx (XFmode);
14426 op1 = gen_reg_rtx (XFmode);
14428 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14429 emit_insn (gen_expm1xf2 (op0, op1));
14430 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14434 (define_expand "ldexpxf3"
14435 [(set (match_dup 3)
14436 (float:XF (match_operand:SI 2 "register_operand" "")))
14437 (parallel [(set (match_operand:XF 0 " register_operand" "")
14438 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14440 UNSPEC_FSCALE_FRACT))
14442 (unspec:XF [(match_dup 1) (match_dup 3)]
14443 UNSPEC_FSCALE_EXP))])]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14447 if (optimize_insn_for_size_p ())
14450 operands[3] = gen_reg_rtx (XFmode);
14451 operands[4] = gen_reg_rtx (XFmode);
14454 (define_expand "ldexp<mode>3"
14455 [(use (match_operand:MODEF 0 "register_operand" ""))
14456 (use (match_operand:MODEF 1 "general_operand" ""))
14457 (use (match_operand:SI 2 "register_operand" ""))]
14458 "TARGET_USE_FANCY_MATH_387
14459 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14460 || TARGET_MIX_SSE_I387)
14461 && flag_unsafe_math_optimizations"
14465 if (optimize_insn_for_size_p ())
14468 op0 = gen_reg_rtx (XFmode);
14469 op1 = gen_reg_rtx (XFmode);
14471 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14472 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14473 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14477 (define_expand "scalbxf3"
14478 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14479 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14480 (match_operand:XF 2 "register_operand" "")]
14481 UNSPEC_FSCALE_FRACT))
14483 (unspec:XF [(match_dup 1) (match_dup 2)]
14484 UNSPEC_FSCALE_EXP))])]
14485 "TARGET_USE_FANCY_MATH_387
14486 && flag_unsafe_math_optimizations"
14488 if (optimize_insn_for_size_p ())
14491 operands[3] = gen_reg_rtx (XFmode);
14494 (define_expand "scalb<mode>3"
14495 [(use (match_operand:MODEF 0 "register_operand" ""))
14496 (use (match_operand:MODEF 1 "general_operand" ""))
14497 (use (match_operand:MODEF 2 "general_operand" ""))]
14498 "TARGET_USE_FANCY_MATH_387
14499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14500 || TARGET_MIX_SSE_I387)
14501 && flag_unsafe_math_optimizations"
14505 if (optimize_insn_for_size_p ())
14508 op0 = gen_reg_rtx (XFmode);
14509 op1 = gen_reg_rtx (XFmode);
14510 op2 = gen_reg_rtx (XFmode);
14512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14514 emit_insn (gen_scalbxf3 (op0, op1, op2));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14519 (define_expand "significandxf2"
14520 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14521 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14522 UNSPEC_XTRACT_FRACT))
14524 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations"
14527 "operands[2] = gen_reg_rtx (XFmode);")
14529 (define_expand "significand<mode>2"
14530 [(use (match_operand:MODEF 0 "register_operand" ""))
14531 (use (match_operand:MODEF 1 "register_operand" ""))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534 || TARGET_MIX_SSE_I387)
14535 && flag_unsafe_math_optimizations"
14537 rtx op0 = gen_reg_rtx (XFmode);
14538 rtx op1 = gen_reg_rtx (XFmode);
14540 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14546 (define_insn "sse4_1_round<mode>2"
14547 [(set (match_operand:MODEF 0 "register_operand" "=x")
14548 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14549 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14552 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14553 [(set_attr "type" "ssecvt")
14554 (set_attr "prefix_extra" "1")
14555 (set_attr "prefix" "maybe_vex")
14556 (set_attr "mode" "<MODE>")])
14558 (define_insn "rintxf2"
14559 [(set (match_operand:XF 0 "register_operand" "=f")
14560 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14565 [(set_attr "type" "fpspc")
14566 (set_attr "mode" "XF")])
14568 (define_expand "rint<mode>2"
14569 [(use (match_operand:MODEF 0 "register_operand" ""))
14570 (use (match_operand:MODEF 1 "register_operand" ""))]
14571 "(TARGET_USE_FANCY_MATH_387
14572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573 || TARGET_MIX_SSE_I387)
14574 && flag_unsafe_math_optimizations)
14575 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14576 && !flag_trapping_math)"
14578 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14579 && !flag_trapping_math)
14581 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14584 emit_insn (gen_sse4_1_round<mode>2
14585 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14587 ix86_expand_rint (operand0, operand1);
14591 rtx op0 = gen_reg_rtx (XFmode);
14592 rtx op1 = gen_reg_rtx (XFmode);
14594 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14595 emit_insn (gen_rintxf2 (op0, op1));
14597 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14602 (define_expand "round<mode>2"
14603 [(match_operand:MODEF 0 "register_operand" "")
14604 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14605 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14606 && !flag_trapping_math && !flag_rounding_math"
14608 if (optimize_insn_for_size_p ())
14610 if (TARGET_64BIT || (<MODE>mode != DFmode))
14611 ix86_expand_round (operand0, operand1);
14613 ix86_expand_rounddf_32 (operand0, operand1);
14617 (define_insn_and_split "*fistdi2_1"
14618 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14619 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14621 "TARGET_USE_FANCY_MATH_387
14622 && can_create_pseudo_p ()"
14627 if (memory_operand (operands[0], VOIDmode))
14628 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14631 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14632 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14637 [(set_attr "type" "fpspc")
14638 (set_attr "mode" "DI")])
14640 (define_insn "fistdi2"
14641 [(set (match_operand:DI 0 "memory_operand" "=m")
14642 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14644 (clobber (match_scratch:XF 2 "=&1f"))]
14645 "TARGET_USE_FANCY_MATH_387"
14646 "* return output_fix_trunc (insn, operands, 0);"
14647 [(set_attr "type" "fpspc")
14648 (set_attr "mode" "DI")])
14650 (define_insn "fistdi2_with_temp"
14651 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14654 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14655 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14656 "TARGET_USE_FANCY_MATH_387"
14658 [(set_attr "type" "fpspc")
14659 (set_attr "mode" "DI")])
14662 [(set (match_operand:DI 0 "register_operand" "")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14665 (clobber (match_operand:DI 2 "memory_operand" ""))
14666 (clobber (match_scratch 3 ""))]
14668 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14669 (clobber (match_dup 3))])
14670 (set (match_dup 0) (match_dup 2))])
14673 [(set (match_operand:DI 0 "memory_operand" "")
14674 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14676 (clobber (match_operand:DI 2 "memory_operand" ""))
14677 (clobber (match_scratch 3 ""))]
14679 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14680 (clobber (match_dup 3))])])
14682 (define_insn_and_split "*fist<mode>2_1"
14683 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14686 "TARGET_USE_FANCY_MATH_387
14687 && can_create_pseudo_p ()"
14692 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14693 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14697 [(set_attr "type" "fpspc")
14698 (set_attr "mode" "<MODE>")])
14700 (define_insn "fist<mode>2"
14701 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14702 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14704 "TARGET_USE_FANCY_MATH_387"
14705 "* return output_fix_trunc (insn, operands, 0);"
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "<MODE>")])
14709 (define_insn "fist<mode>2_with_temp"
14710 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14713 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14714 "TARGET_USE_FANCY_MATH_387"
14716 [(set_attr "type" "fpspc")
14717 (set_attr "mode" "<MODE>")])
14720 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14721 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14723 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14725 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14726 (set (match_dup 0) (match_dup 2))])
14729 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14730 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14732 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14734 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14736 (define_expand "lrintxf<mode>2"
14737 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14738 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14740 "TARGET_USE_FANCY_MATH_387")
14742 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14743 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14744 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14745 UNSPEC_FIX_NOTRUNC))]
14746 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14747 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14749 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14750 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14751 (match_operand:MODEF 1 "register_operand" "")]
14752 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14753 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14754 && !flag_trapping_math && !flag_rounding_math"
14756 if (optimize_insn_for_size_p ())
14758 ix86_expand_lround (operand0, operand1);
14762 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14763 (define_insn_and_split "frndintxf2_floor"
14764 [(set (match_operand:XF 0 "register_operand" "")
14765 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14766 UNSPEC_FRNDINT_FLOOR))
14767 (clobber (reg:CC FLAGS_REG))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && flag_unsafe_math_optimizations
14770 && can_create_pseudo_p ()"
14775 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14777 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14778 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14780 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14781 operands[2], operands[3]));
14784 [(set_attr "type" "frndint")
14785 (set_attr "i387_cw" "floor")
14786 (set_attr "mode" "XF")])
14788 (define_insn "frndintxf2_floor_i387"
14789 [(set (match_operand:XF 0 "register_operand" "=f")
14790 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14791 UNSPEC_FRNDINT_FLOOR))
14792 (use (match_operand:HI 2 "memory_operand" "m"))
14793 (use (match_operand:HI 3 "memory_operand" "m"))]
14794 "TARGET_USE_FANCY_MATH_387
14795 && flag_unsafe_math_optimizations"
14796 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14797 [(set_attr "type" "frndint")
14798 (set_attr "i387_cw" "floor")
14799 (set_attr "mode" "XF")])
14801 (define_expand "floorxf2"
14802 [(use (match_operand:XF 0 "register_operand" ""))
14803 (use (match_operand:XF 1 "register_operand" ""))]
14804 "TARGET_USE_FANCY_MATH_387
14805 && flag_unsafe_math_optimizations"
14807 if (optimize_insn_for_size_p ())
14809 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14813 (define_expand "floor<mode>2"
14814 [(use (match_operand:MODEF 0 "register_operand" ""))
14815 (use (match_operand:MODEF 1 "register_operand" ""))]
14816 "(TARGET_USE_FANCY_MATH_387
14817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818 || TARGET_MIX_SSE_I387)
14819 && flag_unsafe_math_optimizations)
14820 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14821 && !flag_trapping_math)"
14823 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14824 && !flag_trapping_math
14825 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14827 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14830 emit_insn (gen_sse4_1_round<mode>2
14831 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14832 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14833 ix86_expand_floorceil (operand0, operand1, true);
14835 ix86_expand_floorceildf_32 (operand0, operand1, true);
14841 if (optimize_insn_for_size_p ())
14844 op0 = gen_reg_rtx (XFmode);
14845 op1 = gen_reg_rtx (XFmode);
14846 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14847 emit_insn (gen_frndintxf2_floor (op0, op1));
14849 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14854 (define_insn_and_split "*fist<mode>2_floor_1"
14855 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14856 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14857 UNSPEC_FIST_FLOOR))
14858 (clobber (reg:CC FLAGS_REG))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations
14861 && can_create_pseudo_p ()"
14866 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14868 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14869 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14870 if (memory_operand (operands[0], VOIDmode))
14871 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14872 operands[2], operands[3]));
14875 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14876 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14877 operands[2], operands[3],
14882 [(set_attr "type" "fistp")
14883 (set_attr "i387_cw" "floor")
14884 (set_attr "mode" "<MODE>")])
14886 (define_insn "fistdi2_floor"
14887 [(set (match_operand:DI 0 "memory_operand" "=m")
14888 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14889 UNSPEC_FIST_FLOOR))
14890 (use (match_operand:HI 2 "memory_operand" "m"))
14891 (use (match_operand:HI 3 "memory_operand" "m"))
14892 (clobber (match_scratch:XF 4 "=&1f"))]
14893 "TARGET_USE_FANCY_MATH_387
14894 && flag_unsafe_math_optimizations"
14895 "* return output_fix_trunc (insn, operands, 0);"
14896 [(set_attr "type" "fistp")
14897 (set_attr "i387_cw" "floor")
14898 (set_attr "mode" "DI")])
14900 (define_insn "fistdi2_floor_with_temp"
14901 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14902 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14903 UNSPEC_FIST_FLOOR))
14904 (use (match_operand:HI 2 "memory_operand" "m,m"))
14905 (use (match_operand:HI 3 "memory_operand" "m,m"))
14906 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14907 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14908 "TARGET_USE_FANCY_MATH_387
14909 && flag_unsafe_math_optimizations"
14911 [(set_attr "type" "fistp")
14912 (set_attr "i387_cw" "floor")
14913 (set_attr "mode" "DI")])
14916 [(set (match_operand:DI 0 "register_operand" "")
14917 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14918 UNSPEC_FIST_FLOOR))
14919 (use (match_operand:HI 2 "memory_operand" ""))
14920 (use (match_operand:HI 3 "memory_operand" ""))
14921 (clobber (match_operand:DI 4 "memory_operand" ""))
14922 (clobber (match_scratch 5 ""))]
14924 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14925 (use (match_dup 2))
14926 (use (match_dup 3))
14927 (clobber (match_dup 5))])
14928 (set (match_dup 0) (match_dup 4))])
14931 [(set (match_operand:DI 0 "memory_operand" "")
14932 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14933 UNSPEC_FIST_FLOOR))
14934 (use (match_operand:HI 2 "memory_operand" ""))
14935 (use (match_operand:HI 3 "memory_operand" ""))
14936 (clobber (match_operand:DI 4 "memory_operand" ""))
14937 (clobber (match_scratch 5 ""))]
14939 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14940 (use (match_dup 2))
14941 (use (match_dup 3))
14942 (clobber (match_dup 5))])])
14944 (define_insn "fist<mode>2_floor"
14945 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14946 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14947 UNSPEC_FIST_FLOOR))
14948 (use (match_operand:HI 2 "memory_operand" "m"))
14949 (use (match_operand:HI 3 "memory_operand" "m"))]
14950 "TARGET_USE_FANCY_MATH_387
14951 && flag_unsafe_math_optimizations"
14952 "* return output_fix_trunc (insn, operands, 0);"
14953 [(set_attr "type" "fistp")
14954 (set_attr "i387_cw" "floor")
14955 (set_attr "mode" "<MODE>")])
14957 (define_insn "fist<mode>2_floor_with_temp"
14958 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14959 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14960 UNSPEC_FIST_FLOOR))
14961 (use (match_operand:HI 2 "memory_operand" "m,m"))
14962 (use (match_operand:HI 3 "memory_operand" "m,m"))
14963 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && flag_unsafe_math_optimizations"
14967 [(set_attr "type" "fistp")
14968 (set_attr "i387_cw" "floor")
14969 (set_attr "mode" "<MODE>")])
14972 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14973 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14974 UNSPEC_FIST_FLOOR))
14975 (use (match_operand:HI 2 "memory_operand" ""))
14976 (use (match_operand:HI 3 "memory_operand" ""))
14977 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14979 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14980 UNSPEC_FIST_FLOOR))
14981 (use (match_dup 2))
14982 (use (match_dup 3))])
14983 (set (match_dup 0) (match_dup 4))])
14986 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14987 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" ""))
14990 (use (match_operand:HI 3 "memory_operand" ""))
14991 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14993 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14994 UNSPEC_FIST_FLOOR))
14995 (use (match_dup 2))
14996 (use (match_dup 3))])])
14998 (define_expand "lfloorxf<mode>2"
14999 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15000 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15001 UNSPEC_FIST_FLOOR))
15002 (clobber (reg:CC FLAGS_REG))])]
15003 "TARGET_USE_FANCY_MATH_387
15004 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15005 && flag_unsafe_math_optimizations")
15007 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15008 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15009 (match_operand:MODEF 1 "register_operand" "")]
15010 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15011 && !flag_trapping_math"
15013 if (TARGET_64BIT && optimize_insn_for_size_p ())
15015 ix86_expand_lfloorceil (operand0, operand1, true);
15019 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15020 (define_insn_and_split "frndintxf2_ceil"
15021 [(set (match_operand:XF 0 "register_operand" "")
15022 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15023 UNSPEC_FRNDINT_CEIL))
15024 (clobber (reg:CC FLAGS_REG))]
15025 "TARGET_USE_FANCY_MATH_387
15026 && flag_unsafe_math_optimizations
15027 && can_create_pseudo_p ()"
15032 ix86_optimize_mode_switching[I387_CEIL] = 1;
15034 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15035 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15037 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15038 operands[2], operands[3]));
15041 [(set_attr "type" "frndint")
15042 (set_attr "i387_cw" "ceil")
15043 (set_attr "mode" "XF")])
15045 (define_insn "frndintxf2_ceil_i387"
15046 [(set (match_operand:XF 0 "register_operand" "=f")
15047 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15048 UNSPEC_FRNDINT_CEIL))
15049 (use (match_operand:HI 2 "memory_operand" "m"))
15050 (use (match_operand:HI 3 "memory_operand" "m"))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations"
15053 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15054 [(set_attr "type" "frndint")
15055 (set_attr "i387_cw" "ceil")
15056 (set_attr "mode" "XF")])
15058 (define_expand "ceilxf2"
15059 [(use (match_operand:XF 0 "register_operand" ""))
15060 (use (match_operand:XF 1 "register_operand" ""))]
15061 "TARGET_USE_FANCY_MATH_387
15062 && flag_unsafe_math_optimizations"
15064 if (optimize_insn_for_size_p ())
15066 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15070 (define_expand "ceil<mode>2"
15071 [(use (match_operand:MODEF 0 "register_operand" ""))
15072 (use (match_operand:MODEF 1 "register_operand" ""))]
15073 "(TARGET_USE_FANCY_MATH_387
15074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15075 || TARGET_MIX_SSE_I387)
15076 && flag_unsafe_math_optimizations)
15077 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15078 && !flag_trapping_math)"
15080 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15081 && !flag_trapping_math
15082 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15085 emit_insn (gen_sse4_1_round<mode>2
15086 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15087 else if (optimize_insn_for_size_p ())
15089 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15090 ix86_expand_floorceil (operand0, operand1, false);
15092 ix86_expand_floorceildf_32 (operand0, operand1, false);
15098 if (optimize_insn_for_size_p ())
15101 op0 = gen_reg_rtx (XFmode);
15102 op1 = gen_reg_rtx (XFmode);
15103 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15104 emit_insn (gen_frndintxf2_ceil (op0, op1));
15106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15111 (define_insn_and_split "*fist<mode>2_ceil_1"
15112 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15113 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15115 (clobber (reg:CC FLAGS_REG))]
15116 "TARGET_USE_FANCY_MATH_387
15117 && flag_unsafe_math_optimizations
15118 && can_create_pseudo_p ()"
15123 ix86_optimize_mode_switching[I387_CEIL] = 1;
15125 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15126 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15127 if (memory_operand (operands[0], VOIDmode))
15128 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15129 operands[2], operands[3]));
15132 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15133 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15134 operands[2], operands[3],
15139 [(set_attr "type" "fistp")
15140 (set_attr "i387_cw" "ceil")
15141 (set_attr "mode" "<MODE>")])
15143 (define_insn "fistdi2_ceil"
15144 [(set (match_operand:DI 0 "memory_operand" "=m")
15145 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15147 (use (match_operand:HI 2 "memory_operand" "m"))
15148 (use (match_operand:HI 3 "memory_operand" "m"))
15149 (clobber (match_scratch:XF 4 "=&1f"))]
15150 "TARGET_USE_FANCY_MATH_387
15151 && flag_unsafe_math_optimizations"
15152 "* return output_fix_trunc (insn, operands, 0);"
15153 [(set_attr "type" "fistp")
15154 (set_attr "i387_cw" "ceil")
15155 (set_attr "mode" "DI")])
15157 (define_insn "fistdi2_ceil_with_temp"
15158 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15159 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15161 (use (match_operand:HI 2 "memory_operand" "m,m"))
15162 (use (match_operand:HI 3 "memory_operand" "m,m"))
15163 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15164 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15165 "TARGET_USE_FANCY_MATH_387
15166 && flag_unsafe_math_optimizations"
15168 [(set_attr "type" "fistp")
15169 (set_attr "i387_cw" "ceil")
15170 (set_attr "mode" "DI")])
15173 [(set (match_operand:DI 0 "register_operand" "")
15174 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15176 (use (match_operand:HI 2 "memory_operand" ""))
15177 (use (match_operand:HI 3 "memory_operand" ""))
15178 (clobber (match_operand:DI 4 "memory_operand" ""))
15179 (clobber (match_scratch 5 ""))]
15181 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15182 (use (match_dup 2))
15183 (use (match_dup 3))
15184 (clobber (match_dup 5))])
15185 (set (match_dup 0) (match_dup 4))])
15188 [(set (match_operand:DI 0 "memory_operand" "")
15189 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15191 (use (match_operand:HI 2 "memory_operand" ""))
15192 (use (match_operand:HI 3 "memory_operand" ""))
15193 (clobber (match_operand:DI 4 "memory_operand" ""))
15194 (clobber (match_scratch 5 ""))]
15196 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15197 (use (match_dup 2))
15198 (use (match_dup 3))
15199 (clobber (match_dup 5))])])
15201 (define_insn "fist<mode>2_ceil"
15202 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15203 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15205 (use (match_operand:HI 2 "memory_operand" "m"))
15206 (use (match_operand:HI 3 "memory_operand" "m"))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && flag_unsafe_math_optimizations"
15209 "* return output_fix_trunc (insn, operands, 0);"
15210 [(set_attr "type" "fistp")
15211 (set_attr "i387_cw" "ceil")
15212 (set_attr "mode" "<MODE>")])
15214 (define_insn "fist<mode>2_ceil_with_temp"
15215 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15216 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15218 (use (match_operand:HI 2 "memory_operand" "m,m"))
15219 (use (match_operand:HI 3 "memory_operand" "m,m"))
15220 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && flag_unsafe_math_optimizations"
15224 [(set_attr "type" "fistp")
15225 (set_attr "i387_cw" "ceil")
15226 (set_attr "mode" "<MODE>")])
15229 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15230 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15232 (use (match_operand:HI 2 "memory_operand" ""))
15233 (use (match_operand:HI 3 "memory_operand" ""))
15234 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15236 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15238 (use (match_dup 2))
15239 (use (match_dup 3))])
15240 (set (match_dup 0) (match_dup 4))])
15243 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15244 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15246 (use (match_operand:HI 2 "memory_operand" ""))
15247 (use (match_operand:HI 3 "memory_operand" ""))
15248 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15250 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15252 (use (match_dup 2))
15253 (use (match_dup 3))])])
15255 (define_expand "lceilxf<mode>2"
15256 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15257 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15259 (clobber (reg:CC FLAGS_REG))])]
15260 "TARGET_USE_FANCY_MATH_387
15261 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15262 && flag_unsafe_math_optimizations")
15264 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15265 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15266 (match_operand:MODEF 1 "register_operand" "")]
15267 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15268 && !flag_trapping_math"
15270 ix86_expand_lfloorceil (operand0, operand1, false);
15274 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15275 (define_insn_and_split "frndintxf2_trunc"
15276 [(set (match_operand:XF 0 "register_operand" "")
15277 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15278 UNSPEC_FRNDINT_TRUNC))
15279 (clobber (reg:CC FLAGS_REG))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && flag_unsafe_math_optimizations
15282 && can_create_pseudo_p ()"
15287 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15289 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15290 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15292 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15293 operands[2], operands[3]));
15296 [(set_attr "type" "frndint")
15297 (set_attr "i387_cw" "trunc")
15298 (set_attr "mode" "XF")])
15300 (define_insn "frndintxf2_trunc_i387"
15301 [(set (match_operand:XF 0 "register_operand" "=f")
15302 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15303 UNSPEC_FRNDINT_TRUNC))
15304 (use (match_operand:HI 2 "memory_operand" "m"))
15305 (use (match_operand:HI 3 "memory_operand" "m"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15308 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15309 [(set_attr "type" "frndint")
15310 (set_attr "i387_cw" "trunc")
15311 (set_attr "mode" "XF")])
15313 (define_expand "btruncxf2"
15314 [(use (match_operand:XF 0 "register_operand" ""))
15315 (use (match_operand:XF 1 "register_operand" ""))]
15316 "TARGET_USE_FANCY_MATH_387
15317 && flag_unsafe_math_optimizations"
15319 if (optimize_insn_for_size_p ())
15321 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15325 (define_expand "btrunc<mode>2"
15326 [(use (match_operand:MODEF 0 "register_operand" ""))
15327 (use (match_operand:MODEF 1 "register_operand" ""))]
15328 "(TARGET_USE_FANCY_MATH_387
15329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15330 || TARGET_MIX_SSE_I387)
15331 && flag_unsafe_math_optimizations)
15332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15333 && !flag_trapping_math)"
15335 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15336 && !flag_trapping_math
15337 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15340 emit_insn (gen_sse4_1_round<mode>2
15341 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15342 else if (optimize_insn_for_size_p ())
15344 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15345 ix86_expand_trunc (operand0, operand1);
15347 ix86_expand_truncdf_32 (operand0, operand1);
15353 if (optimize_insn_for_size_p ())
15356 op0 = gen_reg_rtx (XFmode);
15357 op1 = gen_reg_rtx (XFmode);
15358 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15359 emit_insn (gen_frndintxf2_trunc (op0, op1));
15361 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15366 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15367 (define_insn_and_split "frndintxf2_mask_pm"
15368 [(set (match_operand:XF 0 "register_operand" "")
15369 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15370 UNSPEC_FRNDINT_MASK_PM))
15371 (clobber (reg:CC FLAGS_REG))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && flag_unsafe_math_optimizations
15374 && can_create_pseudo_p ()"
15379 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15381 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15382 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15384 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15385 operands[2], operands[3]));
15388 [(set_attr "type" "frndint")
15389 (set_attr "i387_cw" "mask_pm")
15390 (set_attr "mode" "XF")])
15392 (define_insn "frndintxf2_mask_pm_i387"
15393 [(set (match_operand:XF 0 "register_operand" "=f")
15394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15395 UNSPEC_FRNDINT_MASK_PM))
15396 (use (match_operand:HI 2 "memory_operand" "m"))
15397 (use (match_operand:HI 3 "memory_operand" "m"))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations"
15400 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15401 [(set_attr "type" "frndint")
15402 (set_attr "i387_cw" "mask_pm")
15403 (set_attr "mode" "XF")])
15405 (define_expand "nearbyintxf2"
15406 [(use (match_operand:XF 0 "register_operand" ""))
15407 (use (match_operand:XF 1 "register_operand" ""))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && flag_unsafe_math_optimizations"
15411 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15415 (define_expand "nearbyint<mode>2"
15416 [(use (match_operand:MODEF 0 "register_operand" ""))
15417 (use (match_operand:MODEF 1 "register_operand" ""))]
15418 "TARGET_USE_FANCY_MATH_387
15419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15420 || TARGET_MIX_SSE_I387)
15421 && flag_unsafe_math_optimizations"
15423 rtx op0 = gen_reg_rtx (XFmode);
15424 rtx op1 = gen_reg_rtx (XFmode);
15426 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15427 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15429 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15433 (define_insn "fxam<mode>2_i387"
15434 [(set (match_operand:HI 0 "register_operand" "=a")
15436 [(match_operand:X87MODEF 1 "register_operand" "f")]
15438 "TARGET_USE_FANCY_MATH_387"
15439 "fxam\n\tfnstsw\t%0"
15440 [(set_attr "type" "multi")
15441 (set_attr "length" "4")
15442 (set_attr "unit" "i387")
15443 (set_attr "mode" "<MODE>")])
15445 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15446 [(set (match_operand:HI 0 "register_operand" "")
15448 [(match_operand:MODEF 1 "memory_operand" "")]
15450 "TARGET_USE_FANCY_MATH_387
15451 && can_create_pseudo_p ()"
15454 [(set (match_dup 2)(match_dup 1))
15456 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15458 operands[2] = gen_reg_rtx (<MODE>mode);
15460 MEM_VOLATILE_P (operands[1]) = 1;
15462 [(set_attr "type" "multi")
15463 (set_attr "unit" "i387")
15464 (set_attr "mode" "<MODE>")])
15466 (define_expand "isinfxf2"
15467 [(use (match_operand:SI 0 "register_operand" ""))
15468 (use (match_operand:XF 1 "register_operand" ""))]
15469 "TARGET_USE_FANCY_MATH_387
15470 && TARGET_C99_FUNCTIONS"
15472 rtx mask = GEN_INT (0x45);
15473 rtx val = GEN_INT (0x05);
15477 rtx scratch = gen_reg_rtx (HImode);
15478 rtx res = gen_reg_rtx (QImode);
15480 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15482 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15483 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15484 cond = gen_rtx_fmt_ee (EQ, QImode,
15485 gen_rtx_REG (CCmode, FLAGS_REG),
15487 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15488 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15492 (define_expand "isinf<mode>2"
15493 [(use (match_operand:SI 0 "register_operand" ""))
15494 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && TARGET_C99_FUNCTIONS
15497 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15499 rtx mask = GEN_INT (0x45);
15500 rtx val = GEN_INT (0x05);
15504 rtx scratch = gen_reg_rtx (HImode);
15505 rtx res = gen_reg_rtx (QImode);
15507 /* Remove excess precision by forcing value through memory. */
15508 if (memory_operand (operands[1], VOIDmode))
15509 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15512 enum ix86_stack_slot slot = (virtuals_instantiated
15515 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15517 emit_move_insn (temp, operands[1]);
15518 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15521 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15522 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15523 cond = gen_rtx_fmt_ee (EQ, QImode,
15524 gen_rtx_REG (CCmode, FLAGS_REG),
15526 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15527 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15531 (define_expand "signbitxf2"
15532 [(use (match_operand:SI 0 "register_operand" ""))
15533 (use (match_operand:XF 1 "register_operand" ""))]
15534 "TARGET_USE_FANCY_MATH_387"
15536 rtx scratch = gen_reg_rtx (HImode);
15538 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15539 emit_insn (gen_andsi3 (operands[0],
15540 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15544 (define_insn "movmsk_df"
15545 [(set (match_operand:SI 0 "register_operand" "=r")
15547 [(match_operand:DF 1 "register_operand" "x")]
15549 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15550 "%vmovmskpd\t{%1, %0|%0, %1}"
15551 [(set_attr "type" "ssemov")
15552 (set_attr "prefix" "maybe_vex")
15553 (set_attr "mode" "DF")])
15555 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15556 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15557 (define_expand "signbitdf2"
15558 [(use (match_operand:SI 0 "register_operand" ""))
15559 (use (match_operand:DF 1 "register_operand" ""))]
15560 "TARGET_USE_FANCY_MATH_387
15561 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15563 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15565 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15566 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15570 rtx scratch = gen_reg_rtx (HImode);
15572 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15573 emit_insn (gen_andsi3 (operands[0],
15574 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15579 (define_expand "signbitsf2"
15580 [(use (match_operand:SI 0 "register_operand" ""))
15581 (use (match_operand:SF 1 "register_operand" ""))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15585 rtx scratch = gen_reg_rtx (HImode);
15587 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15588 emit_insn (gen_andsi3 (operands[0],
15589 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15593 ;; Block operation instructions
15596 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15599 [(set_attr "length" "1")
15600 (set_attr "length_immediate" "0")
15601 (set_attr "modrm" "0")])
15603 (define_expand "movmem<mode>"
15604 [(use (match_operand:BLK 0 "memory_operand" ""))
15605 (use (match_operand:BLK 1 "memory_operand" ""))
15606 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15607 (use (match_operand:SWI48 3 "const_int_operand" ""))
15608 (use (match_operand:SI 4 "const_int_operand" ""))
15609 (use (match_operand:SI 5 "const_int_operand" ""))]
15612 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15613 operands[4], operands[5]))
15619 ;; Most CPUs don't like single string operations
15620 ;; Handle this case here to simplify previous expander.
15622 (define_expand "strmov"
15623 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15624 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15625 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15626 (clobber (reg:CC FLAGS_REG))])
15627 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15628 (clobber (reg:CC FLAGS_REG))])]
15631 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15633 /* If .md ever supports :P for Pmode, these can be directly
15634 in the pattern above. */
15635 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15636 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15638 /* Can't use this if the user has appropriated esi or edi. */
15639 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15640 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15642 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15643 operands[2], operands[3],
15644 operands[5], operands[6]));
15648 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15651 (define_expand "strmov_singleop"
15652 [(parallel [(set (match_operand 1 "memory_operand" "")
15653 (match_operand 3 "memory_operand" ""))
15654 (set (match_operand 0 "register_operand" "")
15655 (match_operand 4 "" ""))
15656 (set (match_operand 2 "register_operand" "")
15657 (match_operand 5 "" ""))])]
15659 "ix86_current_function_needs_cld = 1;")
15661 (define_insn "*strmovdi_rex_1"
15662 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15663 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15664 (set (match_operand:DI 0 "register_operand" "=D")
15665 (plus:DI (match_dup 2)
15667 (set (match_operand:DI 1 "register_operand" "=S")
15668 (plus:DI (match_dup 3)
15672 [(set_attr "type" "str")
15673 (set_attr "memory" "both")
15674 (set_attr "mode" "DI")])
15676 (define_insn "*strmovsi_1"
15677 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15678 (mem:SI (match_operand:P 3 "register_operand" "1")))
15679 (set (match_operand:P 0 "register_operand" "=D")
15680 (plus:P (match_dup 2)
15682 (set (match_operand:P 1 "register_operand" "=S")
15683 (plus:P (match_dup 3)
15687 [(set_attr "type" "str")
15688 (set_attr "memory" "both")
15689 (set_attr "mode" "SI")])
15691 (define_insn "*strmovhi_1"
15692 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15693 (mem:HI (match_operand:P 3 "register_operand" "1")))
15694 (set (match_operand:P 0 "register_operand" "=D")
15695 (plus:P (match_dup 2)
15697 (set (match_operand:P 1 "register_operand" "=S")
15698 (plus:P (match_dup 3)
15702 [(set_attr "type" "str")
15703 (set_attr "memory" "both")
15704 (set_attr "mode" "HI")])
15706 (define_insn "*strmovqi_1"
15707 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15708 (mem:QI (match_operand:P 3 "register_operand" "1")))
15709 (set (match_operand:P 0 "register_operand" "=D")
15710 (plus:P (match_dup 2)
15712 (set (match_operand:P 1 "register_operand" "=S")
15713 (plus:P (match_dup 3)
15717 [(set_attr "type" "str")
15718 (set_attr "memory" "both")
15719 (set (attr "prefix_rex")
15721 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15723 (const_string "*")))
15724 (set_attr "mode" "QI")])
15726 (define_expand "rep_mov"
15727 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15728 (set (match_operand 0 "register_operand" "")
15729 (match_operand 5 "" ""))
15730 (set (match_operand 2 "register_operand" "")
15731 (match_operand 6 "" ""))
15732 (set (match_operand 1 "memory_operand" "")
15733 (match_operand 3 "memory_operand" ""))
15734 (use (match_dup 4))])]
15736 "ix86_current_function_needs_cld = 1;")
15738 (define_insn "*rep_movdi_rex64"
15739 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15740 (set (match_operand:DI 0 "register_operand" "=D")
15741 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15743 (match_operand:DI 3 "register_operand" "0")))
15744 (set (match_operand:DI 1 "register_operand" "=S")
15745 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15746 (match_operand:DI 4 "register_operand" "1")))
15747 (set (mem:BLK (match_dup 3))
15748 (mem:BLK (match_dup 4)))
15749 (use (match_dup 5))]
15752 [(set_attr "type" "str")
15753 (set_attr "prefix_rep" "1")
15754 (set_attr "memory" "both")
15755 (set_attr "mode" "DI")])
15757 (define_insn "*rep_movsi"
15758 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15759 (set (match_operand:P 0 "register_operand" "=D")
15760 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15762 (match_operand:P 3 "register_operand" "0")))
15763 (set (match_operand:P 1 "register_operand" "=S")
15764 (plus:P (ashift:P (match_dup 5) (const_int 2))
15765 (match_operand:P 4 "register_operand" "1")))
15766 (set (mem:BLK (match_dup 3))
15767 (mem:BLK (match_dup 4)))
15768 (use (match_dup 5))]
15770 "rep{%;} movs{l|d}"
15771 [(set_attr "type" "str")
15772 (set_attr "prefix_rep" "1")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "SI")])
15776 (define_insn "*rep_movqi"
15777 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15778 (set (match_operand:P 0 "register_operand" "=D")
15779 (plus:P (match_operand:P 3 "register_operand" "0")
15780 (match_operand:P 5 "register_operand" "2")))
15781 (set (match_operand:P 1 "register_operand" "=S")
15782 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15783 (set (mem:BLK (match_dup 3))
15784 (mem:BLK (match_dup 4)))
15785 (use (match_dup 5))]
15788 [(set_attr "type" "str")
15789 (set_attr "prefix_rep" "1")
15790 (set_attr "memory" "both")
15791 (set_attr "mode" "QI")])
15793 (define_expand "setmem<mode>"
15794 [(use (match_operand:BLK 0 "memory_operand" ""))
15795 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15796 (use (match_operand 2 "const_int_operand" ""))
15797 (use (match_operand 3 "const_int_operand" ""))
15798 (use (match_operand:SI 4 "const_int_operand" ""))
15799 (use (match_operand:SI 5 "const_int_operand" ""))]
15802 if (ix86_expand_setmem (operands[0], operands[1],
15803 operands[2], operands[3],
15804 operands[4], operands[5]))
15810 ;; Most CPUs don't like single string operations
15811 ;; Handle this case here to simplify previous expander.
15813 (define_expand "strset"
15814 [(set (match_operand 1 "memory_operand" "")
15815 (match_operand 2 "register_operand" ""))
15816 (parallel [(set (match_operand 0 "register_operand" "")
15818 (clobber (reg:CC FLAGS_REG))])]
15821 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15822 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15824 /* If .md ever supports :P for Pmode, this can be directly
15825 in the pattern above. */
15826 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15827 GEN_INT (GET_MODE_SIZE (GET_MODE
15829 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15831 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15837 (define_expand "strset_singleop"
15838 [(parallel [(set (match_operand 1 "memory_operand" "")
15839 (match_operand 2 "register_operand" ""))
15840 (set (match_operand 0 "register_operand" "")
15841 (match_operand 3 "" ""))])]
15843 "ix86_current_function_needs_cld = 1;")
15845 (define_insn "*strsetdi_rex_1"
15846 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15847 (match_operand:DI 2 "register_operand" "a"))
15848 (set (match_operand:DI 0 "register_operand" "=D")
15849 (plus:DI (match_dup 1)
15853 [(set_attr "type" "str")
15854 (set_attr "memory" "store")
15855 (set_attr "mode" "DI")])
15857 (define_insn "*strsetsi_1"
15858 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15859 (match_operand:SI 2 "register_operand" "a"))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (match_dup 1)
15865 [(set_attr "type" "str")
15866 (set_attr "memory" "store")
15867 (set_attr "mode" "SI")])
15869 (define_insn "*strsethi_1"
15870 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15871 (match_operand:HI 2 "register_operand" "a"))
15872 (set (match_operand:P 0 "register_operand" "=D")
15873 (plus:P (match_dup 1)
15877 [(set_attr "type" "str")
15878 (set_attr "memory" "store")
15879 (set_attr "mode" "HI")])
15881 (define_insn "*strsetqi_1"
15882 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15883 (match_operand:QI 2 "register_operand" "a"))
15884 (set (match_operand:P 0 "register_operand" "=D")
15885 (plus:P (match_dup 1)
15889 [(set_attr "type" "str")
15890 (set_attr "memory" "store")
15891 (set (attr "prefix_rex")
15893 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15895 (const_string "*")))
15896 (set_attr "mode" "QI")])
15898 (define_expand "rep_stos"
15899 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15900 (set (match_operand 0 "register_operand" "")
15901 (match_operand 4 "" ""))
15902 (set (match_operand 2 "memory_operand" "") (const_int 0))
15903 (use (match_operand 3 "register_operand" ""))
15904 (use (match_dup 1))])]
15906 "ix86_current_function_needs_cld = 1;")
15908 (define_insn "*rep_stosdi_rex64"
15909 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15910 (set (match_operand:DI 0 "register_operand" "=D")
15911 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15913 (match_operand:DI 3 "register_operand" "0")))
15914 (set (mem:BLK (match_dup 3))
15916 (use (match_operand:DI 2 "register_operand" "a"))
15917 (use (match_dup 4))]
15920 [(set_attr "type" "str")
15921 (set_attr "prefix_rep" "1")
15922 (set_attr "memory" "store")
15923 (set_attr "mode" "DI")])
15925 (define_insn "*rep_stossi"
15926 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15927 (set (match_operand:P 0 "register_operand" "=D")
15928 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15930 (match_operand:P 3 "register_operand" "0")))
15931 (set (mem:BLK (match_dup 3))
15933 (use (match_operand:SI 2 "register_operand" "a"))
15934 (use (match_dup 4))]
15936 "rep{%;} stos{l|d}"
15937 [(set_attr "type" "str")
15938 (set_attr "prefix_rep" "1")
15939 (set_attr "memory" "store")
15940 (set_attr "mode" "SI")])
15942 (define_insn "*rep_stosqi"
15943 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15944 (set (match_operand:P 0 "register_operand" "=D")
15945 (plus:P (match_operand:P 3 "register_operand" "0")
15946 (match_operand:P 4 "register_operand" "1")))
15947 (set (mem:BLK (match_dup 3))
15949 (use (match_operand:QI 2 "register_operand" "a"))
15950 (use (match_dup 4))]
15953 [(set_attr "type" "str")
15954 (set_attr "prefix_rep" "1")
15955 (set_attr "memory" "store")
15956 (set (attr "prefix_rex")
15958 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15960 (const_string "*")))
15961 (set_attr "mode" "QI")])
15963 (define_expand "cmpstrnsi"
15964 [(set (match_operand:SI 0 "register_operand" "")
15965 (compare:SI (match_operand:BLK 1 "general_operand" "")
15966 (match_operand:BLK 2 "general_operand" "")))
15967 (use (match_operand 3 "general_operand" ""))
15968 (use (match_operand 4 "immediate_operand" ""))]
15971 rtx addr1, addr2, out, outlow, count, countreg, align;
15973 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15976 /* Can't use this if the user has appropriated esi or edi. */
15977 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15982 out = gen_reg_rtx (SImode);
15984 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15985 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15986 if (addr1 != XEXP (operands[1], 0))
15987 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15988 if (addr2 != XEXP (operands[2], 0))
15989 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15991 count = operands[3];
15992 countreg = ix86_zero_extend_to_Pmode (count);
15994 /* %%% Iff we are testing strict equality, we can use known alignment
15995 to good advantage. This may be possible with combine, particularly
15996 once cc0 is dead. */
15997 align = operands[4];
15999 if (CONST_INT_P (count))
16001 if (INTVAL (count) == 0)
16003 emit_move_insn (operands[0], const0_rtx);
16006 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16007 operands[1], operands[2]));
16011 rtx (*gen_cmp) (rtx, rtx);
16013 gen_cmp = (TARGET_64BIT
16014 ? gen_cmpdi_1 : gen_cmpsi_1);
16016 emit_insn (gen_cmp (countreg, countreg));
16017 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16018 operands[1], operands[2]));
16021 outlow = gen_lowpart (QImode, out);
16022 emit_insn (gen_cmpintqi (outlow));
16023 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16025 if (operands[0] != out)
16026 emit_move_insn (operands[0], out);
16031 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16033 (define_expand "cmpintqi"
16034 [(set (match_dup 1)
16035 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16037 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16038 (parallel [(set (match_operand:QI 0 "register_operand" "")
16039 (minus:QI (match_dup 1)
16041 (clobber (reg:CC FLAGS_REG))])]
16044 operands[1] = gen_reg_rtx (QImode);
16045 operands[2] = gen_reg_rtx (QImode);
16048 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16049 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16051 (define_expand "cmpstrnqi_nz_1"
16052 [(parallel [(set (reg:CC FLAGS_REG)
16053 (compare:CC (match_operand 4 "memory_operand" "")
16054 (match_operand 5 "memory_operand" "")))
16055 (use (match_operand 2 "register_operand" ""))
16056 (use (match_operand:SI 3 "immediate_operand" ""))
16057 (clobber (match_operand 0 "register_operand" ""))
16058 (clobber (match_operand 1 "register_operand" ""))
16059 (clobber (match_dup 2))])]
16061 "ix86_current_function_needs_cld = 1;")
16063 (define_insn "*cmpstrnqi_nz_1"
16064 [(set (reg:CC FLAGS_REG)
16065 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16066 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16067 (use (match_operand:P 6 "register_operand" "2"))
16068 (use (match_operand:SI 3 "immediate_operand" "i"))
16069 (clobber (match_operand:P 0 "register_operand" "=S"))
16070 (clobber (match_operand:P 1 "register_operand" "=D"))
16071 (clobber (match_operand:P 2 "register_operand" "=c"))]
16074 [(set_attr "type" "str")
16075 (set_attr "mode" "QI")
16076 (set (attr "prefix_rex")
16078 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16080 (const_string "*")))
16081 (set_attr "prefix_rep" "1")])
16083 ;; The same, but the count is not known to not be zero.
16085 (define_expand "cmpstrnqi_1"
16086 [(parallel [(set (reg:CC FLAGS_REG)
16087 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16089 (compare:CC (match_operand 4 "memory_operand" "")
16090 (match_operand 5 "memory_operand" ""))
16092 (use (match_operand:SI 3 "immediate_operand" ""))
16093 (use (reg:CC FLAGS_REG))
16094 (clobber (match_operand 0 "register_operand" ""))
16095 (clobber (match_operand 1 "register_operand" ""))
16096 (clobber (match_dup 2))])]
16098 "ix86_current_function_needs_cld = 1;")
16100 (define_insn "*cmpstrnqi_1"
16101 [(set (reg:CC FLAGS_REG)
16102 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16104 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16105 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16107 (use (match_operand:SI 3 "immediate_operand" "i"))
16108 (use (reg:CC FLAGS_REG))
16109 (clobber (match_operand:P 0 "register_operand" "=S"))
16110 (clobber (match_operand:P 1 "register_operand" "=D"))
16111 (clobber (match_operand:P 2 "register_operand" "=c"))]
16114 [(set_attr "type" "str")
16115 (set_attr "mode" "QI")
16116 (set (attr "prefix_rex")
16118 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16120 (const_string "*")))
16121 (set_attr "prefix_rep" "1")])
16123 (define_expand "strlen<mode>"
16124 [(set (match_operand:SWI48x 0 "register_operand" "")
16125 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16126 (match_operand:QI 2 "immediate_operand" "")
16127 (match_operand 3 "immediate_operand" "")]
16131 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16137 (define_expand "strlenqi_1"
16138 [(parallel [(set (match_operand 0 "register_operand" "")
16139 (match_operand 2 "" ""))
16140 (clobber (match_operand 1 "register_operand" ""))
16141 (clobber (reg:CC FLAGS_REG))])]
16143 "ix86_current_function_needs_cld = 1;")
16145 (define_insn "*strlenqi_1"
16146 [(set (match_operand:P 0 "register_operand" "=&c")
16147 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16148 (match_operand:QI 2 "register_operand" "a")
16149 (match_operand:P 3 "immediate_operand" "i")
16150 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16151 (clobber (match_operand:P 1 "register_operand" "=D"))
16152 (clobber (reg:CC FLAGS_REG))]
16155 [(set_attr "type" "str")
16156 (set_attr "mode" "QI")
16157 (set (attr "prefix_rex")
16159 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16161 (const_string "*")))
16162 (set_attr "prefix_rep" "1")])
16164 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16165 ;; handled in combine, but it is not currently up to the task.
16166 ;; When used for their truth value, the cmpstrn* expanders generate
16175 ;; The intermediate three instructions are unnecessary.
16177 ;; This one handles cmpstrn*_nz_1...
16180 (set (reg:CC FLAGS_REG)
16181 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16182 (mem:BLK (match_operand 5 "register_operand" ""))))
16183 (use (match_operand 6 "register_operand" ""))
16184 (use (match_operand:SI 3 "immediate_operand" ""))
16185 (clobber (match_operand 0 "register_operand" ""))
16186 (clobber (match_operand 1 "register_operand" ""))
16187 (clobber (match_operand 2 "register_operand" ""))])
16188 (set (match_operand:QI 7 "register_operand" "")
16189 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16190 (set (match_operand:QI 8 "register_operand" "")
16191 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16192 (set (reg FLAGS_REG)
16193 (compare (match_dup 7) (match_dup 8)))
16195 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16197 (set (reg:CC FLAGS_REG)
16198 (compare:CC (mem:BLK (match_dup 4))
16199 (mem:BLK (match_dup 5))))
16200 (use (match_dup 6))
16201 (use (match_dup 3))
16202 (clobber (match_dup 0))
16203 (clobber (match_dup 1))
16204 (clobber (match_dup 2))])])
16206 ;; ...and this one handles cmpstrn*_1.
16209 (set (reg:CC FLAGS_REG)
16210 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16212 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16213 (mem:BLK (match_operand 5 "register_operand" "")))
16215 (use (match_operand:SI 3 "immediate_operand" ""))
16216 (use (reg:CC FLAGS_REG))
16217 (clobber (match_operand 0 "register_operand" ""))
16218 (clobber (match_operand 1 "register_operand" ""))
16219 (clobber (match_operand 2 "register_operand" ""))])
16220 (set (match_operand:QI 7 "register_operand" "")
16221 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16222 (set (match_operand:QI 8 "register_operand" "")
16223 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16224 (set (reg FLAGS_REG)
16225 (compare (match_dup 7) (match_dup 8)))
16227 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16229 (set (reg:CC FLAGS_REG)
16230 (if_then_else:CC (ne (match_dup 6)
16232 (compare:CC (mem:BLK (match_dup 4))
16233 (mem:BLK (match_dup 5)))
16235 (use (match_dup 3))
16236 (use (reg:CC FLAGS_REG))
16237 (clobber (match_dup 0))
16238 (clobber (match_dup 1))
16239 (clobber (match_dup 2))])])
16241 ;; Conditional move instructions.
16243 (define_expand "mov<mode>cc"
16244 [(set (match_operand:SWIM 0 "register_operand" "")
16245 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16246 (match_operand:SWIM 2 "general_operand" "")
16247 (match_operand:SWIM 3 "general_operand" "")))]
16249 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16251 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16252 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16253 ;; So just document what we're doing explicitly.
16255 (define_expand "x86_mov<mode>cc_0_m1"
16257 [(set (match_operand:SWI48 0 "register_operand" "")
16258 (if_then_else:SWI48
16259 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16260 [(match_operand 1 "flags_reg_operand" "")
16264 (clobber (reg:CC FLAGS_REG))])])
16266 (define_insn "*x86_mov<mode>cc_0_m1"
16267 [(set (match_operand:SWI48 0 "register_operand" "=r")
16268 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16269 [(reg FLAGS_REG) (const_int 0)])
16272 (clobber (reg:CC FLAGS_REG))]
16274 "sbb{<imodesuffix>}\t%0, %0"
16275 ; Since we don't have the proper number of operands for an alu insn,
16276 ; fill in all the blanks.
16277 [(set_attr "type" "alu")
16278 (set_attr "use_carry" "1")
16279 (set_attr "pent_pair" "pu")
16280 (set_attr "memory" "none")
16281 (set_attr "imm_disp" "false")
16282 (set_attr "mode" "<MODE>")
16283 (set_attr "length_immediate" "0")])
16285 (define_insn "*x86_mov<mode>cc_0_m1_se"
16286 [(set (match_operand:SWI48 0 "register_operand" "=r")
16287 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16288 [(reg FLAGS_REG) (const_int 0)])
16291 (clobber (reg:CC FLAGS_REG))]
16293 "sbb{<imodesuffix>}\t%0, %0"
16294 [(set_attr "type" "alu")
16295 (set_attr "use_carry" "1")
16296 (set_attr "pent_pair" "pu")
16297 (set_attr "memory" "none")
16298 (set_attr "imm_disp" "false")
16299 (set_attr "mode" "<MODE>")
16300 (set_attr "length_immediate" "0")])
16302 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16303 [(set (match_operand:SWI48 0 "register_operand" "=r")
16304 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16305 [(reg FLAGS_REG) (const_int 0)])))]
16307 "sbb{<imodesuffix>}\t%0, %0"
16308 [(set_attr "type" "alu")
16309 (set_attr "use_carry" "1")
16310 (set_attr "pent_pair" "pu")
16311 (set_attr "memory" "none")
16312 (set_attr "imm_disp" "false")
16313 (set_attr "mode" "<MODE>")
16314 (set_attr "length_immediate" "0")])
16316 (define_insn "*mov<mode>cc_noc"
16317 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16318 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16319 [(reg FLAGS_REG) (const_int 0)])
16320 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16321 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16322 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16324 cmov%O2%C1\t{%2, %0|%0, %2}
16325 cmov%O2%c1\t{%3, %0|%0, %3}"
16326 [(set_attr "type" "icmov")
16327 (set_attr "mode" "<MODE>")])
16329 (define_insn_and_split "*movqicc_noc"
16330 [(set (match_operand:QI 0 "register_operand" "=r,r")
16331 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16332 [(match_operand 4 "flags_reg_operand" "")
16334 (match_operand:QI 2 "register_operand" "r,0")
16335 (match_operand:QI 3 "register_operand" "0,r")))]
16336 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16338 "&& reload_completed"
16339 [(set (match_dup 0)
16340 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16343 "operands[0] = gen_lowpart (SImode, operands[0]);
16344 operands[2] = gen_lowpart (SImode, operands[2]);
16345 operands[3] = gen_lowpart (SImode, operands[3]);"
16346 [(set_attr "type" "icmov")
16347 (set_attr "mode" "SI")])
16349 (define_expand "mov<mode>cc"
16350 [(set (match_operand:X87MODEF 0 "register_operand" "")
16351 (if_then_else:X87MODEF
16352 (match_operand 1 "ix86_fp_comparison_operator" "")
16353 (match_operand:X87MODEF 2 "register_operand" "")
16354 (match_operand:X87MODEF 3 "register_operand" "")))]
16355 "(TARGET_80387 && TARGET_CMOVE)
16356 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16357 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16359 (define_insn "*movxfcc_1"
16360 [(set (match_operand:XF 0 "register_operand" "=f,f")
16361 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16363 (match_operand:XF 2 "register_operand" "f,0")
16364 (match_operand:XF 3 "register_operand" "0,f")))]
16365 "TARGET_80387 && TARGET_CMOVE"
16367 fcmov%F1\t{%2, %0|%0, %2}
16368 fcmov%f1\t{%3, %0|%0, %3}"
16369 [(set_attr "type" "fcmov")
16370 (set_attr "mode" "XF")])
16372 (define_insn "*movdfcc_1_rex64"
16373 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16374 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16375 [(reg FLAGS_REG) (const_int 0)])
16376 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16377 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16378 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16379 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16381 fcmov%F1\t{%2, %0|%0, %2}
16382 fcmov%f1\t{%3, %0|%0, %3}
16383 cmov%O2%C1\t{%2, %0|%0, %2}
16384 cmov%O2%c1\t{%3, %0|%0, %3}"
16385 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16386 (set_attr "mode" "DF,DF,DI,DI")])
16388 (define_insn "*movdfcc_1"
16389 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16390 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16392 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16393 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16394 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16395 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16397 fcmov%F1\t{%2, %0|%0, %2}
16398 fcmov%f1\t{%3, %0|%0, %3}
16401 [(set_attr "type" "fcmov,fcmov,multi,multi")
16402 (set_attr "mode" "DF,DF,DI,DI")])
16405 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16406 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16407 [(match_operand 4 "flags_reg_operand" "")
16409 (match_operand:DF 2 "nonimmediate_operand" "")
16410 (match_operand:DF 3 "nonimmediate_operand" "")))]
16411 "!TARGET_64BIT && reload_completed"
16412 [(set (match_dup 2)
16413 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16417 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16421 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16422 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16425 (define_insn "*movsfcc_1_387"
16426 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16427 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16428 [(reg FLAGS_REG) (const_int 0)])
16429 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16430 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16431 "TARGET_80387 && TARGET_CMOVE
16432 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16434 fcmov%F1\t{%2, %0|%0, %2}
16435 fcmov%f1\t{%3, %0|%0, %3}
16436 cmov%O2%C1\t{%2, %0|%0, %2}
16437 cmov%O2%c1\t{%3, %0|%0, %3}"
16438 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16439 (set_attr "mode" "SF,SF,SI,SI")])
16441 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16442 ;; the scalar versions to have only XMM registers as operands.
16444 ;; XOP conditional move
16445 (define_insn "*xop_pcmov_<mode>"
16446 [(set (match_operand:MODEF 0 "register_operand" "=x")
16447 (if_then_else:MODEF
16448 (match_operand:MODEF 1 "register_operand" "x")
16449 (match_operand:MODEF 2 "register_operand" "x")
16450 (match_operand:MODEF 3 "register_operand" "x")))]
16452 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16453 [(set_attr "type" "sse4arg")])
16455 ;; These versions of the min/max patterns are intentionally ignorant of
16456 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16457 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16458 ;; are undefined in this condition, we're certain this is correct.
16460 (define_insn "*avx_<code><mode>3"
16461 [(set (match_operand:MODEF 0 "register_operand" "=x")
16463 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16464 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16465 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16466 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16467 [(set_attr "type" "sseadd")
16468 (set_attr "prefix" "vex")
16469 (set_attr "mode" "<MODE>")])
16471 (define_insn "<code><mode>3"
16472 [(set (match_operand:MODEF 0 "register_operand" "=x")
16474 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16475 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16476 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16477 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16478 [(set_attr "type" "sseadd")
16479 (set_attr "mode" "<MODE>")])
16481 ;; These versions of the min/max patterns implement exactly the operations
16482 ;; min = (op1 < op2 ? op1 : op2)
16483 ;; max = (!(op1 < op2) ? op1 : op2)
16484 ;; Their operands are not commutative, and thus they may be used in the
16485 ;; presence of -0.0 and NaN.
16487 (define_insn "*avx_ieee_smin<mode>3"
16488 [(set (match_operand:MODEF 0 "register_operand" "=x")
16490 [(match_operand:MODEF 1 "register_operand" "x")
16491 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16493 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16494 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16495 [(set_attr "type" "sseadd")
16496 (set_attr "prefix" "vex")
16497 (set_attr "mode" "<MODE>")])
16499 (define_insn "*ieee_smin<mode>3"
16500 [(set (match_operand:MODEF 0 "register_operand" "=x")
16502 [(match_operand:MODEF 1 "register_operand" "0")
16503 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16505 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16506 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16507 [(set_attr "type" "sseadd")
16508 (set_attr "mode" "<MODE>")])
16510 (define_insn "*avx_ieee_smax<mode>3"
16511 [(set (match_operand:MODEF 0 "register_operand" "=x")
16513 [(match_operand:MODEF 1 "register_operand" "0")
16514 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16516 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16517 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16518 [(set_attr "type" "sseadd")
16519 (set_attr "prefix" "vex")
16520 (set_attr "mode" "<MODE>")])
16522 (define_insn "*ieee_smax<mode>3"
16523 [(set (match_operand:MODEF 0 "register_operand" "=x")
16525 [(match_operand:MODEF 1 "register_operand" "0")
16526 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16529 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16530 [(set_attr "type" "sseadd")
16531 (set_attr "mode" "<MODE>")])
16533 ;; Make two stack loads independent:
16535 ;; fld %st(0) -> fld bb
16536 ;; fmul bb fmul %st(1), %st
16538 ;; Actually we only match the last two instructions for simplicity.
16540 [(set (match_operand 0 "fp_register_operand" "")
16541 (match_operand 1 "fp_register_operand" ""))
16543 (match_operator 2 "binary_fp_operator"
16545 (match_operand 3 "memory_operand" "")]))]
16546 "REGNO (operands[0]) != REGNO (operands[1])"
16547 [(set (match_dup 0) (match_dup 3))
16548 (set (match_dup 0) (match_dup 4))]
16550 ;; The % modifier is not operational anymore in peephole2's, so we have to
16551 ;; swap the operands manually in the case of addition and multiplication.
16552 "if (COMMUTATIVE_ARITH_P (operands[2]))
16553 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16554 GET_MODE (operands[2]),
16555 operands[0], operands[1]);
16557 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16558 GET_MODE (operands[2]),
16559 operands[1], operands[0]);")
16561 ;; Conditional addition patterns
16562 (define_expand "add<mode>cc"
16563 [(match_operand:SWI 0 "register_operand" "")
16564 (match_operand 1 "ordered_comparison_operator" "")
16565 (match_operand:SWI 2 "register_operand" "")
16566 (match_operand:SWI 3 "const_int_operand" "")]
16568 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16570 ;; Misc patterns (?)
16572 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16573 ;; Otherwise there will be nothing to keep
16575 ;; [(set (reg ebp) (reg esp))]
16576 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16577 ;; (clobber (eflags)]
16578 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16580 ;; in proper program order.
16582 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16583 [(set (match_operand:P 0 "register_operand" "=r,r")
16584 (plus:P (match_operand:P 1 "register_operand" "0,r")
16585 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16586 (clobber (reg:CC FLAGS_REG))
16587 (clobber (mem:BLK (scratch)))]
16590 switch (get_attr_type (insn))
16593 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16596 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16597 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16598 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16600 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16603 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16604 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16607 [(set (attr "type")
16608 (cond [(and (eq_attr "alternative" "0")
16609 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16610 (const_string "alu")
16611 (match_operand:<MODE> 2 "const0_operand" "")
16612 (const_string "imov")
16614 (const_string "lea")))
16615 (set (attr "length_immediate")
16616 (cond [(eq_attr "type" "imov")
16618 (and (eq_attr "type" "alu")
16619 (match_operand 2 "const128_operand" ""))
16622 (const_string "*")))
16623 (set_attr "mode" "<MODE>")])
16625 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16626 [(set (match_operand:P 0 "register_operand" "=r")
16627 (minus:P (match_operand:P 1 "register_operand" "0")
16628 (match_operand:P 2 "register_operand" "r")))
16629 (clobber (reg:CC FLAGS_REG))
16630 (clobber (mem:BLK (scratch)))]
16632 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16633 [(set_attr "type" "alu")
16634 (set_attr "mode" "<MODE>")])
16636 (define_insn "allocate_stack_worker_probe_<mode>"
16637 [(set (match_operand:P 0 "register_operand" "=a")
16638 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16639 UNSPECV_STACK_PROBE))
16640 (clobber (reg:CC FLAGS_REG))]
16641 "ix86_target_stack_probe ()"
16642 "call\t___chkstk_ms"
16643 [(set_attr "type" "multi")
16644 (set_attr "length" "5")])
16646 (define_expand "allocate_stack"
16647 [(match_operand 0 "register_operand" "")
16648 (match_operand 1 "general_operand" "")]
16649 "ix86_target_stack_probe ()"
16653 #ifndef CHECK_STACK_LIMIT
16654 #define CHECK_STACK_LIMIT 0
16657 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16658 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16660 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16661 stack_pointer_rtx, 0, OPTAB_DIRECT);
16662 if (x != stack_pointer_rtx)
16663 emit_move_insn (stack_pointer_rtx, x);
16667 x = copy_to_mode_reg (Pmode, operands[1]);
16669 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16671 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16672 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16673 stack_pointer_rtx, 0, OPTAB_DIRECT);
16674 if (x != stack_pointer_rtx)
16675 emit_move_insn (stack_pointer_rtx, x);
16678 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16682 ;; Use IOR for stack probes, this is shorter.
16683 (define_expand "probe_stack"
16684 [(match_operand 0 "memory_operand" "")]
16687 rtx (*gen_ior3) (rtx, rtx, rtx);
16689 gen_ior3 = (GET_MODE (operands[0]) == DImode
16690 ? gen_iordi3 : gen_iorsi3);
16692 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16696 (define_insn "adjust_stack_and_probe<mode>"
16697 [(set (match_operand:P 0 "register_operand" "=r")
16698 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16699 UNSPECV_PROBE_STACK_RANGE))
16700 (set (reg:P SP_REG)
16701 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16702 (clobber (reg:CC FLAGS_REG))
16703 (clobber (mem:BLK (scratch)))]
16705 "* return output_adjust_stack_and_probe (operands[0]);"
16706 [(set_attr "type" "multi")])
16708 (define_insn "probe_stack_range<mode>"
16709 [(set (match_operand:P 0 "register_operand" "=r")
16710 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16711 (match_operand:P 2 "const_int_operand" "n")]
16712 UNSPECV_PROBE_STACK_RANGE))
16713 (clobber (reg:CC FLAGS_REG))]
16715 "* return output_probe_stack_range (operands[0], operands[2]);"
16716 [(set_attr "type" "multi")])
16718 (define_expand "builtin_setjmp_receiver"
16719 [(label_ref (match_operand 0 "" ""))]
16720 "!TARGET_64BIT && flag_pic"
16726 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16727 rtx label_rtx = gen_label_rtx ();
16728 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16729 xops[0] = xops[1] = picreg;
16730 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16731 ix86_expand_binary_operator (MINUS, SImode, xops);
16735 emit_insn (gen_set_got (pic_offset_table_rtx));
16739 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16742 [(set (match_operand 0 "register_operand" "")
16743 (match_operator 3 "promotable_binary_operator"
16744 [(match_operand 1 "register_operand" "")
16745 (match_operand 2 "aligned_operand" "")]))
16746 (clobber (reg:CC FLAGS_REG))]
16747 "! TARGET_PARTIAL_REG_STALL && reload_completed
16748 && ((GET_MODE (operands[0]) == HImode
16749 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16750 /* ??? next two lines just !satisfies_constraint_K (...) */
16751 || !CONST_INT_P (operands[2])
16752 || satisfies_constraint_K (operands[2])))
16753 || (GET_MODE (operands[0]) == QImode
16754 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16755 [(parallel [(set (match_dup 0)
16756 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16757 (clobber (reg:CC FLAGS_REG))])]
16758 "operands[0] = gen_lowpart (SImode, operands[0]);
16759 operands[1] = gen_lowpart (SImode, operands[1]);
16760 if (GET_CODE (operands[3]) != ASHIFT)
16761 operands[2] = gen_lowpart (SImode, operands[2]);
16762 PUT_MODE (operands[3], SImode);")
16764 ; Promote the QImode tests, as i386 has encoding of the AND
16765 ; instruction with 32-bit sign-extended immediate and thus the
16766 ; instruction size is unchanged, except in the %eax case for
16767 ; which it is increased by one byte, hence the ! optimize_size.
16769 [(set (match_operand 0 "flags_reg_operand" "")
16770 (match_operator 2 "compare_operator"
16771 [(and (match_operand 3 "aligned_operand" "")
16772 (match_operand 4 "const_int_operand" ""))
16774 (set (match_operand 1 "register_operand" "")
16775 (and (match_dup 3) (match_dup 4)))]
16776 "! TARGET_PARTIAL_REG_STALL && reload_completed
16777 && optimize_insn_for_speed_p ()
16778 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16779 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16780 /* Ensure that the operand will remain sign-extended immediate. */
16781 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16782 [(parallel [(set (match_dup 0)
16783 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16786 (and:SI (match_dup 3) (match_dup 4)))])]
16789 = gen_int_mode (INTVAL (operands[4])
16790 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16791 operands[1] = gen_lowpart (SImode, operands[1]);
16792 operands[3] = gen_lowpart (SImode, operands[3]);
16795 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16796 ; the TEST instruction with 32-bit sign-extended immediate and thus
16797 ; the instruction size would at least double, which is not what we
16798 ; want even with ! optimize_size.
16800 [(set (match_operand 0 "flags_reg_operand" "")
16801 (match_operator 1 "compare_operator"
16802 [(and (match_operand:HI 2 "aligned_operand" "")
16803 (match_operand:HI 3 "const_int_operand" ""))
16805 "! TARGET_PARTIAL_REG_STALL && reload_completed
16806 && ! TARGET_FAST_PREFIX
16807 && optimize_insn_for_speed_p ()
16808 /* Ensure that the operand will remain sign-extended immediate. */
16809 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16810 [(set (match_dup 0)
16811 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16815 = gen_int_mode (INTVAL (operands[3])
16816 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16817 operands[2] = gen_lowpart (SImode, operands[2]);
16821 [(set (match_operand 0 "register_operand" "")
16822 (neg (match_operand 1 "register_operand" "")))
16823 (clobber (reg:CC FLAGS_REG))]
16824 "! TARGET_PARTIAL_REG_STALL && reload_completed
16825 && (GET_MODE (operands[0]) == HImode
16826 || (GET_MODE (operands[0]) == QImode
16827 && (TARGET_PROMOTE_QImode
16828 || optimize_insn_for_size_p ())))"
16829 [(parallel [(set (match_dup 0)
16830 (neg:SI (match_dup 1)))
16831 (clobber (reg:CC FLAGS_REG))])]
16832 "operands[0] = gen_lowpart (SImode, operands[0]);
16833 operands[1] = gen_lowpart (SImode, operands[1]);")
16836 [(set (match_operand 0 "register_operand" "")
16837 (not (match_operand 1 "register_operand" "")))]
16838 "! TARGET_PARTIAL_REG_STALL && reload_completed
16839 && (GET_MODE (operands[0]) == HImode
16840 || (GET_MODE (operands[0]) == QImode
16841 && (TARGET_PROMOTE_QImode
16842 || optimize_insn_for_size_p ())))"
16843 [(set (match_dup 0)
16844 (not:SI (match_dup 1)))]
16845 "operands[0] = gen_lowpart (SImode, operands[0]);
16846 operands[1] = gen_lowpart (SImode, operands[1]);")
16849 [(set (match_operand 0 "register_operand" "")
16850 (if_then_else (match_operator 1 "ordered_comparison_operator"
16851 [(reg FLAGS_REG) (const_int 0)])
16852 (match_operand 2 "register_operand" "")
16853 (match_operand 3 "register_operand" "")))]
16854 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16855 && (GET_MODE (operands[0]) == HImode
16856 || (GET_MODE (operands[0]) == QImode
16857 && (TARGET_PROMOTE_QImode
16858 || optimize_insn_for_size_p ())))"
16859 [(set (match_dup 0)
16860 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16861 "operands[0] = gen_lowpart (SImode, operands[0]);
16862 operands[2] = gen_lowpart (SImode, operands[2]);
16863 operands[3] = gen_lowpart (SImode, operands[3]);")
16865 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16866 ;; transform a complex memory operation into two memory to register operations.
16868 ;; Don't push memory operands
16870 [(set (match_operand:SWI 0 "push_operand" "")
16871 (match_operand:SWI 1 "memory_operand" ""))
16872 (match_scratch:SWI 2 "<r>")]
16873 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16874 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16875 [(set (match_dup 2) (match_dup 1))
16876 (set (match_dup 0) (match_dup 2))])
16878 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16881 [(set (match_operand:SF 0 "push_operand" "")
16882 (match_operand:SF 1 "memory_operand" ""))
16883 (match_scratch:SF 2 "r")]
16884 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16885 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16886 [(set (match_dup 2) (match_dup 1))
16887 (set (match_dup 0) (match_dup 2))])
16889 ;; Don't move an immediate directly to memory when the instruction
16892 [(match_scratch:SWI124 1 "<r>")
16893 (set (match_operand:SWI124 0 "memory_operand" "")
16895 "optimize_insn_for_speed_p ()
16896 && !TARGET_USE_MOV0
16897 && TARGET_SPLIT_LONG_MOVES
16898 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16899 && peep2_regno_dead_p (0, FLAGS_REG)"
16900 [(parallel [(set (match_dup 2) (const_int 0))
16901 (clobber (reg:CC FLAGS_REG))])
16902 (set (match_dup 0) (match_dup 1))]
16903 "operands[2] = gen_lowpart (SImode, operands[1]);")
16906 [(match_scratch:SWI124 2 "<r>")
16907 (set (match_operand:SWI124 0 "memory_operand" "")
16908 (match_operand:SWI124 1 "immediate_operand" ""))]
16909 "optimize_insn_for_speed_p ()
16910 && TARGET_SPLIT_LONG_MOVES
16911 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16912 [(set (match_dup 2) (match_dup 1))
16913 (set (match_dup 0) (match_dup 2))])
16915 ;; Don't compare memory with zero, load and use a test instead.
16917 [(set (match_operand 0 "flags_reg_operand" "")
16918 (match_operator 1 "compare_operator"
16919 [(match_operand:SI 2 "memory_operand" "")
16921 (match_scratch:SI 3 "r")]
16922 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16923 [(set (match_dup 3) (match_dup 2))
16924 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16926 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16927 ;; Don't split NOTs with a displacement operand, because resulting XOR
16928 ;; will not be pairable anyway.
16930 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16931 ;; represented using a modRM byte. The XOR replacement is long decoded,
16932 ;; so this split helps here as well.
16934 ;; Note: Can't do this as a regular split because we can't get proper
16935 ;; lifetime information then.
16938 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16939 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16940 "optimize_insn_for_speed_p ()
16941 && ((TARGET_NOT_UNPAIRABLE
16942 && (!MEM_P (operands[0])
16943 || !memory_displacement_operand (operands[0], <MODE>mode)))
16944 || (TARGET_NOT_VECTORMODE
16945 && long_memory_operand (operands[0], <MODE>mode)))
16946 && peep2_regno_dead_p (0, FLAGS_REG)"
16947 [(parallel [(set (match_dup 0)
16948 (xor:SWI124 (match_dup 1) (const_int -1)))
16949 (clobber (reg:CC FLAGS_REG))])])
16951 ;; Non pairable "test imm, reg" instructions can be translated to
16952 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16953 ;; byte opcode instead of two, have a short form for byte operands),
16954 ;; so do it for other CPUs as well. Given that the value was dead,
16955 ;; this should not create any new dependencies. Pass on the sub-word
16956 ;; versions if we're concerned about partial register stalls.
16959 [(set (match_operand 0 "flags_reg_operand" "")
16960 (match_operator 1 "compare_operator"
16961 [(and:SI (match_operand:SI 2 "register_operand" "")
16962 (match_operand:SI 3 "immediate_operand" ""))
16964 "ix86_match_ccmode (insn, CCNOmode)
16965 && (true_regnum (operands[2]) != AX_REG
16966 || satisfies_constraint_K (operands[3]))
16967 && peep2_reg_dead_p (1, operands[2])"
16969 [(set (match_dup 0)
16970 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16973 (and:SI (match_dup 2) (match_dup 3)))])])
16975 ;; We don't need to handle HImode case, because it will be promoted to SImode
16976 ;; on ! TARGET_PARTIAL_REG_STALL
16979 [(set (match_operand 0 "flags_reg_operand" "")
16980 (match_operator 1 "compare_operator"
16981 [(and:QI (match_operand:QI 2 "register_operand" "")
16982 (match_operand:QI 3 "immediate_operand" ""))
16984 "! TARGET_PARTIAL_REG_STALL
16985 && ix86_match_ccmode (insn, CCNOmode)
16986 && true_regnum (operands[2]) != AX_REG
16987 && peep2_reg_dead_p (1, operands[2])"
16989 [(set (match_dup 0)
16990 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16993 (and:QI (match_dup 2) (match_dup 3)))])])
16996 [(set (match_operand 0 "flags_reg_operand" "")
16997 (match_operator 1 "compare_operator"
17000 (match_operand 2 "ext_register_operand" "")
17003 (match_operand 3 "const_int_operand" ""))
17005 "! TARGET_PARTIAL_REG_STALL
17006 && ix86_match_ccmode (insn, CCNOmode)
17007 && true_regnum (operands[2]) != AX_REG
17008 && peep2_reg_dead_p (1, operands[2])"
17009 [(parallel [(set (match_dup 0)
17018 (set (zero_extract:SI (match_dup 2)
17026 (match_dup 3)))])])
17028 ;; Don't do logical operations with memory inputs.
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "register_operand" "")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17034 (match_operand:SI 1 "memory_operand" "")]))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17037 [(set (match_dup 2) (match_dup 1))
17038 (parallel [(set (match_dup 0)
17039 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17040 (clobber (reg:CC FLAGS_REG))])])
17043 [(match_scratch:SI 2 "r")
17044 (parallel [(set (match_operand:SI 0 "register_operand" "")
17045 (match_operator:SI 3 "arith_or_logical_operator"
17046 [(match_operand:SI 1 "memory_operand" "")
17048 (clobber (reg:CC FLAGS_REG))])]
17049 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17050 [(set (match_dup 2) (match_dup 1))
17051 (parallel [(set (match_dup 0)
17052 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17053 (clobber (reg:CC FLAGS_REG))])])
17055 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17056 ;; refers to the destination of the load!
17059 [(set (match_operand:SI 0 "register_operand" "")
17060 (match_operand:SI 1 "register_operand" ""))
17061 (parallel [(set (match_dup 0)
17062 (match_operator:SI 3 "commutative_operator"
17064 (match_operand:SI 2 "memory_operand" "")]))
17065 (clobber (reg:CC FLAGS_REG))])]
17066 "REGNO (operands[0]) != REGNO (operands[1])
17067 && GENERAL_REGNO_P (REGNO (operands[0]))
17068 && GENERAL_REGNO_P (REGNO (operands[1]))"
17069 [(set (match_dup 0) (match_dup 4))
17070 (parallel [(set (match_dup 0)
17071 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17072 (clobber (reg:CC FLAGS_REG))])]
17073 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17076 [(set (match_operand 0 "register_operand" "")
17077 (match_operand 1 "register_operand" ""))
17079 (match_operator 3 "commutative_operator"
17081 (match_operand 2 "memory_operand" "")]))]
17082 "REGNO (operands[0]) != REGNO (operands[1])
17083 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17084 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17085 [(set (match_dup 0) (match_dup 2))
17087 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17089 ; Don't do logical operations with memory outputs
17091 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17092 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17093 ; the same decoder scheduling characteristics as the original.
17096 [(match_scratch:SI 2 "r")
17097 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17098 (match_operator:SI 3 "arith_or_logical_operator"
17100 (match_operand:SI 1 "nonmemory_operand" "")]))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17103 /* Do not split stack checking probes. */
17104 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17105 [(set (match_dup 2) (match_dup 0))
17106 (parallel [(set (match_dup 2)
17107 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17108 (clobber (reg:CC FLAGS_REG))])
17109 (set (match_dup 0) (match_dup 2))])
17112 [(match_scratch:SI 2 "r")
17113 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17114 (match_operator:SI 3 "arith_or_logical_operator"
17115 [(match_operand:SI 1 "nonmemory_operand" "")
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17119 /* Do not split stack checking probes. */
17120 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17121 [(set (match_dup 2) (match_dup 0))
17122 (parallel [(set (match_dup 2)
17123 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17124 (clobber (reg:CC FLAGS_REG))])
17125 (set (match_dup 0) (match_dup 2))])
17127 ;; Attempt to always use XOR for zeroing registers.
17129 [(set (match_operand 0 "register_operand" "")
17130 (match_operand 1 "const0_operand" ""))]
17131 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17132 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17133 && GENERAL_REG_P (operands[0])
17134 && peep2_regno_dead_p (0, FLAGS_REG)"
17135 [(parallel [(set (match_dup 0) (const_int 0))
17136 (clobber (reg:CC FLAGS_REG))])]
17137 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17140 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17142 "(GET_MODE (operands[0]) == QImode
17143 || GET_MODE (operands[0]) == HImode)
17144 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17145 && peep2_regno_dead_p (0, FLAGS_REG)"
17146 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17147 (clobber (reg:CC FLAGS_REG))])])
17149 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17151 [(set (match_operand:SWI248 0 "register_operand" "")
17153 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17154 && peep2_regno_dead_p (0, FLAGS_REG)"
17155 [(parallel [(set (match_dup 0) (const_int -1))
17156 (clobber (reg:CC FLAGS_REG))])]
17158 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17159 operands[0] = gen_lowpart (SImode, operands[0]);
17162 ;; Attempt to convert simple lea to add/shift.
17163 ;; These can be created by move expanders.
17166 [(set (match_operand:SWI48 0 "register_operand" "")
17167 (plus:SWI48 (match_dup 0)
17168 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17169 "peep2_regno_dead_p (0, FLAGS_REG)"
17170 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17171 (clobber (reg:CC FLAGS_REG))])])
17174 [(set (match_operand:SI 0 "register_operand" "")
17175 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17176 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17178 && peep2_regno_dead_p (0, FLAGS_REG)
17179 && REGNO (operands[0]) == REGNO (operands[1])"
17180 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17181 (clobber (reg:CC FLAGS_REG))])]
17182 "operands[2] = gen_lowpart (SImode, operands[2]);")
17185 [(set (match_operand:SWI48 0 "register_operand" "")
17186 (mult:SWI48 (match_dup 0)
17187 (match_operand:SWI48 1 "const_int_operand" "")))]
17188 "exact_log2 (INTVAL (operands[1])) >= 0
17189 && peep2_regno_dead_p (0, FLAGS_REG)"
17190 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17191 (clobber (reg:CC FLAGS_REG))])]
17192 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17195 [(set (match_operand:SI 0 "register_operand" "")
17196 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17197 (match_operand:DI 2 "const_int_operand" "")) 0))]
17199 && exact_log2 (INTVAL (operands[2])) >= 0
17200 && REGNO (operands[0]) == REGNO (operands[1])
17201 && peep2_regno_dead_p (0, FLAGS_REG)"
17202 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17203 (clobber (reg:CC FLAGS_REG))])]
17204 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17206 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17207 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17208 ;; On many CPUs it is also faster, since special hardware to avoid esp
17209 ;; dependencies is present.
17211 ;; While some of these conversions may be done using splitters, we use
17212 ;; peepholes in order to allow combine_stack_adjustments pass to see
17213 ;; nonobfuscated RTL.
17215 ;; Convert prologue esp subtractions to push.
17216 ;; We need register to push. In order to keep verify_flow_info happy we have
17218 ;; - use scratch and clobber it in order to avoid dependencies
17219 ;; - use already live register
17220 ;; We can't use the second way right now, since there is no reliable way how to
17221 ;; verify that given register is live. First choice will also most likely in
17222 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17223 ;; call clobbered registers are dead. We may want to use base pointer as an
17224 ;; alternative when no register is available later.
17227 [(match_scratch:P 1 "r")
17228 (parallel [(set (reg:P SP_REG)
17229 (plus:P (reg:P SP_REG)
17230 (match_operand:P 0 "const_int_operand" "")))
17231 (clobber (reg:CC FLAGS_REG))
17232 (clobber (mem:BLK (scratch)))])]
17233 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17234 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17235 [(clobber (match_dup 1))
17236 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17237 (clobber (mem:BLK (scratch)))])])
17240 [(match_scratch:P 1 "r")
17241 (parallel [(set (reg:P SP_REG)
17242 (plus:P (reg:P SP_REG)
17243 (match_operand:P 0 "const_int_operand" "")))
17244 (clobber (reg:CC FLAGS_REG))
17245 (clobber (mem:BLK (scratch)))])]
17246 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17247 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17248 [(clobber (match_dup 1))
17249 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17250 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17251 (clobber (mem:BLK (scratch)))])])
17253 ;; Convert esp subtractions to push.
17255 [(match_scratch:P 1 "r")
17256 (parallel [(set (reg:P SP_REG)
17257 (plus:P (reg:P SP_REG)
17258 (match_operand:P 0 "const_int_operand" "")))
17259 (clobber (reg:CC FLAGS_REG))])]
17260 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17261 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17262 [(clobber (match_dup 1))
17263 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17266 [(match_scratch:P 1 "r")
17267 (parallel [(set (reg:P SP_REG)
17268 (plus:P (reg:P SP_REG)
17269 (match_operand:P 0 "const_int_operand" "")))
17270 (clobber (reg:CC FLAGS_REG))])]
17271 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17272 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17273 [(clobber (match_dup 1))
17274 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17275 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17277 ;; Convert epilogue deallocator to pop.
17279 [(match_scratch:P 1 "r")
17280 (parallel [(set (reg:P SP_REG)
17281 (plus:P (reg:P SP_REG)
17282 (match_operand:P 0 "const_int_operand" "")))
17283 (clobber (reg:CC FLAGS_REG))
17284 (clobber (mem:BLK (scratch)))])]
17285 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17286 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17287 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17288 (clobber (mem:BLK (scratch)))])])
17290 ;; Two pops case is tricky, since pop causes dependency
17291 ;; on destination register. We use two registers if available.
17293 [(match_scratch:P 1 "r")
17294 (match_scratch:P 2 "r")
17295 (parallel [(set (reg:P SP_REG)
17296 (plus:P (reg:P SP_REG)
17297 (match_operand:P 0 "const_int_operand" "")))
17298 (clobber (reg:CC FLAGS_REG))
17299 (clobber (mem:BLK (scratch)))])]
17300 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17301 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17302 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17303 (clobber (mem:BLK (scratch)))])
17304 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17307 [(match_scratch:P 1 "r")
17308 (parallel [(set (reg:P SP_REG)
17309 (plus:P (reg:P SP_REG)
17310 (match_operand:P 0 "const_int_operand" "")))
17311 (clobber (reg:CC FLAGS_REG))
17312 (clobber (mem:BLK (scratch)))])]
17313 "optimize_insn_for_size_p ()
17314 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17315 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17316 (clobber (mem:BLK (scratch)))])
17317 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17319 ;; Convert esp additions to pop.
17321 [(match_scratch:P 1 "r")
17322 (parallel [(set (reg:P SP_REG)
17323 (plus:P (reg:P SP_REG)
17324 (match_operand:P 0 "const_int_operand" "")))
17325 (clobber (reg:CC FLAGS_REG))])]
17326 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17327 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17329 ;; Two pops case is tricky, since pop causes dependency
17330 ;; on destination register. We use two registers if available.
17332 [(match_scratch:P 1 "r")
17333 (match_scratch:P 2 "r")
17334 (parallel [(set (reg:P SP_REG)
17335 (plus:P (reg:P SP_REG)
17336 (match_operand:P 0 "const_int_operand" "")))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17339 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17340 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17343 [(match_scratch:P 1 "r")
17344 (parallel [(set (reg:P SP_REG)
17345 (plus:P (reg:P SP_REG)
17346 (match_operand:P 0 "const_int_operand" "")))
17347 (clobber (reg:CC FLAGS_REG))])]
17348 "optimize_insn_for_size_p ()
17349 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17350 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17351 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17353 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17354 ;; required and register dies. Similarly for 128 to -128.
17356 [(set (match_operand 0 "flags_reg_operand" "")
17357 (match_operator 1 "compare_operator"
17358 [(match_operand 2 "register_operand" "")
17359 (match_operand 3 "const_int_operand" "")]))]
17360 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17361 && incdec_operand (operands[3], GET_MODE (operands[3])))
17362 || (!TARGET_FUSE_CMP_AND_BRANCH
17363 && INTVAL (operands[3]) == 128))
17364 && ix86_match_ccmode (insn, CCGCmode)
17365 && peep2_reg_dead_p (1, operands[2])"
17366 [(parallel [(set (match_dup 0)
17367 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17368 (clobber (match_dup 2))])])
17370 ;; Convert imul by three, five and nine into lea
17373 [(set (match_operand:SWI48 0 "register_operand" "")
17374 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17375 (match_operand:SWI48 2 "const_int_operand" "")))
17376 (clobber (reg:CC FLAGS_REG))])]
17377 "INTVAL (operands[2]) == 3
17378 || INTVAL (operands[2]) == 5
17379 || INTVAL (operands[2]) == 9"
17380 [(set (match_dup 0)
17381 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17383 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17387 [(set (match_operand:SWI48 0 "register_operand" "")
17388 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17389 (match_operand:SWI48 2 "const_int_operand" "")))
17390 (clobber (reg:CC FLAGS_REG))])]
17391 "optimize_insn_for_speed_p ()
17392 && (INTVAL (operands[2]) == 3
17393 || INTVAL (operands[2]) == 5
17394 || INTVAL (operands[2]) == 9)"
17395 [(set (match_dup 0) (match_dup 1))
17397 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17399 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17401 ;; imul $32bit_imm, mem, reg is vector decoded, while
17402 ;; imul $32bit_imm, reg, reg is direct decoded.
17404 [(match_scratch:SWI48 3 "r")
17405 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17406 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17407 (match_operand:SWI48 2 "immediate_operand" "")))
17408 (clobber (reg:CC FLAGS_REG))])]
17409 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17410 && !satisfies_constraint_K (operands[2])"
17411 [(set (match_dup 3) (match_dup 1))
17412 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17413 (clobber (reg:CC FLAGS_REG))])])
17416 [(match_scratch:SI 3 "r")
17417 (parallel [(set (match_operand:DI 0 "register_operand" "")
17419 (mult:SI (match_operand:SI 1 "memory_operand" "")
17420 (match_operand:SI 2 "immediate_operand" ""))))
17421 (clobber (reg:CC FLAGS_REG))])]
17423 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17424 && !satisfies_constraint_K (operands[2])"
17425 [(set (match_dup 3) (match_dup 1))
17426 (parallel [(set (match_dup 0)
17427 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17428 (clobber (reg:CC FLAGS_REG))])])
17430 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17431 ;; Convert it into imul reg, reg
17432 ;; It would be better to force assembler to encode instruction using long
17433 ;; immediate, but there is apparently no way to do so.
17435 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17437 (match_operand:SWI248 1 "nonimmediate_operand" "")
17438 (match_operand:SWI248 2 "const_int_operand" "")))
17439 (clobber (reg:CC FLAGS_REG))])
17440 (match_scratch:SWI248 3 "r")]
17441 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17442 && satisfies_constraint_K (operands[2])"
17443 [(set (match_dup 3) (match_dup 2))
17444 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17445 (clobber (reg:CC FLAGS_REG))])]
17447 if (!rtx_equal_p (operands[0], operands[1]))
17448 emit_move_insn (operands[0], operands[1]);
17451 ;; After splitting up read-modify operations, array accesses with memory
17452 ;; operands might end up in form:
17454 ;; movl 4(%esp), %edx
17456 ;; instead of pre-splitting:
17458 ;; addl 4(%esp), %eax
17460 ;; movl 4(%esp), %edx
17461 ;; leal (%edx,%eax,4), %eax
17464 [(match_scratch:P 5 "r")
17465 (parallel [(set (match_operand 0 "register_operand" "")
17466 (ashift (match_operand 1 "register_operand" "")
17467 (match_operand 2 "const_int_operand" "")))
17468 (clobber (reg:CC FLAGS_REG))])
17469 (parallel [(set (match_operand 3 "register_operand" "")
17470 (plus (match_dup 0)
17471 (match_operand 4 "x86_64_general_operand" "")))
17472 (clobber (reg:CC FLAGS_REG))])]
17473 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17474 /* Validate MODE for lea. */
17475 && ((!TARGET_PARTIAL_REG_STALL
17476 && (GET_MODE (operands[0]) == QImode
17477 || GET_MODE (operands[0]) == HImode))
17478 || GET_MODE (operands[0]) == SImode
17479 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17480 && (rtx_equal_p (operands[0], operands[3])
17481 || peep2_reg_dead_p (2, operands[0]))
17482 /* We reorder load and the shift. */
17483 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17484 [(set (match_dup 5) (match_dup 4))
17485 (set (match_dup 0) (match_dup 1))]
17487 enum machine_mode op1mode = GET_MODE (operands[1]);
17488 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17489 int scale = 1 << INTVAL (operands[2]);
17490 rtx index = gen_lowpart (Pmode, operands[1]);
17491 rtx base = gen_lowpart (Pmode, operands[5]);
17492 rtx dest = gen_lowpart (mode, operands[3]);
17494 operands[1] = gen_rtx_PLUS (Pmode, base,
17495 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17496 operands[5] = base;
17498 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17499 if (op1mode != Pmode)
17500 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17501 operands[0] = dest;
17504 ;; Call-value patterns last so that the wildcard operand does not
17505 ;; disrupt insn-recog's switch tables.
17507 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17509 [(set (match_operand 0 "" "")
17510 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17511 (match_operand:SI 2 "" "")))
17512 (set (reg:SI SP_REG)
17513 (plus:SI (reg:SI SP_REG)
17514 (match_operand:SI 3 "immediate_operand" "")))])
17515 (unspec [(match_operand 4 "const_int_operand" "")]
17516 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17517 "TARGET_VZEROUPPER && !TARGET_64BIT"
17519 "&& reload_completed"
17521 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17522 [(set_attr "type" "callv")])
17524 (define_insn "*call_value_pop_0"
17525 [(set (match_operand 0 "" "")
17526 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17527 (match_operand:SI 2 "" "")))
17528 (set (reg:SI SP_REG)
17529 (plus:SI (reg:SI SP_REG)
17530 (match_operand:SI 3 "immediate_operand" "")))]
17532 { return ix86_output_call_insn (insn, operands[1], 1); }
17533 [(set_attr "type" "callv")])
17535 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17537 [(set (match_operand 0 "" "")
17538 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17539 (match_operand:SI 2 "" "")))
17540 (set (reg:SI SP_REG)
17541 (plus:SI (reg:SI SP_REG)
17542 (match_operand:SI 3 "immediate_operand" "i")))])
17543 (unspec [(match_operand 4 "const_int_operand" "")]
17544 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17545 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17547 "&& reload_completed"
17549 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17550 [(set_attr "type" "callv")])
17552 (define_insn "*call_value_pop_1"
17553 [(set (match_operand 0 "" "")
17554 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17555 (match_operand:SI 2 "" "")))
17556 (set (reg:SI SP_REG)
17557 (plus:SI (reg:SI SP_REG)
17558 (match_operand:SI 3 "immediate_operand" "i")))]
17559 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17560 { return ix86_output_call_insn (insn, operands[1], 1); }
17561 [(set_attr "type" "callv")])
17563 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17565 [(set (match_operand 0 "" "")
17566 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17567 (match_operand:SI 2 "" "")))
17568 (set (reg:SI SP_REG)
17569 (plus:SI (reg:SI SP_REG)
17570 (match_operand:SI 3 "immediate_operand" "i,i")))])
17571 (unspec [(match_operand 4 "const_int_operand" "")]
17572 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17573 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17575 "&& reload_completed"
17577 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17578 [(set_attr "type" "callv")])
17580 (define_insn "*sibcall_value_pop_1"
17581 [(set (match_operand 0 "" "")
17582 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17583 (match_operand:SI 2 "" "")))
17584 (set (reg:SI SP_REG)
17585 (plus:SI (reg:SI SP_REG)
17586 (match_operand:SI 3 "immediate_operand" "i,i")))]
17587 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17588 { return ix86_output_call_insn (insn, operands[1], 1); }
17589 [(set_attr "type" "callv")])
17591 (define_insn_and_split "*call_value_0_vzeroupper"
17592 [(set (match_operand 0 "" "")
17593 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17594 (match_operand:SI 2 "" "")))
17595 (unspec [(match_operand 3 "const_int_operand" "")]
17596 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17597 "TARGET_VZEROUPPER && !TARGET_64BIT"
17599 "&& reload_completed"
17601 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17602 [(set_attr "type" "callv")])
17604 (define_insn "*call_value_0"
17605 [(set (match_operand 0 "" "")
17606 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17607 (match_operand:SI 2 "" "")))]
17609 { return ix86_output_call_insn (insn, operands[1], 1); }
17610 [(set_attr "type" "callv")])
17612 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17613 [(set (match_operand 0 "" "")
17614 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17615 (match_operand:DI 2 "const_int_operand" "")))
17616 (unspec [(match_operand 3 "const_int_operand" "")]
17617 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17618 "TARGET_VZEROUPPER && TARGET_64BIT"
17620 "&& reload_completed"
17622 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17623 [(set_attr "type" "callv")])
17625 (define_insn "*call_value_0_rex64"
17626 [(set (match_operand 0 "" "")
17627 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17628 (match_operand:DI 2 "const_int_operand" "")))]
17630 { return ix86_output_call_insn (insn, operands[1], 1); }
17631 [(set_attr "type" "callv")])
17633 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17635 [(set (match_operand 0 "" "")
17636 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17637 (match_operand:DI 2 "const_int_operand" "")))
17638 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17639 (clobber (reg:TI XMM6_REG))
17640 (clobber (reg:TI XMM7_REG))
17641 (clobber (reg:TI XMM8_REG))
17642 (clobber (reg:TI XMM9_REG))
17643 (clobber (reg:TI XMM10_REG))
17644 (clobber (reg:TI XMM11_REG))
17645 (clobber (reg:TI XMM12_REG))
17646 (clobber (reg:TI XMM13_REG))
17647 (clobber (reg:TI XMM14_REG))
17648 (clobber (reg:TI XMM15_REG))
17649 (clobber (reg:DI SI_REG))
17650 (clobber (reg:DI DI_REG))])
17651 (unspec [(match_operand 3 "const_int_operand" "")]
17652 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17653 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17655 "&& reload_completed"
17657 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17658 [(set_attr "type" "callv")])
17660 (define_insn "*call_value_0_rex64_ms_sysv"
17661 [(set (match_operand 0 "" "")
17662 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17663 (match_operand:DI 2 "const_int_operand" "")))
17664 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17665 (clobber (reg:TI XMM6_REG))
17666 (clobber (reg:TI XMM7_REG))
17667 (clobber (reg:TI XMM8_REG))
17668 (clobber (reg:TI XMM9_REG))
17669 (clobber (reg:TI XMM10_REG))
17670 (clobber (reg:TI XMM11_REG))
17671 (clobber (reg:TI XMM12_REG))
17672 (clobber (reg:TI XMM13_REG))
17673 (clobber (reg:TI XMM14_REG))
17674 (clobber (reg:TI XMM15_REG))
17675 (clobber (reg:DI SI_REG))
17676 (clobber (reg:DI DI_REG))]
17677 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17678 { return ix86_output_call_insn (insn, operands[1], 1); }
17679 [(set_attr "type" "callv")])
17681 (define_insn_and_split "*call_value_1_vzeroupper"
17682 [(set (match_operand 0 "" "")
17683 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17684 (match_operand:SI 2 "" "")))
17685 (unspec [(match_operand 3 "const_int_operand" "")]
17686 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17687 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17689 "&& reload_completed"
17691 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17692 [(set_attr "type" "callv")])
17694 (define_insn "*call_value_1"
17695 [(set (match_operand 0 "" "")
17696 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17697 (match_operand:SI 2 "" "")))]
17698 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17699 { return ix86_output_call_insn (insn, operands[1], 1); }
17700 [(set_attr "type" "callv")])
17702 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17703 [(set (match_operand 0 "" "")
17704 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17705 (match_operand:SI 2 "" "")))
17706 (unspec [(match_operand 3 "const_int_operand" "")]
17707 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17708 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17710 "&& reload_completed"
17712 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17713 [(set_attr "type" "callv")])
17715 (define_insn "*sibcall_value_1"
17716 [(set (match_operand 0 "" "")
17717 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17718 (match_operand:SI 2 "" "")))]
17719 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17720 { return ix86_output_call_insn (insn, operands[1], 1); }
17721 [(set_attr "type" "callv")])
17723 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17724 [(set (match_operand 0 "" "")
17725 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17726 (match_operand:DI 2 "" "")))
17727 (unspec [(match_operand 3 "const_int_operand" "")]
17728 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17729 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17730 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17732 "&& reload_completed"
17734 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17735 [(set_attr "type" "callv")])
17737 (define_insn "*call_value_1_rex64"
17738 [(set (match_operand 0 "" "")
17739 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17740 (match_operand:DI 2 "" "")))]
17741 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17742 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17743 { return ix86_output_call_insn (insn, operands[1], 1); }
17744 [(set_attr "type" "callv")])
17746 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17748 [(set (match_operand 0 "" "")
17749 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17750 (match_operand:DI 2 "" "")))
17751 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17752 (clobber (reg:TI XMM6_REG))
17753 (clobber (reg:TI XMM7_REG))
17754 (clobber (reg:TI XMM8_REG))
17755 (clobber (reg:TI XMM9_REG))
17756 (clobber (reg:TI XMM10_REG))
17757 (clobber (reg:TI XMM11_REG))
17758 (clobber (reg:TI XMM12_REG))
17759 (clobber (reg:TI XMM13_REG))
17760 (clobber (reg:TI XMM14_REG))
17761 (clobber (reg:TI XMM15_REG))
17762 (clobber (reg:DI SI_REG))
17763 (clobber (reg:DI DI_REG))])
17764 (unspec [(match_operand 3 "const_int_operand" "")]
17765 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17766 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17768 "&& reload_completed"
17770 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17771 [(set_attr "type" "callv")])
17773 (define_insn "*call_value_1_rex64_ms_sysv"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17776 (match_operand:DI 2 "" "")))
17777 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17778 (clobber (reg:TI XMM6_REG))
17779 (clobber (reg:TI XMM7_REG))
17780 (clobber (reg:TI XMM8_REG))
17781 (clobber (reg:TI XMM9_REG))
17782 (clobber (reg:TI XMM10_REG))
17783 (clobber (reg:TI XMM11_REG))
17784 (clobber (reg:TI XMM12_REG))
17785 (clobber (reg:TI XMM13_REG))
17786 (clobber (reg:TI XMM14_REG))
17787 (clobber (reg:TI XMM15_REG))
17788 (clobber (reg:DI SI_REG))
17789 (clobber (reg:DI DI_REG))]
17790 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17791 { return ix86_output_call_insn (insn, operands[1], 1); }
17792 [(set_attr "type" "callv")])
17794 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17795 [(set (match_operand 0 "" "")
17796 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17797 (match_operand:DI 2 "" "")))
17798 (unspec [(match_operand 3 "const_int_operand" "")]
17799 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17800 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17802 "&& reload_completed"
17804 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17805 [(set_attr "type" "callv")])
17807 (define_insn "*call_value_1_rex64_large"
17808 [(set (match_operand 0 "" "")
17809 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17810 (match_operand:DI 2 "" "")))]
17811 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17812 { return ix86_output_call_insn (insn, operands[1], 1); }
17813 [(set_attr "type" "callv")])
17815 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17816 [(set (match_operand 0 "" "")
17817 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17818 (match_operand:DI 2 "" "")))
17819 (unspec [(match_operand 3 "const_int_operand" "")]
17820 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17821 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17823 "&& reload_completed"
17825 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17826 [(set_attr "type" "callv")])
17828 (define_insn "*sibcall_value_1_rex64"
17829 [(set (match_operand 0 "" "")
17830 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17831 (match_operand:DI 2 "" "")))]
17832 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17833 { return ix86_output_call_insn (insn, operands[1], 1); }
17834 [(set_attr "type" "callv")])
17836 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17837 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17838 ;; caught for use by garbage collectors and the like. Using an insn that
17839 ;; maps to SIGILL makes it more likely the program will rightfully die.
17840 ;; Keeping with tradition, "6" is in honor of #UD.
17841 (define_insn "trap"
17842 [(trap_if (const_int 1) (const_int 6))]
17844 { return ASM_SHORT "0x0b0f"; }
17845 [(set_attr "length" "2")])
17847 (define_expand "prefetch"
17848 [(prefetch (match_operand 0 "address_operand" "")
17849 (match_operand:SI 1 "const_int_operand" "")
17850 (match_operand:SI 2 "const_int_operand" ""))]
17851 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17853 int rw = INTVAL (operands[1]);
17854 int locality = INTVAL (operands[2]);
17856 gcc_assert (rw == 0 || rw == 1);
17857 gcc_assert (locality >= 0 && locality <= 3);
17858 gcc_assert (GET_MODE (operands[0]) == Pmode
17859 || GET_MODE (operands[0]) == VOIDmode);
17861 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17862 supported by SSE counterpart or the SSE prefetch is not available
17863 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17865 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17866 operands[2] = GEN_INT (3);
17868 operands[1] = const0_rtx;
17871 (define_insn "*prefetch_sse_<mode>"
17872 [(prefetch (match_operand:P 0 "address_operand" "p")
17874 (match_operand:SI 1 "const_int_operand" ""))]
17875 "TARGET_PREFETCH_SSE"
17877 static const char * const patterns[4] = {
17878 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17881 int locality = INTVAL (operands[1]);
17882 gcc_assert (locality >= 0 && locality <= 3);
17884 return patterns[locality];
17886 [(set_attr "type" "sse")
17887 (set_attr "atom_sse_attr" "prefetch")
17888 (set (attr "length_address")
17889 (symbol_ref "memory_address_length (operands[0])"))
17890 (set_attr "memory" "none")])
17892 (define_insn "*prefetch_3dnow_<mode>"
17893 [(prefetch (match_operand:P 0 "address_operand" "p")
17894 (match_operand:SI 1 "const_int_operand" "n")
17898 if (INTVAL (operands[1]) == 0)
17899 return "prefetch\t%a0";
17901 return "prefetchw\t%a0";
17903 [(set_attr "type" "mmx")
17904 (set (attr "length_address")
17905 (symbol_ref "memory_address_length (operands[0])"))
17906 (set_attr "memory" "none")])
17908 (define_expand "stack_protect_set"
17909 [(match_operand 0 "memory_operand" "")
17910 (match_operand 1 "memory_operand" "")]
17913 rtx (*insn)(rtx, rtx);
17915 #ifdef TARGET_THREAD_SSP_OFFSET
17916 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17917 insn = (TARGET_64BIT
17918 ? gen_stack_tls_protect_set_di
17919 : gen_stack_tls_protect_set_si);
17921 insn = (TARGET_64BIT
17922 ? gen_stack_protect_set_di
17923 : gen_stack_protect_set_si);
17926 emit_insn (insn (operands[0], operands[1]));
17930 (define_insn "stack_protect_set_<mode>"
17931 [(set (match_operand:P 0 "memory_operand" "=m")
17932 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17933 (set (match_scratch:P 2 "=&r") (const_int 0))
17934 (clobber (reg:CC FLAGS_REG))]
17936 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17937 [(set_attr "type" "multi")])
17939 (define_insn "stack_tls_protect_set_<mode>"
17940 [(set (match_operand:P 0 "memory_operand" "=m")
17941 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17942 UNSPEC_SP_TLS_SET))
17943 (set (match_scratch:P 2 "=&r") (const_int 0))
17944 (clobber (reg:CC FLAGS_REG))]
17946 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17947 [(set_attr "type" "multi")])
17949 (define_expand "stack_protect_test"
17950 [(match_operand 0 "memory_operand" "")
17951 (match_operand 1 "memory_operand" "")
17952 (match_operand 2 "" "")]
17955 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17957 rtx (*insn)(rtx, rtx, rtx);
17959 #ifdef TARGET_THREAD_SSP_OFFSET
17960 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17961 insn = (TARGET_64BIT
17962 ? gen_stack_tls_protect_test_di
17963 : gen_stack_tls_protect_test_si);
17965 insn = (TARGET_64BIT
17966 ? gen_stack_protect_test_di
17967 : gen_stack_protect_test_si);
17970 emit_insn (insn (flags, operands[0], operands[1]));
17972 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17973 flags, const0_rtx, operands[2]));
17977 (define_insn "stack_protect_test_<mode>"
17978 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17979 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17980 (match_operand:P 2 "memory_operand" "m")]
17982 (clobber (match_scratch:P 3 "=&r"))]
17984 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17985 [(set_attr "type" "multi")])
17987 (define_insn "stack_tls_protect_test_<mode>"
17988 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17989 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17990 (match_operand:P 2 "const_int_operand" "i")]
17991 UNSPEC_SP_TLS_TEST))
17992 (clobber (match_scratch:P 3 "=r"))]
17994 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17995 [(set_attr "type" "multi")])
17997 (define_insn "sse4_2_crc32<mode>"
17998 [(set (match_operand:SI 0 "register_operand" "=r")
18000 [(match_operand:SI 1 "register_operand" "0")
18001 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18003 "TARGET_SSE4_2 || TARGET_CRC32"
18004 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18005 [(set_attr "type" "sselog1")
18006 (set_attr "prefix_rep" "1")
18007 (set_attr "prefix_extra" "1")
18008 (set (attr "prefix_data16")
18009 (if_then_else (match_operand:HI 2 "" "")
18011 (const_string "*")))
18012 (set (attr "prefix_rex")
18013 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18015 (const_string "*")))
18016 (set_attr "mode" "SI")])
18018 (define_insn "sse4_2_crc32di"
18019 [(set (match_operand:DI 0 "register_operand" "=r")
18021 [(match_operand:DI 1 "register_operand" "0")
18022 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18024 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18025 "crc32{q}\t{%2, %0|%0, %2}"
18026 [(set_attr "type" "sselog1")
18027 (set_attr "prefix_rep" "1")
18028 (set_attr "prefix_extra" "1")
18029 (set_attr "mode" "DI")])
18031 (define_expand "rdpmc"
18032 [(match_operand:DI 0 "register_operand" "")
18033 (match_operand:SI 1 "register_operand" "")]
18036 rtx reg = gen_reg_rtx (DImode);
18039 /* Force operand 1 into ECX. */
18040 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18041 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18042 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18047 rtvec vec = rtvec_alloc (2);
18048 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18049 rtx upper = gen_reg_rtx (DImode);
18050 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18051 gen_rtvec (1, const0_rtx),
18053 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18054 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18056 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18057 NULL, 1, OPTAB_DIRECT);
18058 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18062 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18063 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18067 (define_insn "*rdpmc"
18068 [(set (match_operand:DI 0 "register_operand" "=A")
18069 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18073 [(set_attr "type" "other")
18074 (set_attr "length" "2")])
18076 (define_insn "*rdpmc_rex64"
18077 [(set (match_operand:DI 0 "register_operand" "=a")
18078 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18080 (set (match_operand:DI 1 "register_operand" "=d")
18081 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18084 [(set_attr "type" "other")
18085 (set_attr "length" "2")])
18087 (define_expand "rdtsc"
18088 [(set (match_operand:DI 0 "register_operand" "")
18089 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18094 rtvec vec = rtvec_alloc (2);
18095 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18096 rtx upper = gen_reg_rtx (DImode);
18097 rtx lower = gen_reg_rtx (DImode);
18098 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18099 gen_rtvec (1, const0_rtx),
18101 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18102 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18104 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18105 NULL, 1, OPTAB_DIRECT);
18106 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18108 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18113 (define_insn "*rdtsc"
18114 [(set (match_operand:DI 0 "register_operand" "=A")
18115 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18118 [(set_attr "type" "other")
18119 (set_attr "length" "2")])
18121 (define_insn "*rdtsc_rex64"
18122 [(set (match_operand:DI 0 "register_operand" "=a")
18123 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18124 (set (match_operand:DI 1 "register_operand" "=d")
18125 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18128 [(set_attr "type" "other")
18129 (set_attr "length" "2")])
18131 (define_expand "rdtscp"
18132 [(match_operand:DI 0 "register_operand" "")
18133 (match_operand:SI 1 "memory_operand" "")]
18136 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18137 gen_rtvec (1, const0_rtx),
18139 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18140 gen_rtvec (1, const0_rtx),
18142 rtx reg = gen_reg_rtx (DImode);
18143 rtx tmp = gen_reg_rtx (SImode);
18147 rtvec vec = rtvec_alloc (3);
18148 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18149 rtx upper = gen_reg_rtx (DImode);
18150 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18151 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18152 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18154 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18155 NULL, 1, OPTAB_DIRECT);
18156 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18161 rtvec vec = rtvec_alloc (2);
18162 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18163 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18164 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18167 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18168 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18172 (define_insn "*rdtscp"
18173 [(set (match_operand:DI 0 "register_operand" "=A")
18174 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18175 (set (match_operand:SI 1 "register_operand" "=c")
18176 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18179 [(set_attr "type" "other")
18180 (set_attr "length" "3")])
18182 (define_insn "*rdtscp_rex64"
18183 [(set (match_operand:DI 0 "register_operand" "=a")
18184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18185 (set (match_operand:DI 1 "register_operand" "=d")
18186 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18187 (set (match_operand:SI 2 "register_operand" "=c")
18188 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18191 [(set_attr "type" "other")
18192 (set_attr "length" "3")])
18194 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18196 ;; LWP instructions
18198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18200 (define_expand "lwp_llwpcb"
18201 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18202 UNSPECV_LLWP_INTRINSIC)]
18205 (define_insn "*lwp_llwpcb<mode>1"
18206 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18207 UNSPECV_LLWP_INTRINSIC)]
18210 [(set_attr "type" "lwp")
18211 (set_attr "mode" "<MODE>")
18212 (set_attr "length" "5")])
18214 (define_expand "lwp_slwpcb"
18215 [(set (match_operand 0 "register_operand" "=r")
18216 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18220 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18222 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18226 (define_insn "lwp_slwpcb<mode>"
18227 [(set (match_operand:P 0 "register_operand" "=r")
18228 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18231 [(set_attr "type" "lwp")
18232 (set_attr "mode" "<MODE>")
18233 (set_attr "length" "5")])
18235 (define_expand "lwp_lwpval<mode>3"
18236 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18237 (match_operand:SI 2 "nonimmediate_operand" "rm")
18238 (match_operand:SI 3 "const_int_operand" "i")]
18239 UNSPECV_LWPVAL_INTRINSIC)]
18241 "/* Avoid unused variable warning. */
18244 (define_insn "*lwp_lwpval<mode>3_1"
18245 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18246 (match_operand:SI 1 "nonimmediate_operand" "rm")
18247 (match_operand:SI 2 "const_int_operand" "i")]
18248 UNSPECV_LWPVAL_INTRINSIC)]
18250 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18251 [(set_attr "type" "lwp")
18252 (set_attr "mode" "<MODE>")
18253 (set (attr "length")
18254 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18256 (define_expand "lwp_lwpins<mode>3"
18257 [(set (reg:CCC FLAGS_REG)
18258 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18259 (match_operand:SI 2 "nonimmediate_operand" "rm")
18260 (match_operand:SI 3 "const_int_operand" "i")]
18261 UNSPECV_LWPINS_INTRINSIC))
18262 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18263 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18266 (define_insn "*lwp_lwpins<mode>3_1"
18267 [(set (reg:CCC FLAGS_REG)
18268 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18269 (match_operand:SI 1 "nonimmediate_operand" "rm")
18270 (match_operand:SI 2 "const_int_operand" "i")]
18271 UNSPECV_LWPINS_INTRINSIC))]
18273 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18274 [(set_attr "type" "lwp")
18275 (set_attr "mode" "<MODE>")
18276 (set (attr "length")
18277 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18279 (define_insn "rdfsbase<mode>"
18280 [(set (match_operand:SWI48 0 "register_operand" "=r")
18281 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18282 "TARGET_64BIT && TARGET_FSGSBASE"
18284 [(set_attr "type" "other")
18285 (set_attr "prefix_extra" "2")])
18287 (define_insn "rdgsbase<mode>"
18288 [(set (match_operand:SWI48 0 "register_operand" "=r")
18289 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18290 "TARGET_64BIT && TARGET_FSGSBASE"
18292 [(set_attr "type" "other")
18293 (set_attr "prefix_extra" "2")])
18295 (define_insn "wrfsbase<mode>"
18296 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18298 "TARGET_64BIT && TARGET_FSGSBASE"
18300 [(set_attr "type" "other")
18301 (set_attr "prefix_extra" "2")])
18303 (define_insn "wrgsbase<mode>"
18304 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18306 "TARGET_64BIT && TARGET_FSGSBASE"
18308 [(set_attr "type" "other")
18309 (set_attr "prefix_extra" "2")])
18311 (define_insn "rdrand<mode>_1"
18312 [(set (match_operand:SWI248 0 "register_operand" "=r")
18313 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18314 (set (reg:CCC FLAGS_REG)
18315 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18318 [(set_attr "type" "other")
18319 (set_attr "prefix_extra" "1")])
18323 (include "sync.md")