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 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
132 UNSPEC_MS_TO_SYSV_CALL
134 ;; Generic math support
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
139 ;; x87 Floating point
155 UNSPEC_FRNDINT_MASK_PM
159 ;; x87 Double output FP
191 ;; For SSE4.1 support
201 ;; For SSE4.2 support
208 UNSPEC_XOP_UNSIGNED_CMP
219 UNSPEC_AESKEYGENASSIST
221 ;; 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, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
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, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
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 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
716 (define_code_iterator plusminus [plus minus])
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
793 ;; 64bit single word integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
796 ;; 64bit single word integer modes without QImode and HImode.
797 (define_mode_iterator SWI48x [SI DI])
799 ;; Single word integer modes.
800 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
802 ;; Single word integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
805 ;; Single word integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
808 ;; Single word integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
811 ;; Single word integer modes without QImode.
812 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
814 ;; Single word integer modes without QImode and HImode.
815 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
817 ;; All math-dependant single and double word integer modes.
818 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
819 (HI "TARGET_HIMODE_MATH")
820 SI DI (TI "TARGET_64BIT")])
822 ;; Math-dependant single word integer modes.
823 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
824 (HI "TARGET_HIMODE_MATH")
825 SI (DI "TARGET_64BIT")])
827 ;; Math-dependant single word integer modes without DImode.
828 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
829 (HI "TARGET_HIMODE_MATH")
832 ;; Math-dependant single word integer modes without QImode.
833 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
834 SI (DI "TARGET_64BIT")])
836 ;; Double word integer modes.
837 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
838 (TI "TARGET_64BIT")])
840 ;; Double word integer modes as mode attribute.
841 (define_mode_attr DWI [(SI "DI") (DI "TI")])
842 (define_mode_attr dwi [(SI "di") (DI "ti")])
844 ;; Half mode for double word integer modes.
845 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
846 (DI "TARGET_64BIT")])
848 ;; Instruction suffix for integer modes.
849 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
851 ;; Pointer size prefix for integer modes (Intel asm dialect)
852 (define_mode_attr iptrsize [(QI "BYTE")
857 ;; Register class for integer modes.
858 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
860 ;; Immediate operand constraint for integer modes.
861 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
863 ;; General operand constraint for word modes.
864 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
866 ;; Immediate operand constraint for double integer modes.
867 (define_mode_attr di [(SI "iF") (DI "e")])
869 ;; Immediate operand constraint for shifts.
870 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
872 ;; General operand predicate for integer modes.
873 (define_mode_attr general_operand
874 [(QI "general_operand")
875 (HI "general_operand")
876 (SI "general_operand")
877 (DI "x86_64_general_operand")
878 (TI "x86_64_general_operand")])
880 ;; General sign/zero extend operand predicate for integer modes.
881 (define_mode_attr general_szext_operand
882 [(QI "general_operand")
883 (HI "general_operand")
884 (SI "general_operand")
885 (DI "x86_64_szext_general_operand")])
887 ;; Immediate operand predicate for integer modes.
888 (define_mode_attr immediate_operand
889 [(QI "immediate_operand")
890 (HI "immediate_operand")
891 (SI "immediate_operand")
892 (DI "x86_64_immediate_operand")])
894 ;; Nonmemory operand predicate for integer modes.
895 (define_mode_attr nonmemory_operand
896 [(QI "nonmemory_operand")
897 (HI "nonmemory_operand")
898 (SI "nonmemory_operand")
899 (DI "x86_64_nonmemory_operand")])
901 ;; Operand predicate for shifts.
902 (define_mode_attr shift_operand
903 [(QI "nonimmediate_operand")
904 (HI "nonimmediate_operand")
905 (SI "nonimmediate_operand")
906 (DI "shiftdi_operand")
907 (TI "register_operand")])
909 ;; Operand predicate for shift argument.
910 (define_mode_attr shift_immediate_operand
911 [(QI "const_1_to_31_operand")
912 (HI "const_1_to_31_operand")
913 (SI "const_1_to_31_operand")
914 (DI "const_1_to_63_operand")])
916 ;; Input operand predicate for arithmetic left shifts.
917 (define_mode_attr ashl_input_operand
918 [(QI "nonimmediate_operand")
919 (HI "nonimmediate_operand")
920 (SI "nonimmediate_operand")
921 (DI "ashldi_input_operand")
922 (TI "reg_or_pm1_operand")])
924 ;; SSE and x87 SFmode and DFmode floating point modes
925 (define_mode_iterator MODEF [SF DF])
927 ;; All x87 floating point modes
928 (define_mode_iterator X87MODEF [SF DF XF])
930 ;; All integer modes handled by x87 fisttp operator.
931 (define_mode_iterator X87MODEI [HI SI DI])
933 ;; All integer modes handled by integer x87 operators.
934 (define_mode_iterator X87MODEI12 [HI SI])
936 ;; All integer modes handled by SSE cvtts?2si* operators.
937 (define_mode_iterator SSEMODEI24 [SI DI])
939 ;; SSE instruction suffix for various modes
940 (define_mode_attr ssemodesuffix
942 (V8SF "ps") (V4DF "pd")
943 (V4SF "ps") (V2DF "pd")
944 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
947 ;; SSE vector suffix for floating point modes
948 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
950 ;; SSE vector mode corresponding to a scalar mode
951 (define_mode_attr ssevecmode
952 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
954 ;; Instruction suffix for REX 64bit operators.
955 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
957 ;; This mode iterator allows :P to be used for patterns that operate on
958 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
959 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
961 ;; Scheduling descriptions
963 (include "pentium.md")
966 (include "athlon.md")
967 (include "bdver1.md")
973 ;; Operand and operator predicates and constraints
975 (include "predicates.md")
976 (include "constraints.md")
979 ;; Compare and branch/compare and store instructions.
981 (define_expand "cbranch<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
984 (match_operand:SDWIM 2 "<general_operand>" "")))
985 (set (pc) (if_then_else
986 (match_operator 0 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)])
988 (label_ref (match_operand 3 "" ""))
992 if (MEM_P (operands[1]) && MEM_P (operands[2]))
993 operands[1] = force_reg (<MODE>mode, operands[1]);
994 ix86_expand_branch (GET_CODE (operands[0]),
995 operands[1], operands[2], operands[3]);
999 (define_expand "cstore<mode>4"
1000 [(set (reg:CC FLAGS_REG)
1001 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1002 (match_operand:SWIM 3 "<general_operand>" "")))
1003 (set (match_operand:QI 0 "register_operand" "")
1004 (match_operator 1 "ordered_comparison_operator"
1005 [(reg:CC FLAGS_REG) (const_int 0)]))]
1008 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1009 operands[2] = force_reg (<MODE>mode, operands[2]);
1010 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1011 operands[2], operands[3]);
1015 (define_expand "cmp<mode>_1"
1016 [(set (reg:CC FLAGS_REG)
1017 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1018 (match_operand:SWI48 1 "<general_operand>" "")))])
1020 (define_insn "*cmp<mode>_ccno_1"
1021 [(set (reg FLAGS_REG)
1022 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1023 (match_operand:SWI 1 "const0_operand" "")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1026 test{<imodesuffix>}\t%0, %0
1027 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "test,icmp")
1029 (set_attr "length_immediate" "0,1")
1030 (set_attr "mode" "<MODE>")])
1032 (define_insn "*cmp<mode>_1"
1033 [(set (reg FLAGS_REG)
1034 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1036 "ix86_match_ccmode (insn, CCmode)"
1037 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "<MODE>")])
1041 (define_insn "*cmp<mode>_minus_1"
1042 [(set (reg FLAGS_REG)
1044 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1045 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1047 "ix86_match_ccmode (insn, CCGOCmode)"
1048 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "<MODE>")])
1052 (define_insn "*cmpqi_ext_1"
1053 [(set (reg FLAGS_REG)
1055 (match_operand:QI 0 "general_operand" "Qm")
1058 (match_operand 1 "ext_register_operand" "Q")
1060 (const_int 8)) 0)))]
1061 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1062 "cmp{b}\t{%h1, %0|%0, %h1}"
1063 [(set_attr "type" "icmp")
1064 (set_attr "mode" "QI")])
1066 (define_insn "*cmpqi_ext_1_rex64"
1067 [(set (reg FLAGS_REG)
1069 (match_operand:QI 0 "register_operand" "Q")
1072 (match_operand 1 "ext_register_operand" "Q")
1074 (const_int 8)) 0)))]
1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%h1, %0|%0, %h1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "mode" "QI")])
1080 (define_insn "*cmpqi_ext_2"
1081 [(set (reg FLAGS_REG)
1085 (match_operand 0 "ext_register_operand" "Q")
1088 (match_operand:QI 1 "const0_operand" "")))]
1089 "ix86_match_ccmode (insn, CCNOmode)"
1091 [(set_attr "type" "test")
1092 (set_attr "length_immediate" "0")
1093 (set_attr "mode" "QI")])
1095 (define_expand "cmpqi_ext_3"
1096 [(set (reg:CC FLAGS_REG)
1100 (match_operand 0 "ext_register_operand" "")
1103 (match_operand:QI 1 "immediate_operand" "")))])
1105 (define_insn "*cmpqi_ext_3_insn"
1106 [(set (reg FLAGS_REG)
1110 (match_operand 0 "ext_register_operand" "Q")
1113 (match_operand:QI 1 "general_operand" "Qmn")))]
1114 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1115 "cmp{b}\t{%1, %h0|%h0, %1}"
1116 [(set_attr "type" "icmp")
1117 (set_attr "modrm" "1")
1118 (set_attr "mode" "QI")])
1120 (define_insn "*cmpqi_ext_3_insn_rex64"
1121 [(set (reg FLAGS_REG)
1125 (match_operand 0 "ext_register_operand" "Q")
1128 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1129 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1130 "cmp{b}\t{%1, %h0|%h0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "modrm" "1")
1133 (set_attr "mode" "QI")])
1135 (define_insn "*cmpqi_ext_4"
1136 [(set (reg FLAGS_REG)
1140 (match_operand 0 "ext_register_operand" "Q")
1145 (match_operand 1 "ext_register_operand" "Q")
1147 (const_int 8)) 0)))]
1148 "ix86_match_ccmode (insn, CCmode)"
1149 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1150 [(set_attr "type" "icmp")
1151 (set_attr "mode" "QI")])
1153 ;; These implement float point compares.
1154 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1155 ;; which would allow mix and match FP modes on the compares. Which is what
1156 ;; the old patterns did, but with many more of them.
1158 (define_expand "cbranchxf4"
1159 [(set (reg:CC FLAGS_REG)
1160 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1161 (match_operand:XF 2 "nonmemory_operand" "")))
1162 (set (pc) (if_then_else
1163 (match_operator 0 "ix86_fp_comparison_operator"
1166 (label_ref (match_operand 3 "" ""))
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1175 (define_expand "cstorexf4"
1176 [(set (reg:CC FLAGS_REG)
1177 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1178 (match_operand:XF 3 "nonmemory_operand" "")))
1179 (set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "ix86_fp_comparison_operator"
1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186 operands[2], operands[3]);
1190 (define_expand "cbranch<mode>4"
1191 [(set (reg:CC FLAGS_REG)
1192 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1193 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1194 (set (pc) (if_then_else
1195 (match_operator 0 "ix86_fp_comparison_operator"
1198 (label_ref (match_operand 3 "" ""))
1200 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1202 ix86_expand_branch (GET_CODE (operands[0]),
1203 operands[1], operands[2], operands[3]);
1207 (define_expand "cstore<mode>4"
1208 [(set (reg:CC FLAGS_REG)
1209 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1210 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1211 (set (match_operand:QI 0 "register_operand" "")
1212 (match_operator 1 "ix86_fp_comparison_operator"
1215 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1217 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1218 operands[2], operands[3]);
1222 (define_expand "cbranchcc4"
1223 [(set (pc) (if_then_else
1224 (match_operator 0 "comparison_operator"
1225 [(match_operand 1 "flags_reg_operand" "")
1226 (match_operand 2 "const0_operand" "")])
1227 (label_ref (match_operand 3 "" ""))
1231 ix86_expand_branch (GET_CODE (operands[0]),
1232 operands[1], operands[2], operands[3]);
1236 (define_expand "cstorecc4"
1237 [(set (match_operand:QI 0 "register_operand" "")
1238 (match_operator 1 "comparison_operator"
1239 [(match_operand 2 "flags_reg_operand" "")
1240 (match_operand 3 "const0_operand" "")]))]
1243 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244 operands[2], operands[3]);
1249 ;; FP compares, step 1:
1250 ;; Set the FP condition codes.
1252 ;; CCFPmode compare with exceptions
1253 ;; CCFPUmode compare with no exceptions
1255 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1256 ;; used to manage the reg stack popping would not be preserved.
1258 (define_insn "*cmpfp_0"
1259 [(set (match_operand:HI 0 "register_operand" "=a")
1262 (match_operand 1 "register_operand" "f")
1263 (match_operand 2 "const0_operand" ""))]
1265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1266 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1267 "* return output_fp_compare (insn, operands, false, false);"
1268 [(set_attr "type" "multi")
1269 (set_attr "unit" "i387")
1271 (cond [(match_operand:SF 1 "" "")
1273 (match_operand:DF 1 "" "")
1276 (const_string "XF")))])
1278 (define_insn_and_split "*cmpfp_0_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1281 (match_operand 1 "register_operand" "f")
1282 (match_operand 2 "const0_operand" "")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1284 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1285 && TARGET_SAHF && !TARGET_CMOVE
1286 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1288 "&& reload_completed"
1291 [(compare:CCFP (match_dup 1)(match_dup 2))]
1293 (set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1296 [(set_attr "type" "multi")
1297 (set_attr "unit" "i387")
1299 (cond [(match_operand:SF 1 "" "")
1301 (match_operand:DF 1 "" "")
1304 (const_string "XF")))])
1306 (define_insn "*cmpfp_xf"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1310 (match_operand:XF 1 "register_operand" "f")
1311 (match_operand:XF 2 "register_operand" "f"))]
1314 "* return output_fp_compare (insn, operands, false, false);"
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "XF")])
1319 (define_insn_and_split "*cmpfp_xf_cc"
1320 [(set (reg:CCFP FLAGS_REG)
1322 (match_operand:XF 1 "register_operand" "f")
1323 (match_operand:XF 2 "register_operand" "f")))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1326 && TARGET_SAHF && !TARGET_CMOVE"
1328 "&& reload_completed"
1331 [(compare:CCFP (match_dup 1)(match_dup 2))]
1333 (set (reg:CC FLAGS_REG)
1334 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1336 [(set_attr "type" "multi")
1337 (set_attr "unit" "i387")
1338 (set_attr "mode" "XF")])
1340 (define_insn "*cmpfp_<mode>"
1341 [(set (match_operand:HI 0 "register_operand" "=a")
1344 (match_operand:MODEF 1 "register_operand" "f")
1345 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1348 "* return output_fp_compare (insn, operands, false, false);"
1349 [(set_attr "type" "multi")
1350 (set_attr "unit" "i387")
1351 (set_attr "mode" "<MODE>")])
1353 (define_insn_and_split "*cmpfp_<mode>_cc"
1354 [(set (reg:CCFP FLAGS_REG)
1356 (match_operand:MODEF 1 "register_operand" "f")
1357 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360 && TARGET_SAHF && !TARGET_CMOVE"
1362 "&& reload_completed"
1365 [(compare:CCFP (match_dup 1)(match_dup 2))]
1367 (set (reg:CC FLAGS_REG)
1368 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1370 [(set_attr "type" "multi")
1371 (set_attr "unit" "i387")
1372 (set_attr "mode" "<MODE>")])
1374 (define_insn "*cmpfp_u"
1375 [(set (match_operand:HI 0 "register_operand" "=a")
1378 (match_operand 1 "register_operand" "f")
1379 (match_operand 2 "register_operand" "f"))]
1381 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1382 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1383 "* return output_fp_compare (insn, operands, false, true);"
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1387 (cond [(match_operand:SF 1 "" "")
1389 (match_operand:DF 1 "" "")
1392 (const_string "XF")))])
1394 (define_insn_and_split "*cmpfp_u_cc"
1395 [(set (reg:CCFPU FLAGS_REG)
1397 (match_operand 1 "register_operand" "f")
1398 (match_operand 2 "register_operand" "f")))
1399 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && TARGET_SAHF && !TARGET_CMOVE
1402 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1404 "&& reload_completed"
1407 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1409 (set (reg:CC FLAGS_REG)
1410 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1415 (cond [(match_operand:SF 1 "" "")
1417 (match_operand:DF 1 "" "")
1420 (const_string "XF")))])
1422 (define_insn "*cmpfp_<mode>"
1423 [(set (match_operand:HI 0 "register_operand" "=a")
1426 (match_operand 1 "register_operand" "f")
1427 (match_operator 3 "float_operator"
1428 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1430 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1431 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1432 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1433 "* return output_fp_compare (insn, operands, false, false);"
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "fp_int_src" "true")
1437 (set_attr "mode" "<MODE>")])
1439 (define_insn_and_split "*cmpfp_<mode>_cc"
1440 [(set (reg:CCFP FLAGS_REG)
1442 (match_operand 1 "register_operand" "f")
1443 (match_operator 3 "float_operator"
1444 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1445 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447 && TARGET_SAHF && !TARGET_CMOVE
1448 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1449 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1451 "&& reload_completed"
1456 (match_op_dup 3 [(match_dup 2)]))]
1458 (set (reg:CC FLAGS_REG)
1459 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1461 [(set_attr "type" "multi")
1462 (set_attr "unit" "i387")
1463 (set_attr "fp_int_src" "true")
1464 (set_attr "mode" "<MODE>")])
1466 ;; FP compares, step 2
1467 ;; Move the fpsw to ax.
1469 (define_insn "x86_fnstsw_1"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1471 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1474 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1475 (set_attr "mode" "SI")
1476 (set_attr "unit" "i387")])
1478 ;; FP compares, step 3
1479 ;; Get ax into flags, general case.
1481 (define_insn "x86_sahf_1"
1482 [(set (reg:CC FLAGS_REG)
1483 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1487 #ifndef HAVE_AS_IX86_SAHF
1489 return ASM_BYTE "0x9e";
1494 [(set_attr "length" "1")
1495 (set_attr "athlon_decode" "vector")
1496 (set_attr "amdfam10_decode" "direct")
1497 (set_attr "bdver1_decode" "direct")
1498 (set_attr "mode" "SI")])
1500 ;; Pentium Pro can do steps 1 through 3 in one go.
1501 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1502 (define_insn "*cmpfp_i_mixed"
1503 [(set (reg:CCFP FLAGS_REG)
1504 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1505 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1506 "TARGET_MIX_SSE_I387
1507 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1509 "* return output_fp_compare (insn, operands, true, false);"
1510 [(set_attr "type" "fcmp,ssecomi")
1511 (set_attr "prefix" "orig,maybe_vex")
1513 (if_then_else (match_operand:SF 1 "" "")
1515 (const_string "DF")))
1516 (set (attr "prefix_rep")
1517 (if_then_else (eq_attr "type" "ssecomi")
1519 (const_string "*")))
1520 (set (attr "prefix_data16")
1521 (cond [(eq_attr "type" "fcmp")
1523 (eq_attr "mode" "DF")
1526 (const_string "0")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")
1529 (set_attr "bdver1_decode" "double")])
1531 (define_insn "*cmpfp_i_sse"
1532 [(set (reg:CCFP FLAGS_REG)
1533 (compare:CCFP (match_operand 0 "register_operand" "x")
1534 (match_operand 1 "nonimmediate_operand" "xm")))]
1536 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1537 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1538 "* return output_fp_compare (insn, operands, true, false);"
1539 [(set_attr "type" "ssecomi")
1540 (set_attr "prefix" "maybe_vex")
1542 (if_then_else (match_operand:SF 1 "" "")
1544 (const_string "DF")))
1545 (set_attr "prefix_rep" "0")
1546 (set (attr "prefix_data16")
1547 (if_then_else (eq_attr "mode" "DF")
1549 (const_string "0")))
1550 (set_attr "athlon_decode" "vector")
1551 (set_attr "amdfam10_decode" "direct")
1552 (set_attr "bdver1_decode" "double")])
1554 (define_insn "*cmpfp_i_i387"
1555 [(set (reg:CCFP FLAGS_REG)
1556 (compare:CCFP (match_operand 0 "register_operand" "f")
1557 (match_operand 1 "register_operand" "f")))]
1558 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1560 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1561 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1562 "* return output_fp_compare (insn, operands, true, false);"
1563 [(set_attr "type" "fcmp")
1565 (cond [(match_operand:SF 1 "" "")
1567 (match_operand:DF 1 "" "")
1570 (const_string "XF")))
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "double")])
1575 (define_insn "*cmpfp_iu_mixed"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1578 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1579 "TARGET_MIX_SSE_I387
1580 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1582 "* return output_fp_compare (insn, operands, true, true);"
1583 [(set_attr "type" "fcmp,ssecomi")
1584 (set_attr "prefix" "orig,maybe_vex")
1586 (if_then_else (match_operand:SF 1 "" "")
1588 (const_string "DF")))
1589 (set (attr "prefix_rep")
1590 (if_then_else (eq_attr "type" "ssecomi")
1592 (const_string "*")))
1593 (set (attr "prefix_data16")
1594 (cond [(eq_attr "type" "fcmp")
1596 (eq_attr "mode" "DF")
1599 (const_string "0")))
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "direct")
1602 (set_attr "bdver1_decode" "double")])
1604 (define_insn "*cmpfp_iu_sse"
1605 [(set (reg:CCFPU FLAGS_REG)
1606 (compare:CCFPU (match_operand 0 "register_operand" "x")
1607 (match_operand 1 "nonimmediate_operand" "xm")))]
1609 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1610 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1611 "* return output_fp_compare (insn, operands, true, true);"
1612 [(set_attr "type" "ssecomi")
1613 (set_attr "prefix" "maybe_vex")
1615 (if_then_else (match_operand:SF 1 "" "")
1617 (const_string "DF")))
1618 (set_attr "prefix_rep" "0")
1619 (set (attr "prefix_data16")
1620 (if_then_else (eq_attr "mode" "DF")
1622 (const_string "0")))
1623 (set_attr "athlon_decode" "vector")
1624 (set_attr "amdfam10_decode" "direct")
1625 (set_attr "bdver1_decode" "double")])
1627 (define_insn "*cmpfp_iu_387"
1628 [(set (reg:CCFPU FLAGS_REG)
1629 (compare:CCFPU (match_operand 0 "register_operand" "f")
1630 (match_operand 1 "register_operand" "f")))]
1631 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1633 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1634 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1635 "* return output_fp_compare (insn, operands, true, true);"
1636 [(set_attr "type" "fcmp")
1638 (cond [(match_operand:SF 1 "" "")
1640 (match_operand:DF 1 "" "")
1643 (const_string "XF")))
1644 (set_attr "athlon_decode" "vector")
1645 (set_attr "amdfam10_decode" "direct")
1646 (set_attr "bdver1_decode" "direct")])
1648 ;; Push/pop instructions.
1650 (define_insn "*push<mode>2"
1651 [(set (match_operand:DWI 0 "push_operand" "=<")
1652 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1657 [(set (match_operand:TI 0 "push_operand" "")
1658 (match_operand:TI 1 "general_operand" ""))]
1659 "TARGET_64BIT && reload_completed
1660 && !SSE_REG_P (operands[1])"
1662 "ix86_split_long_move (operands); DONE;")
1664 (define_insn "*pushdi2_rex64"
1665 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1666 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1671 [(set_attr "type" "push,multi")
1672 (set_attr "mode" "DI")])
1674 ;; Convert impossible pushes of immediate to existing instructions.
1675 ;; First try to get scratch register and go through it. In case this
1676 ;; fails, push sign extended lower part first and then overwrite
1677 ;; upper part by 32bit move.
1679 [(match_scratch:DI 2 "r")
1680 (set (match_operand:DI 0 "push_operand" "")
1681 (match_operand:DI 1 "immediate_operand" ""))]
1682 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 2) (match_dup 1))
1685 (set (match_dup 0) (match_dup 2))])
1687 ;; We need to define this as both peepholer and splitter for case
1688 ;; peephole2 pass is not run.
1689 ;; "&& 1" is needed to keep it from matching the previous pattern.
1691 [(set (match_operand:DI 0 "push_operand" "")
1692 (match_operand:DI 1 "immediate_operand" ""))]
1693 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1694 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1695 [(set (match_dup 0) (match_dup 1))
1696 (set (match_dup 2) (match_dup 3))]
1698 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1700 operands[1] = gen_lowpart (DImode, operands[2]);
1701 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1706 [(set (match_operand:DI 0 "push_operand" "")
1707 (match_operand:DI 1 "immediate_operand" ""))]
1708 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1709 ? epilogue_completed : reload_completed)
1710 && !symbolic_operand (operands[1], DImode)
1711 && !x86_64_immediate_operand (operands[1], DImode)"
1712 [(set (match_dup 0) (match_dup 1))
1713 (set (match_dup 2) (match_dup 3))]
1715 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1717 operands[1] = gen_lowpart (DImode, operands[2]);
1718 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1723 [(set (match_operand:DI 0 "push_operand" "")
1724 (match_operand:DI 1 "general_operand" ""))]
1725 "!TARGET_64BIT && reload_completed
1726 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1728 "ix86_split_long_move (operands); DONE;")
1730 (define_insn "*pushsi2"
1731 [(set (match_operand:SI 0 "push_operand" "=<")
1732 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1735 [(set_attr "type" "push")
1736 (set_attr "mode" "SI")])
1738 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1739 ;; "push a byte/word". But actually we use pushl, which has the effect
1740 ;; of rounding the amount pushed up to a word.
1742 ;; For TARGET_64BIT we always round up to 8 bytes.
1743 (define_insn "*push<mode>2_rex64"
1744 [(set (match_operand:SWI124 0 "push_operand" "=X")
1745 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1748 [(set_attr "type" "push")
1749 (set_attr "mode" "DI")])
1751 (define_insn "*push<mode>2"
1752 [(set (match_operand:SWI12 0 "push_operand" "=X")
1753 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "SI")])
1759 (define_insn "*push<mode>2_prologue"
1760 [(set (match_operand:P 0 "push_operand" "=<")
1761 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1762 (clobber (mem:BLK (scratch)))]
1764 "push{<imodesuffix>}\t%1"
1765 [(set_attr "type" "push")
1766 (set_attr "mode" "<MODE>")])
1768 (define_insn "*pop<mode>1"
1769 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1770 (match_operand:P 1 "pop_operand" ">"))]
1772 "pop{<imodesuffix>}\t%0"
1773 [(set_attr "type" "pop")
1774 (set_attr "mode" "<MODE>")])
1776 (define_insn "*pop<mode>1_epilogue"
1777 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1778 (match_operand:P 1 "pop_operand" ">"))
1779 (clobber (mem:BLK (scratch)))]
1781 "pop{<imodesuffix>}\t%0"
1782 [(set_attr "type" "pop")
1783 (set_attr "mode" "<MODE>")])
1785 ;; Move instructions.
1787 (define_expand "movoi"
1788 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1789 (match_operand:OI 1 "general_operand" ""))]
1791 "ix86_expand_move (OImode, operands); DONE;")
1793 (define_expand "movti"
1794 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1795 (match_operand:TI 1 "nonimmediate_operand" ""))]
1796 "TARGET_64BIT || TARGET_SSE"
1799 ix86_expand_move (TImode, operands);
1800 else if (push_operand (operands[0], TImode))
1801 ix86_expand_push (TImode, operands[1]);
1803 ix86_expand_vector_move (TImode, operands);
1807 ;; This expands to what emit_move_complex would generate if we didn't
1808 ;; have a movti pattern. Having this avoids problems with reload on
1809 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1810 ;; to have around all the time.
1811 (define_expand "movcdi"
1812 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1813 (match_operand:CDI 1 "general_operand" ""))]
1816 if (push_operand (operands[0], CDImode))
1817 emit_move_complex_push (CDImode, operands[0], operands[1]);
1819 emit_move_complex_parts (operands[0], operands[1]);
1823 (define_expand "mov<mode>"
1824 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1825 (match_operand:SWI1248x 1 "general_operand" ""))]
1827 "ix86_expand_move (<MODE>mode, operands); DONE;")
1829 (define_insn "*mov<mode>_xor"
1830 [(set (match_operand:SWI48 0 "register_operand" "=r")
1831 (match_operand:SWI48 1 "const0_operand" ""))
1832 (clobber (reg:CC FLAGS_REG))]
1835 [(set_attr "type" "alu1")
1836 (set_attr "mode" "SI")
1837 (set_attr "length_immediate" "0")])
1839 (define_insn "*mov<mode>_or"
1840 [(set (match_operand:SWI48 0 "register_operand" "=r")
1841 (match_operand:SWI48 1 "const_int_operand" ""))
1842 (clobber (reg:CC FLAGS_REG))]
1844 && operands[1] == constm1_rtx"
1845 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1846 [(set_attr "type" "alu1")
1847 (set_attr "mode" "<MODE>")
1848 (set_attr "length_immediate" "1")])
1850 (define_insn "*movoi_internal_avx"
1851 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1852 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1853 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855 switch (which_alternative)
1858 return standard_sse_constant_opcode (insn, operands[1]);
1861 if (misaligned_operand (operands[0], OImode)
1862 || misaligned_operand (operands[1], OImode))
1863 return "vmovdqu\t{%1, %0|%0, %1}";
1865 return "vmovdqa\t{%1, %0|%0, %1}";
1870 [(set_attr "type" "sselog1,ssemov,ssemov")
1871 (set_attr "prefix" "vex")
1872 (set_attr "mode" "OI")])
1874 (define_insn "*movti_internal_rex64"
1875 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1876 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1877 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879 switch (which_alternative)
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1909 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912 (cond [(eq_attr "alternative" "2,3")
1914 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916 (const_string "V4SF")
1917 (const_string "TI"))
1918 (eq_attr "alternative" "4")
1920 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924 (const_string "V4SF")
1925 (const_string "TI"))]
1926 (const_string "DI")))])
1929 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1930 (match_operand:TI 1 "general_operand" ""))]
1932 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934 "ix86_split_long_move (operands); DONE;")
1936 (define_insn "*movti_internal_sse"
1937 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1938 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1939 "TARGET_SSE && !TARGET_64BIT
1940 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 switch (which_alternative)
1945 return standard_sse_constant_opcode (insn, operands[1]);
1948 /* TDmode values are passed as TImode on the stack. Moving them
1949 to stack may result in unaligned memory access. */
1950 if (misaligned_operand (operands[0], TImode)
1951 || misaligned_operand (operands[1], TImode))
1953 if (get_attr_mode (insn) == MODE_V4SF)
1954 return "%vmovups\t{%1, %0|%0, %1}";
1956 return "%vmovdqu\t{%1, %0|%0, %1}";
1960 if (get_attr_mode (insn) == MODE_V4SF)
1961 return "%vmovaps\t{%1, %0|%0, %1}";
1963 return "%vmovdqa\t{%1, %0|%0, %1}";
1969 [(set_attr "type" "sselog1,ssemov,ssemov")
1970 (set_attr "prefix" "maybe_vex")
1972 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1973 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1975 (const_string "V4SF")
1976 (and (eq_attr "alternative" "2")
1977 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1979 (const_string "V4SF")]
1980 (const_string "TI")))])
1982 (define_insn "*movdi_internal_rex64"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1985 (match_operand:DI 1 "general_operand"
1986 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1987 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 switch (get_attr_type (insn))
1992 if (SSE_REG_P (operands[0]))
1993 return "movq2dq\t{%1, %0|%0, %1}";
1995 return "movdq2q\t{%1, %0|%0, %1}";
1998 if (get_attr_mode (insn) == MODE_TI)
1999 return "%vmovdqa\t{%1, %0|%0, %1}";
2000 /* Handle broken assemblers that require movd instead of movq. */
2001 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2002 return "%vmovd\t{%1, %0|%0, %1}";
2004 return "%vmovq\t{%1, %0|%0, %1}";
2007 /* Handle broken assemblers that require movd instead of movq. */
2008 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2009 return "movd\t{%1, %0|%0, %1}";
2011 return "movq\t{%1, %0|%0, %1}";
2014 return standard_sse_constant_opcode (insn, operands[1]);
2017 return "pxor\t%0, %0";
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2026 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2027 if (get_attr_mode (insn) == MODE_SI)
2028 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029 else if (which_alternative == 2)
2030 return "movabs{q}\t{%1, %0|%0, %1}";
2032 return "mov{q}\t{%1, %0|%0, %1}";
2036 (cond [(eq_attr "alternative" "5")
2037 (const_string "mmx")
2038 (eq_attr "alternative" "6,7,8,9,10")
2039 (const_string "mmxmov")
2040 (eq_attr "alternative" "11")
2041 (const_string "sselog1")
2042 (eq_attr "alternative" "12,13,14,15,16")
2043 (const_string "ssemov")
2044 (eq_attr "alternative" "17,18")
2045 (const_string "ssecvt")
2046 (eq_attr "alternative" "4")
2047 (const_string "multi")
2048 (match_operand:DI 1 "pic_32bit_operand" "")
2049 (const_string "lea")
2051 (const_string "imov")))
2054 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2056 (const_string "*")))
2057 (set (attr "length_immediate")
2059 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2061 (const_string "*")))
2062 (set (attr "prefix_rex")
2063 (if_then_else (eq_attr "alternative" "7,9")
2065 (const_string "*")))
2066 (set (attr "prefix_data16")
2067 (if_then_else (eq_attr "alternative" "15")
2069 (const_string "*")))
2070 (set (attr "prefix")
2071 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2072 (const_string "maybe_vex")
2073 (const_string "orig")))
2074 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it. In case this
2078 ;; fails, move by 32bit parts.
2080 [(match_scratch:DI 2 "r")
2081 (set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 1))
2086 (set (match_dup 0) (match_dup 2))])
2088 ;; We need to define this as both peepholer and splitter for case
2089 ;; peephole2 pass is not run.
2090 ;; "&& 1" is needed to keep it from matching the previous pattern.
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2095 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2096 [(set (match_dup 2) (match_dup 3))
2097 (set (match_dup 4) (match_dup 5))]
2098 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2101 [(set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2104 ? epilogue_completed : reload_completed)
2105 && !symbolic_operand (operands[1], DImode)
2106 && !x86_64_immediate_operand (operands[1], DImode)"
2107 [(set (match_dup 2) (match_dup 3))
2108 (set (match_dup 4) (match_dup 5))]
2109 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2111 (define_insn "*movdi_internal"
2112 [(set (match_operand:DI 0 "nonimmediate_operand"
2113 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2114 (match_operand:DI 1 "general_operand"
2115 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2116 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2118 switch (get_attr_type (insn))
2121 if (SSE_REG_P (operands[0]))
2122 return "movq2dq\t{%1, %0|%0, %1}";
2124 return "movdq2q\t{%1, %0|%0, %1}";
2127 switch (get_attr_mode (insn))
2130 return "%vmovdqa\t{%1, %0|%0, %1}";
2132 return "%vmovq\t{%1, %0|%0, %1}";
2134 return "movaps\t{%1, %0|%0, %1}";
2136 return "movlps\t{%1, %0|%0, %1}";
2142 return "movq\t{%1, %0|%0, %1}";
2145 return standard_sse_constant_opcode (insn, operands[1]);
2148 return "pxor\t%0, %0";
2158 (if_then_else (eq_attr "alternative" "9,10,11,12")
2159 (const_string "noavx")
2160 (const_string "base")))
2162 (cond [(eq_attr "alternative" "0,1")
2163 (const_string "multi")
2164 (eq_attr "alternative" "2")
2165 (const_string "mmx")
2166 (eq_attr "alternative" "3,4")
2167 (const_string "mmxmov")
2168 (eq_attr "alternative" "5,9")
2169 (const_string "sselog1")
2170 (eq_attr "alternative" "13,14")
2171 (const_string "ssecvt")
2173 (const_string "ssemov")))
2174 (set (attr "prefix")
2175 (if_then_else (eq_attr "alternative" "5,6,7,8")
2176 (const_string "maybe_vex")
2177 (const_string "orig")))
2178 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2181 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2182 (match_operand:DI 1 "general_operand" ""))]
2183 "!TARGET_64BIT && reload_completed
2184 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2185 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2187 "ix86_split_long_move (operands); DONE;")
2189 (define_insn "*movsi_internal"
2190 [(set (match_operand:SI 0 "nonimmediate_operand"
2191 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2192 (match_operand:SI 1 "general_operand"
2193 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 switch (get_attr_type (insn))
2199 return standard_sse_constant_opcode (insn, operands[1]);
2202 switch (get_attr_mode (insn))
2205 return "%vmovdqa\t{%1, %0|%0, %1}";
2207 return "%vmovaps\t{%1, %0|%0, %1}";
2209 return "%vmovd\t{%1, %0|%0, %1}";
2211 return "%vmovss\t{%1, %0|%0, %1}";
2217 return "pxor\t%0, %0";
2220 if (get_attr_mode (insn) == MODE_DI)
2221 return "movq\t{%1, %0|%0, %1}";
2222 return "movd\t{%1, %0|%0, %1}";
2225 return "lea{l}\t{%a1, %0|%0, %a1}";
2228 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2229 return "mov{l}\t{%1, %0|%0, %1}";
2233 (cond [(eq_attr "alternative" "2")
2234 (const_string "mmx")
2235 (eq_attr "alternative" "3,4,5")
2236 (const_string "mmxmov")
2237 (eq_attr "alternative" "6")
2238 (const_string "sselog1")
2239 (eq_attr "alternative" "7,8,9,10,11")
2240 (const_string "ssemov")
2241 (match_operand:DI 1 "pic_32bit_operand" "")
2242 (const_string "lea")
2244 (const_string "imov")))
2245 (set (attr "prefix")
2246 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2247 (const_string "orig")
2248 (const_string "maybe_vex")))
2249 (set (attr "prefix_data16")
2250 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2252 (const_string "*")))
2254 (cond [(eq_attr "alternative" "2,3")
2256 (eq_attr "alternative" "6,7")
2258 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2259 (const_string "V4SF")
2260 (const_string "TI"))
2261 (and (eq_attr "alternative" "8,9,10,11")
2262 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2265 (const_string "SI")))])
2267 (define_insn "*movhi_internal"
2268 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2269 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2270 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2272 switch (get_attr_type (insn))
2275 /* movzwl is faster than movw on p2 due to partial word stalls,
2276 though not as fast as an aligned movl. */
2277 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2279 if (get_attr_mode (insn) == MODE_SI)
2280 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282 return "mov{w}\t{%1, %0|%0, %1}";
2286 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "0")
2290 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2292 (eq (symbol_ref "TARGET_HIMODE_MATH")
2294 (const_string "imov")
2295 (and (eq_attr "alternative" "1,2")
2296 (match_operand:HI 1 "aligned_operand" ""))
2297 (const_string "imov")
2298 (and (ne (symbol_ref "TARGET_MOVX")
2300 (eq_attr "alternative" "0,2"))
2301 (const_string "imovx")
2303 (const_string "imov")))
2305 (cond [(eq_attr "type" "imovx")
2307 (and (eq_attr "alternative" "1,2")
2308 (match_operand:HI 1 "aligned_operand" ""))
2310 (and (eq_attr "alternative" "0")
2311 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2313 (eq (symbol_ref "TARGET_HIMODE_MATH")
2317 (const_string "HI")))])
2319 ;; Situation is quite tricky about when to choose full sized (SImode) move
2320 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2321 ;; partial register dependency machines (such as AMD Athlon), where QImode
2322 ;; moves issue extra dependency and for partial register stalls machines
2323 ;; that don't use QImode patterns (and QImode move cause stall on the next
2326 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2327 ;; register stall machines with, where we use QImode instructions, since
2328 ;; partial register stall can be caused there. Then we use movzx.
2329 (define_insn "*movqi_internal"
2330 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2331 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2334 switch (get_attr_type (insn))
2337 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2338 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2340 if (get_attr_mode (insn) == MODE_SI)
2341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2343 return "mov{b}\t{%1, %0|%0, %1}";
2347 (cond [(and (eq_attr "alternative" "5")
2348 (not (match_operand:QI 1 "aligned_operand" "")))
2349 (const_string "imovx")
2350 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2352 (const_string "imov")
2353 (and (eq_attr "alternative" "3")
2354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2356 (eq (symbol_ref "TARGET_QIMODE_MATH")
2358 (const_string "imov")
2359 (eq_attr "alternative" "3,5")
2360 (const_string "imovx")
2361 (and (ne (symbol_ref "TARGET_MOVX")
2363 (eq_attr "alternative" "2"))
2364 (const_string "imovx")
2366 (const_string "imov")))
2368 (cond [(eq_attr "alternative" "3,4,5")
2370 (eq_attr "alternative" "6")
2372 (eq_attr "type" "imovx")
2374 (and (eq_attr "type" "imov")
2375 (and (eq_attr "alternative" "0,1")
2376 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2378 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2380 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2383 ;; Avoid partial register stalls when not using QImode arithmetic
2384 (and (eq_attr "type" "imov")
2385 (and (eq_attr "alternative" "0,1")
2386 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2388 (eq (symbol_ref "TARGET_QIMODE_MATH")
2392 (const_string "QI")))])
2394 ;; Stores and loads of ax to arbitrary constant address.
2395 ;; We fake an second form of instruction to force reload to load address
2396 ;; into register when rax is not available
2397 (define_insn "*movabs<mode>_1"
2398 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2399 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2400 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2402 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2403 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2404 [(set_attr "type" "imov")
2405 (set_attr "modrm" "0,*")
2406 (set_attr "length_address" "8,0")
2407 (set_attr "length_immediate" "0,*")
2408 (set_attr "memory" "store")
2409 (set_attr "mode" "<MODE>")])
2411 (define_insn "*movabs<mode>_2"
2412 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2413 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2414 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2416 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2417 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2418 [(set_attr "type" "imov")
2419 (set_attr "modrm" "0,*")
2420 (set_attr "length_address" "8,0")
2421 (set_attr "length_immediate" "0")
2422 (set_attr "memory" "load")
2423 (set_attr "mode" "<MODE>")])
2425 (define_insn "*swap<mode>"
2426 [(set (match_operand:SWI48 0 "register_operand" "+r")
2427 (match_operand:SWI48 1 "register_operand" "+r"))
2431 "xchg{<imodesuffix>}\t%1, %0"
2432 [(set_attr "type" "imov")
2433 (set_attr "mode" "<MODE>")
2434 (set_attr "pent_pair" "np")
2435 (set_attr "athlon_decode" "vector")
2436 (set_attr "amdfam10_decode" "double")
2437 (set_attr "bdver1_decode" "double")])
2439 (define_insn "*swap<mode>_1"
2440 [(set (match_operand:SWI12 0 "register_operand" "+r")
2441 (match_operand:SWI12 1 "register_operand" "+r"))
2444 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2446 [(set_attr "type" "imov")
2447 (set_attr "mode" "SI")
2448 (set_attr "pent_pair" "np")
2449 (set_attr "athlon_decode" "vector")
2450 (set_attr "amdfam10_decode" "double")
2451 (set_attr "bdver1_decode" "double")])
2453 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2454 ;; is disabled for AMDFAM10
2455 (define_insn "*swap<mode>_2"
2456 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2457 (match_operand:SWI12 1 "register_operand" "+<r>"))
2460 "TARGET_PARTIAL_REG_STALL"
2461 "xchg{<imodesuffix>}\t%1, %0"
2462 [(set_attr "type" "imov")
2463 (set_attr "mode" "<MODE>")
2464 (set_attr "pent_pair" "np")
2465 (set_attr "athlon_decode" "vector")])
2467 (define_expand "movstrict<mode>"
2468 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2469 (match_operand:SWI12 1 "general_operand" ""))]
2472 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2474 if (GET_CODE (operands[0]) == SUBREG
2475 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2477 /* Don't generate memory->memory moves, go through a register */
2478 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2479 operands[1] = force_reg (<MODE>mode, operands[1]);
2482 (define_insn "*movstrict<mode>_1"
2483 [(set (strict_low_part
2484 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2485 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2486 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2487 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2488 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2489 [(set_attr "type" "imov")
2490 (set_attr "mode" "<MODE>")])
2492 (define_insn "*movstrict<mode>_xor"
2493 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2494 (match_operand:SWI12 1 "const0_operand" ""))
2495 (clobber (reg:CC FLAGS_REG))]
2497 "xor{<imodesuffix>}\t%0, %0"
2498 [(set_attr "type" "alu1")
2499 (set_attr "mode" "<MODE>")
2500 (set_attr "length_immediate" "0")])
2502 (define_insn "*mov<mode>_extv_1"
2503 [(set (match_operand:SWI24 0 "register_operand" "=R")
2504 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2508 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2509 [(set_attr "type" "imovx")
2510 (set_attr "mode" "SI")])
2512 (define_insn "*movqi_extv_1_rex64"
2513 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2514 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2519 switch (get_attr_type (insn))
2522 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2528 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2529 (ne (symbol_ref "TARGET_MOVX")
2531 (const_string "imovx")
2532 (const_string "imov")))
2534 (if_then_else (eq_attr "type" "imovx")
2536 (const_string "QI")))])
2538 (define_insn "*movqi_extv_1"
2539 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2540 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2545 switch (get_attr_type (insn))
2548 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2550 return "mov{b}\t{%h1, %0|%0, %h1}";
2554 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2555 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2558 (const_string "imovx")
2559 (const_string "imov")))
2561 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "QI")))])
2565 (define_insn "*mov<mode>_extzv_1"
2566 [(set (match_operand:SWI48 0 "register_operand" "=R")
2567 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2571 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2572 [(set_attr "type" "imovx")
2573 (set_attr "mode" "SI")])
2575 (define_insn "*movqi_extzv_2_rex64"
2576 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2578 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2583 switch (get_attr_type (insn))
2586 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2588 return "mov{b}\t{%h1, %0|%0, %h1}";
2592 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2593 (ne (symbol_ref "TARGET_MOVX")
2595 (const_string "imovx")
2596 (const_string "imov")))
2598 (if_then_else (eq_attr "type" "imovx")
2600 (const_string "QI")))])
2602 (define_insn "*movqi_extzv_2"
2603 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2605 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2610 switch (get_attr_type (insn))
2613 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2615 return "mov{b}\t{%h1, %0|%0, %h1}";
2619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2620 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2621 (ne (symbol_ref "TARGET_MOVX")
2623 (const_string "imovx")
2624 (const_string "imov")))
2626 (if_then_else (eq_attr "type" "imovx")
2628 (const_string "QI")))])
2630 (define_expand "mov<mode>_insv_1"
2631 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2634 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2636 (define_insn "*mov<mode>_insv_1_rex64"
2637 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2640 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2642 "mov{b}\t{%b1, %h0|%h0, %b1}"
2643 [(set_attr "type" "imov")
2644 (set_attr "mode" "QI")])
2646 (define_insn "*movsi_insv_1"
2647 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2650 (match_operand:SI 1 "general_operand" "Qmn"))]
2652 "mov{b}\t{%b1, %h0|%h0, %b1}"
2653 [(set_attr "type" "imov")
2654 (set_attr "mode" "QI")])
2656 (define_insn "*movqi_insv_2"
2657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2660 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2663 "mov{b}\t{%h1, %h0|%h0, %h1}"
2664 [(set_attr "type" "imov")
2665 (set_attr "mode" "QI")])
2667 ;; Floating point push instructions.
2669 (define_insn "*pushtf"
2670 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2671 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2674 /* This insn should be already split before reg-stack. */
2677 [(set_attr "type" "multi")
2678 (set_attr "unit" "sse,*,*")
2679 (set_attr "mode" "TF,SI,SI")])
2682 [(set (match_operand:TF 0 "push_operand" "")
2683 (match_operand:TF 1 "sse_reg_operand" ""))]
2684 "TARGET_SSE2 && reload_completed"
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2686 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2689 [(set (match_operand:TF 0 "push_operand" "")
2690 (match_operand:TF 1 "general_operand" ""))]
2691 "TARGET_SSE2 && reload_completed
2692 && !SSE_REG_P (operands[1])"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*pushxf"
2697 [(set (match_operand:XF 0 "push_operand" "=<,<")
2698 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2699 "optimize_function_for_speed_p (cfun)"
2701 /* This insn should be already split before reg-stack. */
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*")
2706 (set_attr "mode" "XF,SI")])
2708 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2710 ;; Pushing using integer instructions is longer except for constants
2711 ;; and direct memory references (assuming that any given constant is pushed
2712 ;; only once, but this ought to be handled elsewhere).
2714 (define_insn "*pushxf_nointeger"
2715 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2716 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2717 "optimize_function_for_size_p (cfun)"
2719 /* This insn should be already split before reg-stack. */
2722 [(set_attr "type" "multi")
2723 (set_attr "unit" "i387,*,*")
2724 (set_attr "mode" "XF,SI,SI")])
2727 [(set (match_operand:XF 0 "push_operand" "")
2728 (match_operand:XF 1 "fp_register_operand" ""))]
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2731 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2732 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2735 [(set (match_operand:XF 0 "push_operand" "")
2736 (match_operand:XF 1 "general_operand" ""))]
2738 && !FP_REG_P (operands[1])"
2740 "ix86_split_long_move (operands); DONE;")
2742 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2744 ;; On the average, pushdf using integers can be still shorter.
2746 (define_insn "*pushdf"
2747 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2748 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2751 /* This insn should be already split before reg-stack. */
2754 [(set_attr "type" "multi")
2755 (set_attr "unit" "i387,*,*")
2756 (set_attr "mode" "DF,SI,DF")])
2758 ;; %%% Kill this when call knows how to work this out.
2760 [(set (match_operand:DF 0 "push_operand" "")
2761 (match_operand:DF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2764 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2767 [(set (match_operand:DF 0 "push_operand" "")
2768 (match_operand:DF 1 "general_operand" ""))]
2770 && !ANY_FP_REG_P (operands[1])"
2772 "ix86_split_long_move (operands); DONE;")
2774 (define_insn "*pushsf_rex64"
2775 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2776 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2779 /* Anything else should be already split before reg-stack. */
2780 gcc_assert (which_alternative == 1);
2781 return "push{q}\t%q1";
2783 [(set_attr "type" "multi,push,multi")
2784 (set_attr "unit" "i387,*,*")
2785 (set_attr "mode" "SF,DI,SF")])
2787 (define_insn "*pushsf"
2788 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2789 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2792 /* Anything else should be already split before reg-stack. */
2793 gcc_assert (which_alternative == 1);
2794 return "push{l}\t%1";
2796 [(set_attr "type" "multi,push,multi")
2797 (set_attr "unit" "i387,*,*")
2798 (set_attr "mode" "SF,SI,SF")])
2801 [(set (match_operand:SF 0 "push_operand" "")
2802 (match_operand:SF 1 "memory_operand" ""))]
2804 && MEM_P (operands[1])
2805 && (operands[2] = find_constant_src (insn))"
2809 ;; %%% Kill this when call knows how to work this out.
2811 [(set (match_operand:SF 0 "push_operand" "")
2812 (match_operand:SF 1 "any_fp_register_operand" ""))]
2814 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2815 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2816 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2818 ;; Floating point move instructions.
2820 (define_expand "movtf"
2821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822 (match_operand:TF 1 "nonimmediate_operand" ""))]
2825 ix86_expand_move (TFmode, operands);
2829 (define_expand "mov<mode>"
2830 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2831 (match_operand:X87MODEF 1 "general_operand" ""))]
2833 "ix86_expand_move (<MODE>mode, operands); DONE;")
2835 (define_insn "*movtf_internal"
2836 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2837 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2839 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2841 switch (which_alternative)
2845 if (get_attr_mode (insn) == MODE_V4SF)
2846 return "%vmovaps\t{%1, %0|%0, %1}";
2848 return "%vmovdqa\t{%1, %0|%0, %1}";
2851 return standard_sse_constant_opcode (insn, operands[1]);
2861 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2862 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2864 (cond [(eq_attr "alternative" "0,2")
2866 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2868 (const_string "V4SF")
2869 (const_string "TI"))
2870 (eq_attr "alternative" "1")
2872 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2874 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2876 (const_string "V4SF")
2877 (const_string "TI"))]
2878 (const_string "DI")))])
2881 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2882 (match_operand:TF 1 "general_operand" ""))]
2884 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2886 "ix86_split_long_move (operands); DONE;")
2888 (define_insn "*movxf_internal"
2889 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
2890 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2891 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2892 && (!can_create_pseudo_p ()
2893 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894 || GET_CODE (operands[1]) != CONST_DOUBLE
2895 || (optimize_function_for_size_p (cfun)
2896 && standard_80387_constant_p (operands[1]) > 0)
2897 || memory_operand (operands[0], XFmode))"
2899 switch (which_alternative)
2903 return output_387_reg_move (insn, operands);
2906 return standard_80387_constant_opcode (operands[1]);
2914 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2915 (set_attr "mode" "XF,XF,XF,SI,SI")])
2918 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2919 (match_operand:XF 1 "general_operand" ""))]
2921 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && ! (FP_REG_P (operands[0]) ||
2923 (GET_CODE (operands[0]) == SUBREG
2924 && FP_REG_P (SUBREG_REG (operands[0]))))
2925 && ! (FP_REG_P (operands[1]) ||
2926 (GET_CODE (operands[1]) == SUBREG
2927 && FP_REG_P (SUBREG_REG (operands[1]))))"
2929 "ix86_split_long_move (operands); DONE;")
2931 (define_insn "*movdf_internal_rex64"
2932 [(set (match_operand:DF 0 "nonimmediate_operand"
2933 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2934 (match_operand:DF 1 "general_operand"
2935 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2936 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2937 && (!can_create_pseudo_p ()
2938 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2939 || GET_CODE (operands[1]) != CONST_DOUBLE
2940 || (optimize_function_for_size_p (cfun)
2941 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2942 && standard_80387_constant_p (operands[1]) > 0)
2943 || (TARGET_SSE2 && TARGET_SSE_MATH
2944 && standard_sse_constant_p (operands[1]))))
2945 || memory_operand (operands[0], DFmode))"
2947 switch (which_alternative)
2951 return output_387_reg_move (insn, operands);
2954 return standard_80387_constant_opcode (operands[1]);
2958 return "mov{q}\t{%1, %0|%0, %1}";
2961 return "movabs{q}\t{%1, %0|%0, %1}";
2967 return standard_sse_constant_opcode (insn, operands[1]);
2972 switch (get_attr_mode (insn))
2975 return "%vmovaps\t{%1, %0|%0, %1}";
2977 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2978 return "%vmovaps\t{%1, %0|%0, %1}";
2980 return "%vmovapd\t{%1, %0|%0, %1}";
2982 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2983 return "%vmovaps\t{%1, %0|%0, %1}";
2985 return "%vmovdqa\t{%1, %0|%0, %1}";
2987 return "%vmovq\t{%1, %0|%0, %1}";
2989 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2990 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2992 return "%vmovsd\t{%1, %0|%0, %1}";
2994 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2996 return "%vmovlps\t{%1, %d0|%d0, %1}";
3003 /* Handle broken assemblers that require movd instead of movq. */
3004 return "%vmovd\t{%1, %0|%0, %1}";
3010 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3013 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3015 (const_string "*")))
3016 (set (attr "length_immediate")
3018 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3020 (const_string "*")))
3021 (set (attr "prefix")
3022 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3023 (const_string "orig")
3024 (const_string "maybe_vex")))
3025 (set (attr "prefix_data16")
3026 (if_then_else (eq_attr "mode" "V1DF")
3028 (const_string "*")))
3030 (cond [(eq_attr "alternative" "0,1,2")
3032 (eq_attr "alternative" "3,4,5,6,11,12")
3035 /* For SSE1, we have many fewer alternatives. */
3036 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3037 (cond [(eq_attr "alternative" "7,8")
3038 (const_string "V4SF")
3040 (const_string "V2SF"))
3042 /* xorps is one byte shorter. */
3043 (eq_attr "alternative" "7")
3044 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3046 (const_string "V4SF")
3047 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3051 (const_string "V2DF"))
3053 /* For architectures resolving dependencies on
3054 whole SSE registers use APD move to break dependency
3055 chains, otherwise use short move to avoid extra work.
3057 movaps encodes one byte shorter. */
3058 (eq_attr "alternative" "8")
3060 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3062 (const_string "V4SF")
3063 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3065 (const_string "V2DF")
3067 (const_string "DF"))
3068 /* For architectures resolving dependencies on register
3069 parts we may avoid extra work to zero out upper part
3071 (eq_attr "alternative" "9")
3073 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3075 (const_string "V1DF")
3076 (const_string "DF"))
3078 (const_string "DF")))])
3080 ;; Possible store forwarding (partial memory) stall in alternative 4.
3081 (define_insn "*movdf_internal"
3082 [(set (match_operand:DF 0 "nonimmediate_operand"
3083 "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
3084 (match_operand:DF 1 "general_operand"
3085 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3086 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3087 && (!can_create_pseudo_p ()
3088 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3089 || GET_CODE (operands[1]) != CONST_DOUBLE
3090 || (!TARGET_INTEGER_DFMODE_MOVES
3091 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3092 && standard_80387_constant_p (operands[1]) > 0)
3093 || (TARGET_SSE2 && TARGET_SSE_MATH
3094 && standard_sse_constant_p (operands[1])))
3095 && !memory_operand (operands[0], DFmode))
3096 || ((TARGET_INTEGER_DFMODE_MOVES
3097 || !TARGET_MEMORY_MISMATCH_STALL)
3098 && memory_operand (operands[0], DFmode)))"
3100 switch (which_alternative)
3104 return output_387_reg_move (insn, operands);
3107 return standard_80387_constant_opcode (operands[1]);
3114 return standard_sse_constant_opcode (insn, operands[1]);
3119 switch (get_attr_mode (insn))
3122 return "%vmovaps\t{%1, %0|%0, %1}";
3124 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3125 return "%vmovaps\t{%1, %0|%0, %1}";
3127 return "%vmovapd\t{%1, %0|%0, %1}";
3129 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3130 return "%vmovaps\t{%1, %0|%0, %1}";
3132 return "%vmovdqa\t{%1, %0|%0, %1}";
3134 return "%vmovq\t{%1, %0|%0, %1}";
3136 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3137 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3139 return "%vmovsd\t{%1, %0|%0, %1}";
3141 if (TARGET_AVX && REG_P (operands[0]))
3142 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3144 return "%vmovlpd\t{%1, %0|%0, %1}";
3146 if (TARGET_AVX && REG_P (operands[0]))
3147 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3149 return "%vmovlps\t{%1, %0|%0, %1}";
3158 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3159 (set (attr "prefix")
3160 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3161 (const_string "orig")
3162 (const_string "maybe_vex")))
3163 (set (attr "prefix_data16")
3164 (if_then_else (eq_attr "mode" "V1DF")
3166 (const_string "*")))
3168 (cond [(eq_attr "alternative" "0,1,2")
3170 (eq_attr "alternative" "3,4")
3173 /* For SSE1, we have many fewer alternatives. */
3174 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3175 (cond [(eq_attr "alternative" "5,6")
3176 (const_string "V4SF")
3178 (const_string "V2SF"))
3180 /* xorps is one byte shorter. */
3181 (eq_attr "alternative" "5")
3182 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3184 (const_string "V4SF")
3185 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3189 (const_string "V2DF"))
3191 /* For architectures resolving dependencies on
3192 whole SSE registers use APD move to break dependency
3193 chains, otherwise use short move to avoid extra work.
3195 movaps encodes one byte shorter. */
3196 (eq_attr "alternative" "6")
3198 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3200 (const_string "V4SF")
3201 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3203 (const_string "V2DF")
3205 (const_string "DF"))
3206 /* For architectures resolving dependencies on register
3207 parts we may avoid extra work to zero out upper part
3209 (eq_attr "alternative" "7")
3211 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3213 (const_string "V1DF")
3214 (const_string "DF"))
3216 (const_string "DF")))])
3219 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3220 (match_operand:DF 1 "general_operand" ""))]
3222 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3223 && ! (ANY_FP_REG_P (operands[0]) ||
3224 (GET_CODE (operands[0]) == SUBREG
3225 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3226 && ! (ANY_FP_REG_P (operands[1]) ||
3227 (GET_CODE (operands[1]) == SUBREG
3228 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3230 "ix86_split_long_move (operands); DONE;")
3232 (define_insn "*movsf_internal"
3233 [(set (match_operand:SF 0 "nonimmediate_operand"
3234 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3235 (match_operand:SF 1 "general_operand"
3236 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3237 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3238 && (!can_create_pseudo_p ()
3239 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3240 || GET_CODE (operands[1]) != CONST_DOUBLE
3241 || (optimize_function_for_size_p (cfun)
3242 && ((!TARGET_SSE_MATH
3243 && standard_80387_constant_p (operands[1]) > 0)
3245 && standard_sse_constant_p (operands[1]))))
3246 || memory_operand (operands[0], SFmode))"
3248 switch (which_alternative)
3252 return output_387_reg_move (insn, operands);
3255 return standard_80387_constant_opcode (operands[1]);
3259 return "mov{l}\t{%1, %0|%0, %1}";
3262 return standard_sse_constant_opcode (insn, operands[1]);
3265 if (get_attr_mode (insn) == MODE_V4SF)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3268 return "%vmovss\t{%1, %d0|%d0, %1}";
3270 if (TARGET_AVX && REG_P (operands[1]))
3271 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3273 return "%vmovss\t{%1, %0|%0, %1}";
3275 return "%vmovss\t{%1, %0|%0, %1}";
3277 case 9: case 10: case 14: case 15:
3278 return "movd\t{%1, %0|%0, %1}";
3281 return "movq\t{%1, %0|%0, %1}";
3284 return "%vmovd\t{%1, %0|%0, %1}";
3290 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3291 (set (attr "prefix")
3292 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3293 (const_string "maybe_vex")
3294 (const_string "orig")))
3296 (cond [(eq_attr "alternative" "3,4,9,10")
3298 (eq_attr "alternative" "5")
3300 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3302 (ne (symbol_ref "TARGET_SSE2")
3304 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3307 (const_string "V4SF"))
3308 /* For architectures resolving dependencies on
3309 whole SSE registers use APS move to break dependency
3310 chains, otherwise use short move to avoid extra work.
3312 Do the same for architectures resolving dependencies on
3313 the parts. While in DF mode it is better to always handle
3314 just register parts, the SF mode is different due to lack
3315 of instructions to load just part of the register. It is
3316 better to maintain the whole registers in single format
3317 to avoid problems on using packed logical operations. */
3318 (eq_attr "alternative" "6")
3320 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3322 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3324 (const_string "V4SF")
3325 (const_string "SF"))
3326 (eq_attr "alternative" "11")
3327 (const_string "DI")]
3328 (const_string "SF")))])
3331 [(set (match_operand 0 "register_operand" "")
3332 (match_operand 1 "memory_operand" ""))]
3334 && MEM_P (operands[1])
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode
3338 || GET_MODE (operands[0]) == SFmode)
3339 && (operands[2] = find_constant_src (insn))"
3340 [(set (match_dup 0) (match_dup 2))]
3342 rtx c = operands[2];
3343 rtx r = operands[0];
3345 if (GET_CODE (r) == SUBREG)
3350 if (!standard_sse_constant_p (c))
3353 else if (FP_REG_P (r))
3355 if (standard_80387_constant_p (c) < 1)
3358 else if (MMX_REG_P (r))
3363 [(set (match_operand 0 "register_operand" "")
3364 (float_extend (match_operand 1 "memory_operand" "")))]
3366 && MEM_P (operands[1])
3367 && (GET_MODE (operands[0]) == TFmode
3368 || GET_MODE (operands[0]) == XFmode
3369 || GET_MODE (operands[0]) == DFmode
3370 || GET_MODE (operands[0]) == SFmode)
3371 && (operands[2] = find_constant_src (insn))"
3372 [(set (match_dup 0) (match_dup 2))]
3374 rtx c = operands[2];
3375 rtx r = operands[0];
3377 if (GET_CODE (r) == SUBREG)
3382 if (!standard_sse_constant_p (c))
3385 else if (FP_REG_P (r))
3387 if (standard_80387_constant_p (c) < 1)
3390 else if (MMX_REG_P (r))
3394 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3396 [(set (match_operand:X87MODEF 0 "register_operand" "")
3397 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3398 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3399 && (standard_80387_constant_p (operands[1]) == 8
3400 || standard_80387_constant_p (operands[1]) == 9)"
3401 [(set (match_dup 0)(match_dup 1))
3403 (neg:X87MODEF (match_dup 0)))]
3407 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3408 if (real_isnegzero (&r))
3409 operands[1] = CONST0_RTX (<MODE>mode);
3411 operands[1] = CONST1_RTX (<MODE>mode);
3414 (define_insn "swapxf"
3415 [(set (match_operand:XF 0 "register_operand" "+f")
3416 (match_operand:XF 1 "register_operand" "+f"))
3421 if (STACK_TOP_P (operands[0]))
3426 [(set_attr "type" "fxch")
3427 (set_attr "mode" "XF")])
3429 (define_insn "*swap<mode>"
3430 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3431 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3434 "TARGET_80387 || reload_completed"
3436 if (STACK_TOP_P (operands[0]))
3441 [(set_attr "type" "fxch")
3442 (set_attr "mode" "<MODE>")])
3444 ;; Zero extension instructions
3446 (define_expand "zero_extendsidi2"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3448 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3453 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3458 (define_insn "*zero_extendsidi2_rex64"
3459 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3461 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3464 mov\t{%k1, %k0|%k0, %k1}
3466 movd\t{%1, %0|%0, %1}
3467 movd\t{%1, %0|%0, %1}
3468 %vmovd\t{%1, %0|%0, %1}
3469 %vmovd\t{%1, %0|%0, %1}"
3470 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3471 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3472 (set_attr "prefix_0f" "0,*,*,*,*,*")
3473 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3476 [(set (match_operand:DI 0 "memory_operand" "")
3477 (zero_extend:DI (match_dup 0)))]
3479 [(set (match_dup 4) (const_int 0))]
3480 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3482 ;; %%% Kill me once multi-word ops are sane.
3483 (define_insn "zero_extendsidi2_1"
3484 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3486 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3487 (clobber (reg:CC FLAGS_REG))]
3493 movd\t{%1, %0|%0, %1}
3494 movd\t{%1, %0|%0, %1}
3495 %vmovd\t{%1, %0|%0, %1}
3496 %vmovd\t{%1, %0|%0, %1}"
3497 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3498 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3499 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3502 [(set (match_operand:DI 0 "register_operand" "")
3503 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3504 (clobber (reg:CC FLAGS_REG))]
3505 "!TARGET_64BIT && reload_completed
3506 && true_regnum (operands[0]) == true_regnum (operands[1])"
3507 [(set (match_dup 4) (const_int 0))]
3508 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3511 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3512 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3513 (clobber (reg:CC FLAGS_REG))]
3514 "!TARGET_64BIT && reload_completed
3515 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3516 [(set (match_dup 3) (match_dup 1))
3517 (set (match_dup 4) (const_int 0))]
3518 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3520 (define_insn "zero_extend<mode>di2"
3521 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3525 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "SI")])
3529 (define_expand "zero_extendhisi2"
3530 [(set (match_operand:SI 0 "register_operand" "")
3531 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3534 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3536 operands[1] = force_reg (HImode, operands[1]);
3537 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3542 (define_insn_and_split "zero_extendhisi2_and"
3543 [(set (match_operand:SI 0 "register_operand" "=r")
3544 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3545 (clobber (reg:CC FLAGS_REG))]
3546 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3548 "&& reload_completed"
3549 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3550 (clobber (reg:CC FLAGS_REG))])]
3552 [(set_attr "type" "alu1")
3553 (set_attr "mode" "SI")])
3555 (define_insn "*zero_extendhisi2_movzwl"
3556 [(set (match_operand:SI 0 "register_operand" "=r")
3557 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3558 "!TARGET_ZERO_EXTEND_WITH_AND
3559 || optimize_function_for_size_p (cfun)"
3560 "movz{wl|x}\t{%1, %0|%0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3564 (define_expand "zero_extendqi<mode>2"
3566 [(set (match_operand:SWI24 0 "register_operand" "")
3567 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3568 (clobber (reg:CC FLAGS_REG))])])
3570 (define_insn "*zero_extendqi<mode>2_and"
3571 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3572 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3573 (clobber (reg:CC FLAGS_REG))]
3574 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3576 [(set_attr "type" "alu1")
3577 (set_attr "mode" "<MODE>")])
3579 ;; When source and destination does not overlap, clear destination
3580 ;; first and then do the movb
3582 [(set (match_operand:SWI24 0 "register_operand" "")
3583 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3584 (clobber (reg:CC FLAGS_REG))]
3586 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3587 && ANY_QI_REG_P (operands[0])
3588 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3589 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3590 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3592 operands[2] = gen_lowpart (QImode, operands[0]);
3593 ix86_expand_clear (operands[0]);
3596 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3597 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3598 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3599 (clobber (reg:CC FLAGS_REG))]
3600 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3602 [(set_attr "type" "imovx,alu1")
3603 (set_attr "mode" "<MODE>")])
3605 ;; For the movzbl case strip only the clobber
3607 [(set (match_operand:SWI24 0 "register_operand" "")
3608 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3609 (clobber (reg:CC FLAGS_REG))]
3611 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3612 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3614 (zero_extend:SWI24 (match_dup 1)))])
3616 ; zero extend to SImode to avoid partial register stalls
3617 (define_insn "*zero_extendqi<mode>2_movzbl"
3618 [(set (match_operand:SWI24 0 "register_operand" "=r")
3619 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3621 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3622 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3623 [(set_attr "type" "imovx")
3624 (set_attr "mode" "SI")])
3626 ;; Rest is handled by single and.
3628 [(set (match_operand:SWI24 0 "register_operand" "")
3629 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3630 (clobber (reg:CC FLAGS_REG))]
3632 && true_regnum (operands[0]) == true_regnum (operands[1])"
3633 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3634 (clobber (reg:CC FLAGS_REG))])])
3636 ;; Sign extension instructions
3638 (define_expand "extendsidi2"
3639 [(set (match_operand:DI 0 "register_operand" "")
3640 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3645 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3650 (define_insn "*extendsidi2_rex64"
3651 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3652 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3656 movs{lq|x}\t{%1, %0|%0, %1}"
3657 [(set_attr "type" "imovx")
3658 (set_attr "mode" "DI")
3659 (set_attr "prefix_0f" "0")
3660 (set_attr "modrm" "0,1")])
3662 (define_insn "extendsidi2_1"
3663 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3664 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3665 (clobber (reg:CC FLAGS_REG))
3666 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3670 ;; Extend to memory case when source register does die.
3672 [(set (match_operand:DI 0 "memory_operand" "")
3673 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))
3675 (clobber (match_operand:SI 2 "register_operand" ""))]
3677 && dead_or_set_p (insn, operands[1])
3678 && !reg_mentioned_p (operands[1], operands[0]))"
3679 [(set (match_dup 3) (match_dup 1))
3680 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3681 (clobber (reg:CC FLAGS_REG))])
3682 (set (match_dup 4) (match_dup 1))]
3683 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3685 ;; Extend to memory case when source register does not die.
3687 [(set (match_operand:DI 0 "memory_operand" "")
3688 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3689 (clobber (reg:CC FLAGS_REG))
3690 (clobber (match_operand:SI 2 "register_operand" ""))]
3694 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3696 emit_move_insn (operands[3], operands[1]);
3698 /* Generate a cltd if possible and doing so it profitable. */
3699 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3700 && true_regnum (operands[1]) == AX_REG
3701 && true_regnum (operands[2]) == DX_REG)
3703 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3707 emit_move_insn (operands[2], operands[1]);
3708 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3710 emit_move_insn (operands[4], operands[2]);
3714 ;; Extend to register case. Optimize case where source and destination
3715 ;; registers match and cases where we can use cltd.
3717 [(set (match_operand:DI 0 "register_operand" "")
3718 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3719 (clobber (reg:CC FLAGS_REG))
3720 (clobber (match_scratch:SI 2 ""))]
3724 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3726 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3727 emit_move_insn (operands[3], operands[1]);
3729 /* Generate a cltd if possible and doing so it profitable. */
3730 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3731 && true_regnum (operands[3]) == AX_REG
3732 && true_regnum (operands[4]) == DX_REG)
3734 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3738 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3739 emit_move_insn (operands[4], operands[1]);
3741 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3745 (define_insn "extend<mode>di2"
3746 [(set (match_operand:DI 0 "register_operand" "=r")
3748 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3750 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "DI")])
3754 (define_insn "extendhisi2"
3755 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3756 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3759 switch (get_attr_prefix_0f (insn))
3762 return "{cwtl|cwde}";
3764 return "movs{wl|x}\t{%1, %0|%0, %1}";
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "SI")
3769 (set (attr "prefix_0f")
3770 ;; movsx is short decodable while cwtl is vector decoded.
3771 (if_then_else (and (eq_attr "cpu" "!k6")
3772 (eq_attr "alternative" "0"))
3774 (const_string "1")))
3776 (if_then_else (eq_attr "prefix_0f" "0")
3778 (const_string "1")))])
3780 (define_insn "*extendhisi2_zext"
3781 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3784 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3787 switch (get_attr_prefix_0f (insn))
3790 return "{cwtl|cwde}";
3792 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "SI")
3797 (set (attr "prefix_0f")
3798 ;; movsx is short decodable while cwtl is vector decoded.
3799 (if_then_else (and (eq_attr "cpu" "!k6")
3800 (eq_attr "alternative" "0"))
3802 (const_string "1")))
3804 (if_then_else (eq_attr "prefix_0f" "0")
3806 (const_string "1")))])
3808 (define_insn "extendqisi2"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3812 "movs{bl|x}\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "SI")])
3816 (define_insn "*extendqisi2_zext"
3817 [(set (match_operand:DI 0 "register_operand" "=r")
3819 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3821 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_insn "extendqihi2"
3826 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3827 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3830 switch (get_attr_prefix_0f (insn))
3833 return "{cbtw|cbw}";
3835 return "movs{bw|x}\t{%1, %0|%0, %1}";
3838 [(set_attr "type" "imovx")
3839 (set_attr "mode" "HI")
3840 (set (attr "prefix_0f")
3841 ;; movsx is short decodable while cwtl is vector decoded.
3842 (if_then_else (and (eq_attr "cpu" "!k6")
3843 (eq_attr "alternative" "0"))
3845 (const_string "1")))
3847 (if_then_else (eq_attr "prefix_0f" "0")
3849 (const_string "1")))])
3851 ;; Conversions between float and double.
3853 ;; These are all no-ops in the model used for the 80387.
3854 ;; So just emit moves.
3856 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3858 [(set (match_operand:DF 0 "push_operand" "")
3859 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3861 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3862 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3865 [(set (match_operand:XF 0 "push_operand" "")
3866 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3868 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3869 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3870 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3872 (define_expand "extendsfdf2"
3873 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3874 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3875 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3877 /* ??? Needed for compress_float_constant since all fp constants
3878 are TARGET_LEGITIMATE_CONSTANT_P. */
3879 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3881 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3882 && standard_80387_constant_p (operands[1]) > 0)
3884 operands[1] = simplify_const_unary_operation
3885 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3886 emit_move_insn_1 (operands[0], operands[1]);
3889 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3893 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3895 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3897 We do the conversion post reload to avoid producing of 128bit spills
3898 that might lead to ICE on 32bit target. The sequence unlikely combine
3901 [(set (match_operand:DF 0 "register_operand" "")
3903 (match_operand:SF 1 "nonimmediate_operand" "")))]
3904 "TARGET_USE_VECTOR_FP_CONVERTS
3905 && optimize_insn_for_speed_p ()
3906 && reload_completed && SSE_REG_P (operands[0])"
3911 (parallel [(const_int 0) (const_int 1)]))))]
3913 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3914 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3915 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3916 Try to avoid move when unpacking can be done in source. */
3917 if (REG_P (operands[1]))
3919 /* If it is unsafe to overwrite upper half of source, we need
3920 to move to destination and unpack there. */
3921 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3922 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3923 && true_regnum (operands[0]) != true_regnum (operands[1]))
3925 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3926 emit_move_insn (tmp, operands[1]);
3929 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3930 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3934 emit_insn (gen_vec_setv4sf_0 (operands[3],
3935 CONST0_RTX (V4SFmode), operands[1]));
3938 (define_insn "*extendsfdf2_mixed"
3939 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3941 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3942 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3944 switch (which_alternative)
3948 return output_387_reg_move (insn, operands);
3951 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3957 [(set_attr "type" "fmov,fmov,ssecvt")
3958 (set_attr "prefix" "orig,orig,maybe_vex")
3959 (set_attr "mode" "SF,XF,DF")])
3961 (define_insn "*extendsfdf2_sse"
3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3963 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3964 "TARGET_SSE2 && TARGET_SSE_MATH"
3965 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3966 [(set_attr "type" "ssecvt")
3967 (set_attr "prefix" "maybe_vex")
3968 (set_attr "mode" "DF")])
3970 (define_insn "*extendsfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3972 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3974 "* return output_387_reg_move (insn, operands);"
3975 [(set_attr "type" "fmov")
3976 (set_attr "mode" "SF,XF")])
3978 (define_expand "extend<mode>xf2"
3979 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3980 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3983 /* ??? Needed for compress_float_constant since all fp constants
3984 are TARGET_LEGITIMATE_CONSTANT_P. */
3985 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3987 if (standard_80387_constant_p (operands[1]) > 0)
3989 operands[1] = simplify_const_unary_operation
3990 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3991 emit_move_insn_1 (operands[0], operands[1]);
3994 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3998 (define_insn "*extend<mode>xf2_i387"
3999 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4001 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4003 "* return output_387_reg_move (insn, operands);"
4004 [(set_attr "type" "fmov")
4005 (set_attr "mode" "<MODE>,XF")])
4007 ;; %%% This seems bad bad news.
4008 ;; This cannot output into an f-reg because there is no way to be sure
4009 ;; of truncating in that case. Otherwise this is just like a simple move
4010 ;; insn. So we pretend we can output to a reg in order to get better
4011 ;; register preferencing, but we really use a stack slot.
4013 ;; Conversion from DFmode to SFmode.
4015 (define_expand "truncdfsf2"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4018 (match_operand:DF 1 "nonimmediate_operand" "")))]
4019 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4021 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4023 else if (flag_unsafe_math_optimizations)
4027 enum ix86_stack_slot slot = (virtuals_instantiated
4030 rtx temp = assign_386_stack_local (SFmode, slot);
4031 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4036 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4038 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4040 We do the conversion post reload to avoid producing of 128bit spills
4041 that might lead to ICE on 32bit target. The sequence unlikely combine
4044 [(set (match_operand:SF 0 "register_operand" "")
4046 (match_operand:DF 1 "nonimmediate_operand" "")))]
4047 "TARGET_USE_VECTOR_FP_CONVERTS
4048 && optimize_insn_for_speed_p ()
4049 && reload_completed && SSE_REG_P (operands[0])"
4052 (float_truncate:V2SF
4056 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4057 operands[3] = CONST0_RTX (V2SFmode);
4058 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4059 /* Use movsd for loading from memory, unpcklpd for registers.
4060 Try to avoid move when unpacking can be done in source, or SSE3
4061 movddup is available. */
4062 if (REG_P (operands[1]))
4065 && true_regnum (operands[0]) != true_regnum (operands[1])
4066 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4067 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4069 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4070 emit_move_insn (tmp, operands[1]);
4073 else if (!TARGET_SSE3)
4074 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4075 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4078 emit_insn (gen_sse2_loadlpd (operands[4],
4079 CONST0_RTX (V2DFmode), operands[1]));
4082 (define_expand "truncdfsf2_with_temp"
4083 [(parallel [(set (match_operand:SF 0 "" "")
4084 (float_truncate:SF (match_operand:DF 1 "" "")))
4085 (clobber (match_operand:SF 2 "" ""))])])
4087 (define_insn "*truncdfsf_fast_mixed"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4091 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4093 switch (which_alternative)
4096 return output_387_reg_move (insn, operands);
4098 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4103 [(set_attr "type" "fmov,ssecvt")
4104 (set_attr "prefix" "orig,maybe_vex")
4105 (set_attr "mode" "SF")])
4107 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4108 ;; because nothing we do here is unsafe.
4109 (define_insn "*truncdfsf_fast_sse"
4110 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4112 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4113 "TARGET_SSE2 && TARGET_SSE_MATH"
4114 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4115 [(set_attr "type" "ssecvt")
4116 (set_attr "prefix" "maybe_vex")
4117 (set_attr "mode" "SF")])
4119 (define_insn "*truncdfsf_fast_i387"
4120 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4122 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4123 "TARGET_80387 && flag_unsafe_math_optimizations"
4124 "* return output_387_reg_move (insn, operands);"
4125 [(set_attr "type" "fmov")
4126 (set_attr "mode" "SF")])
4128 (define_insn "*truncdfsf_mixed"
4129 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4131 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4132 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4133 "TARGET_MIX_SSE_I387"
4135 switch (which_alternative)
4138 return output_387_reg_move (insn, operands);
4140 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4146 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4147 (set_attr "unit" "*,*,i387,i387,i387")
4148 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4149 (set_attr "mode" "SF")])
4151 (define_insn "*truncdfsf_i387"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4154 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4155 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4158 switch (which_alternative)
4161 return output_387_reg_move (insn, operands);
4167 [(set_attr "type" "fmov,multi,multi,multi")
4168 (set_attr "unit" "*,i387,i387,i387")
4169 (set_attr "mode" "SF")])
4171 (define_insn "*truncdfsf2_i387_1"
4172 [(set (match_operand:SF 0 "memory_operand" "=m")
4174 (match_operand:DF 1 "register_operand" "f")))]
4176 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4177 && !TARGET_MIX_SSE_I387"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "SF")])
4183 [(set (match_operand:SF 0 "register_operand" "")
4185 (match_operand:DF 1 "fp_register_operand" "")))
4186 (clobber (match_operand 2 "" ""))]
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (match_dup 2))]
4190 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4192 ;; Conversion from XFmode to {SF,DF}mode
4194 (define_expand "truncxf<mode>2"
4195 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_dup 2))])]
4201 if (flag_unsafe_math_optimizations)
4203 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4204 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4205 if (reg != operands[0])
4206 emit_move_insn (operands[0], reg);
4211 enum ix86_stack_slot slot = (virtuals_instantiated
4214 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4218 (define_insn "*truncxfsf2_mixed"
4219 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4221 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4222 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4225 gcc_assert (!which_alternative);
4226 return output_387_reg_move (insn, operands);
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "unit" "*,i387,i387,i387")
4230 (set_attr "mode" "SF")])
4232 (define_insn "*truncxfdf2_mixed"
4233 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4235 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4236 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4239 gcc_assert (!which_alternative);
4240 return output_387_reg_move (insn, operands);
4242 [(set_attr "type" "fmov,multi,multi,multi")
4243 (set_attr "unit" "*,i387,i387,i387")
4244 (set_attr "mode" "DF")])
4246 (define_insn "truncxf<mode>2_i387_noop"
4247 [(set (match_operand:MODEF 0 "register_operand" "=f")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "f")))]
4250 "TARGET_80387 && flag_unsafe_math_optimizations"
4251 "* return output_387_reg_move (insn, operands);"
4252 [(set_attr "type" "fmov")
4253 (set_attr "mode" "<MODE>")])
4255 (define_insn "*truncxf<mode>2_i387"
4256 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4257 (float_truncate:MODEF
4258 (match_operand:XF 1 "register_operand" "f")))]
4260 "* return output_387_reg_move (insn, operands);"
4261 [(set_attr "type" "fmov")
4262 (set_attr "mode" "<MODE>")])
4265 [(set (match_operand:MODEF 0 "register_operand" "")
4266 (float_truncate:MODEF
4267 (match_operand:XF 1 "register_operand" "")))
4268 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4269 "TARGET_80387 && reload_completed"
4270 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4271 (set (match_dup 0) (match_dup 2))])
4274 [(set (match_operand:MODEF 0 "memory_operand" "")
4275 (float_truncate:MODEF
4276 (match_operand:XF 1 "register_operand" "")))
4277 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4279 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4281 ;; Signed conversion to DImode.
4283 (define_expand "fix_truncxfdi2"
4284 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4285 (fix:DI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>di2"
4297 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4298 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4303 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4311 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to SImode.
4320 (define_expand "fix_truncxfsi2"
4321 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4322 (fix:SI (match_operand:XF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4328 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4333 (define_expand "fix_trunc<mode>si2"
4334 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4335 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4336 (clobber (reg:CC FLAGS_REG))])]
4337 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4340 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4342 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4345 if (SSE_FLOAT_MODE_P (<MODE>mode))
4347 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4348 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4349 if (out != operands[0])
4350 emit_move_insn (operands[0], out);
4355 ;; Signed conversion to HImode.
4357 (define_expand "fix_trunc<mode>hi2"
4358 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4360 (clobber (reg:CC FLAGS_REG))])]
4362 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4366 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4371 ;; Unsigned conversion to SImode.
4373 (define_expand "fixuns_trunc<mode>si2"
4375 [(set (match_operand:SI 0 "register_operand" "")
4377 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4379 (clobber (match_scratch:<ssevecmode> 3 ""))
4380 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4381 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4383 enum machine_mode mode = <MODE>mode;
4384 enum machine_mode vecmode = <ssevecmode>mode;
4385 REAL_VALUE_TYPE TWO31r;
4388 if (optimize_insn_for_size_p ())
4391 real_ldexp (&TWO31r, &dconst1, 31);
4392 two31 = const_double_from_real_value (TWO31r, mode);
4393 two31 = ix86_build_const_vector (vecmode, true, two31);
4394 operands[2] = force_reg (vecmode, two31);
4397 (define_insn_and_split "*fixuns_trunc<mode>_1"
4398 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4400 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4401 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4402 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4403 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4404 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4405 && optimize_function_for_speed_p (cfun)"
4407 "&& reload_completed"
4410 ix86_split_convert_uns_si_sse (operands);
4414 ;; Unsigned conversion to HImode.
4415 ;; Without these patterns, we'll try the unsigned SI conversion which
4416 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4418 (define_expand "fixuns_trunc<mode>hi2"
4420 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4421 (set (match_operand:HI 0 "nonimmediate_operand" "")
4422 (subreg:HI (match_dup 2) 0))]
4423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4424 "operands[2] = gen_reg_rtx (SImode);")
4426 ;; When SSE is available, it is always faster to use it!
4427 (define_insn "fix_trunc<mode>di_sse"
4428 [(set (match_operand:DI 0 "register_operand" "=r,r")
4429 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4430 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4431 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4432 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4433 [(set_attr "type" "sseicvt")
4434 (set_attr "prefix" "maybe_vex")
4435 (set_attr "prefix_rex" "1")
4436 (set_attr "mode" "<MODE>")
4437 (set_attr "athlon_decode" "double,vector")
4438 (set_attr "amdfam10_decode" "double,double")
4439 (set_attr "bdver1_decode" "double,double")])
4441 (define_insn "fix_trunc<mode>si_sse"
4442 [(set (match_operand:SI 0 "register_operand" "=r,r")
4443 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4444 "SSE_FLOAT_MODE_P (<MODE>mode)
4445 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4446 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4447 [(set_attr "type" "sseicvt")
4448 (set_attr "prefix" "maybe_vex")
4449 (set_attr "mode" "<MODE>")
4450 (set_attr "athlon_decode" "double,vector")
4451 (set_attr "amdfam10_decode" "double,double")
4452 (set_attr "bdver1_decode" "double,double")])
4454 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4456 [(set (match_operand:MODEF 0 "register_operand" "")
4457 (match_operand:MODEF 1 "memory_operand" ""))
4458 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4459 (fix:SSEMODEI24 (match_dup 0)))]
4460 "TARGET_SHORTEN_X87_SSE
4461 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4462 && peep2_reg_dead_p (2, operands[0])"
4463 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4465 ;; Avoid vector decoded forms of the instruction.
4467 [(match_scratch:DF 2 "Y2")
4468 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4469 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4470 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4471 [(set (match_dup 2) (match_dup 1))
4472 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4475 [(match_scratch:SF 2 "x")
4476 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4477 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4478 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4479 [(set (match_dup 2) (match_dup 1))
4480 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4482 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4483 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4484 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (TARGET_64BIT || <MODE>mode != DImode))
4490 && can_create_pseudo_p ()"
4495 if (memory_operand (operands[0], VOIDmode))
4496 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4499 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4500 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4506 [(set_attr "type" "fisttp")
4507 (set_attr "mode" "<MODE>")])
4509 (define_insn "fix_trunc<mode>_i387_fisttp"
4510 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4511 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4512 (clobber (match_scratch:XF 2 "=&1f"))]
4513 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && (TARGET_64BIT || <MODE>mode != DImode))
4517 && TARGET_SSE_MATH)"
4518 "* return output_fix_trunc (insn, operands, true);"
4519 [(set_attr "type" "fisttp")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4523 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4524 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4525 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4526 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && TARGET_SSE_MATH)"
4533 [(set_attr "type" "fisttp")
4534 (set_attr "mode" "<MODE>")])
4537 [(set (match_operand:X87MODEI 0 "register_operand" "")
4538 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4539 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4540 (clobber (match_scratch 3 ""))]
4542 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4543 (clobber (match_dup 3))])
4544 (set (match_dup 0) (match_dup 2))])
4547 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4548 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4549 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4550 (clobber (match_scratch 3 ""))]
4552 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4553 (clobber (match_dup 3))])])
4555 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4556 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4557 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4558 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4559 ;; function in i386.c.
4560 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4561 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4562 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4563 (clobber (reg:CC FLAGS_REG))]
4564 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4567 && (TARGET_64BIT || <MODE>mode != DImode))
4568 && can_create_pseudo_p ()"
4573 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4577 if (memory_operand (operands[0], VOIDmode))
4578 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4579 operands[2], operands[3]));
4582 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4583 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4584 operands[2], operands[3],
4589 [(set_attr "type" "fistp")
4590 (set_attr "i387_cw" "trunc")
4591 (set_attr "mode" "<MODE>")])
4593 (define_insn "fix_truncdi_i387"
4594 [(set (match_operand:DI 0 "memory_operand" "=m")
4595 (fix:DI (match_operand 1 "register_operand" "f")))
4596 (use (match_operand:HI 2 "memory_operand" "m"))
4597 (use (match_operand:HI 3 "memory_operand" "m"))
4598 (clobber (match_scratch:XF 4 "=&1f"))]
4599 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602 "* return output_fix_trunc (insn, operands, false);"
4603 [(set_attr "type" "fistp")
4604 (set_attr "i387_cw" "trunc")
4605 (set_attr "mode" "DI")])
4607 (define_insn "fix_truncdi_i387_with_temp"
4608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:DI (match_operand 1 "register_operand" "f,f")))
4610 (use (match_operand:HI 2 "memory_operand" "m,m"))
4611 (use (match_operand:HI 3 "memory_operand" "m,m"))
4612 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4613 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "DI")])
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (fix:DI (match_operand 1 "register_operand" "")))
4625 (use (match_operand:HI 2 "memory_operand" ""))
4626 (use (match_operand:HI 3 "memory_operand" ""))
4627 (clobber (match_operand:DI 4 "memory_operand" ""))
4628 (clobber (match_scratch 5 ""))]
4630 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4633 (clobber (match_dup 5))])
4634 (set (match_dup 0) (match_dup 4))])
4637 [(set (match_operand:DI 0 "memory_operand" "")
4638 (fix:DI (match_operand 1 "register_operand" "")))
4639 (use (match_operand:HI 2 "memory_operand" ""))
4640 (use (match_operand:HI 3 "memory_operand" ""))
4641 (clobber (match_operand:DI 4 "memory_operand" ""))
4642 (clobber (match_scratch 5 ""))]
4644 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4647 (clobber (match_dup 5))])])
4649 (define_insn "fix_trunc<mode>_i387"
4650 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4651 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4652 (use (match_operand:HI 2 "memory_operand" "m"))
4653 (use (match_operand:HI 3 "memory_operand" "m"))]
4654 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4657 "* return output_fix_trunc (insn, operands, false);"
4658 [(set_attr "type" "fistp")
4659 (set_attr "i387_cw" "trunc")
4660 (set_attr "mode" "<MODE>")])
4662 (define_insn "fix_trunc<mode>_i387_with_temp"
4663 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4664 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4665 (use (match_operand:HI 2 "memory_operand" "m,m"))
4666 (use (match_operand:HI 3 "memory_operand" "m,m"))
4667 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4672 [(set_attr "type" "fistp")
4673 (set_attr "i387_cw" "trunc")
4674 (set_attr "mode" "<MODE>")])
4677 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4678 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4679 (use (match_operand:HI 2 "memory_operand" ""))
4680 (use (match_operand:HI 3 "memory_operand" ""))
4681 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4683 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4685 (use (match_dup 3))])
4686 (set (match_dup 0) (match_dup 4))])
4689 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4690 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4695 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4697 (use (match_dup 3))])])
4699 (define_insn "x86_fnstcw_1"
4700 [(set (match_operand:HI 0 "memory_operand" "=m")
4701 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4704 [(set (attr "length")
4705 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4706 (set_attr "mode" "HI")
4707 (set_attr "unit" "i387")
4708 (set_attr "bdver1_decode" "vector")])
4710 (define_insn "x86_fldcw_1"
4711 [(set (reg:HI FPCR_REG)
4712 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4715 [(set (attr "length")
4716 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4717 (set_attr "mode" "HI")
4718 (set_attr "unit" "i387")
4719 (set_attr "athlon_decode" "vector")
4720 (set_attr "amdfam10_decode" "vector")
4721 (set_attr "bdver1_decode" "vector")])
4723 ;; Conversion between fixed point and floating point.
4725 ;; Even though we only accept memory inputs, the backend _really_
4726 ;; wants to be able to do this between registers.
4728 (define_expand "floathi<mode>2"
4729 [(set (match_operand:X87MODEF 0 "register_operand" "")
4730 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4733 || TARGET_MIX_SSE_I387)")
4735 ;; Pre-reload splitter to add memory clobber to the pattern.
4736 (define_insn_and_split "*floathi<mode>2_1"
4737 [(set (match_operand:X87MODEF 0 "register_operand" "")
4738 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741 || TARGET_MIX_SSE_I387)
4742 && can_create_pseudo_p ()"
4745 [(parallel [(set (match_dup 0)
4746 (float:X87MODEF (match_dup 1)))
4747 (clobber (match_dup 2))])]
4748 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4750 (define_insn "*floathi<mode>2_i387_with_temp"
4751 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4752 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4753 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4756 || TARGET_MIX_SSE_I387)"
4758 [(set_attr "type" "fmov,multi")
4759 (set_attr "mode" "<MODE>")
4760 (set_attr "unit" "*,i387")
4761 (set_attr "fp_int_src" "true")])
4763 (define_insn "*floathi<mode>2_i387"
4764 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4765 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4768 || TARGET_MIX_SSE_I387)"
4770 [(set_attr "type" "fmov")
4771 (set_attr "mode" "<MODE>")
4772 (set_attr "fp_int_src" "true")])
4775 [(set (match_operand:X87MODEF 0 "register_operand" "")
4776 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4777 (clobber (match_operand:HI 2 "memory_operand" ""))]
4779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4780 || TARGET_MIX_SSE_I387)
4781 && reload_completed"
4782 [(set (match_dup 2) (match_dup 1))
4783 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4786 [(set (match_operand:X87MODEF 0 "register_operand" "")
4787 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4788 (clobber (match_operand:HI 2 "memory_operand" ""))]
4790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791 || TARGET_MIX_SSE_I387)
4792 && reload_completed"
4793 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4795 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4796 [(set (match_operand:X87MODEF 0 "register_operand" "")
4798 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4800 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4801 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4803 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4805 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4807 rtx reg = gen_reg_rtx (XFmode);
4808 rtx (*insn)(rtx, rtx);
4810 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4812 if (<X87MODEF:MODE>mode == SFmode)
4813 insn = gen_truncxfsf2;
4814 else if (<X87MODEF:MODE>mode == DFmode)
4815 insn = gen_truncxfdf2;
4819 emit_insn (insn (operands[0], reg));
4824 ;; Pre-reload splitter to add memory clobber to the pattern.
4825 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4826 [(set (match_operand:X87MODEF 0 "register_operand" "")
4827 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4829 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4830 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4831 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4832 || TARGET_MIX_SSE_I387))
4833 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4835 && ((<SSEMODEI24:MODE>mode == SImode
4836 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4837 && optimize_function_for_speed_p (cfun)
4838 && flag_trapping_math)
4839 || !(TARGET_INTER_UNIT_CONVERSIONS
4840 || optimize_function_for_size_p (cfun)))))
4841 && can_create_pseudo_p ()"
4844 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4845 (clobber (match_dup 2))])]
4847 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4849 /* Avoid store forwarding (partial memory) stall penalty
4850 by passing DImode value through XMM registers. */
4851 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4852 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4853 && optimize_function_for_speed_p (cfun))
4855 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4862 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4863 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4865 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4866 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4867 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4868 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4870 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4871 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4872 (set_attr "unit" "*,i387,*,*,*")
4873 (set_attr "athlon_decode" "*,*,double,direct,double")
4874 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4875 (set_attr "bdver1_decode" "*,*,double,direct,double")
4876 (set_attr "fp_int_src" "true")])
4878 (define_insn "*floatsi<mode>2_vector_mixed"
4879 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4880 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4881 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4882 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4886 [(set_attr "type" "fmov,sseicvt")
4887 (set_attr "mode" "<MODE>,<ssevecmode>")
4888 (set_attr "unit" "i387,*")
4889 (set_attr "athlon_decode" "*,direct")
4890 (set_attr "amdfam10_decode" "*,double")
4891 (set_attr "bdver1_decode" "*,direct")
4892 (set_attr "fp_int_src" "true")])
4894 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4895 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4897 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4898 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4899 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4902 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set_attr "unit" "*,i387,*,*")
4905 (set_attr "athlon_decode" "*,*,double,direct")
4906 (set_attr "amdfam10_decode" "*,*,vector,double")
4907 (set_attr "bdver1_decode" "*,*,double,direct")
4908 (set_attr "fp_int_src" "true")])
4911 [(set (match_operand:MODEF 0 "register_operand" "")
4912 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4913 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4914 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4915 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916 && TARGET_INTER_UNIT_CONVERSIONS
4918 && (SSE_REG_P (operands[0])
4919 || (GET_CODE (operands[0]) == SUBREG
4920 && SSE_REG_P (operands[0])))"
4921 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4924 [(set (match_operand:MODEF 0 "register_operand" "")
4925 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4926 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4927 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4928 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4929 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4931 && (SSE_REG_P (operands[0])
4932 || (GET_CODE (operands[0]) == SUBREG
4933 && SSE_REG_P (operands[0])))"
4934 [(set (match_dup 2) (match_dup 1))
4935 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4937 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4938 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4940 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4941 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4943 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4946 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4947 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4948 [(set_attr "type" "fmov,sseicvt,sseicvt")
4949 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4950 (set_attr "mode" "<MODEF:MODE>")
4951 (set (attr "prefix_rex")
4953 (and (eq_attr "prefix" "maybe_vex")
4954 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4956 (const_string "*")))
4957 (set_attr "unit" "i387,*,*")
4958 (set_attr "athlon_decode" "*,double,direct")
4959 (set_attr "amdfam10_decode" "*,vector,double")
4960 (set_attr "bdver1_decode" "*,double,direct")
4961 (set_attr "fp_int_src" "true")])
4963 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4964 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4966 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4967 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4968 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4969 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4972 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4973 [(set_attr "type" "fmov,sseicvt")
4974 (set_attr "prefix" "orig,maybe_vex")
4975 (set_attr "mode" "<MODEF:MODE>")
4976 (set (attr "prefix_rex")
4978 (and (eq_attr "prefix" "maybe_vex")
4979 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4981 (const_string "*")))
4982 (set_attr "athlon_decode" "*,direct")
4983 (set_attr "amdfam10_decode" "*,double")
4984 (set_attr "bdver1_decode" "*,direct")
4985 (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4988 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4990 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4991 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4992 "TARGET_SSE2 && TARGET_SSE_MATH
4993 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4995 [(set_attr "type" "sseicvt")
4996 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4997 (set_attr "athlon_decode" "double,direct,double")
4998 (set_attr "amdfam10_decode" "vector,double,double")
4999 (set_attr "bdver1_decode" "double,direct,double")
5000 (set_attr "fp_int_src" "true")])
5002 (define_insn "*floatsi<mode>2_vector_sse"
5003 [(set (match_operand:MODEF 0 "register_operand" "=x")
5004 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5005 "TARGET_SSE2 && TARGET_SSE_MATH
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5008 [(set_attr "type" "sseicvt")
5009 (set_attr "mode" "<MODE>")
5010 (set_attr "athlon_decode" "direct")
5011 (set_attr "amdfam10_decode" "double")
5012 (set_attr "bdver1_decode" "direct")
5013 (set_attr "fp_int_src" "true")])
5016 [(set (match_operand:MODEF 0 "register_operand" "")
5017 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5018 (clobber (match_operand:SI 2 "memory_operand" ""))]
5019 "TARGET_SSE2 && TARGET_SSE_MATH
5020 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5022 && (SSE_REG_P (operands[0])
5023 || (GET_CODE (operands[0]) == SUBREG
5024 && SSE_REG_P (operands[0])))"
5027 rtx op1 = operands[1];
5029 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5031 if (GET_CODE (op1) == SUBREG)
5032 op1 = SUBREG_REG (op1);
5034 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5036 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5037 emit_insn (gen_sse2_loadld (operands[4],
5038 CONST0_RTX (V4SImode), operands[1]));
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047 emit_move_insn (operands[2], operands[1]);
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[2]));
5052 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5057 [(set (match_operand:MODEF 0 "register_operand" "")
5058 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5059 (clobber (match_operand:SI 2 "memory_operand" ""))]
5060 "TARGET_SSE2 && TARGET_SSE_MATH
5061 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063 && (SSE_REG_P (operands[0])
5064 || (GET_CODE (operands[0]) == SUBREG
5065 && SSE_REG_P (operands[0])))"
5068 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5070 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5072 emit_insn (gen_sse2_loadld (operands[4],
5073 CONST0_RTX (V4SImode), operands[1]));
5075 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5080 [(set (match_operand:MODEF 0 "register_operand" "")
5081 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5082 "TARGET_SSE2 && TARGET_SSE_MATH
5083 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5085 && (SSE_REG_P (operands[0])
5086 || (GET_CODE (operands[0]) == SUBREG
5087 && SSE_REG_P (operands[0])))"
5090 rtx op1 = operands[1];
5092 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5094 if (GET_CODE (op1) == SUBREG)
5095 op1 = SUBREG_REG (op1);
5097 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5099 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5103 /* We can ignore possible trapping value in the
5104 high part of SSE register for non-trapping math. */
5105 else if (SSE_REG_P (op1) && !flag_trapping_math)
5106 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5110 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5115 [(set (match_operand:MODEF 0 "register_operand" "")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5120 && (SSE_REG_P (operands[0])
5121 || (GET_CODE (operands[0]) == SUBREG
5122 && SSE_REG_P (operands[0])))"
5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5127 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5129 emit_insn (gen_sse2_loadld (operands[4],
5130 CONST0_RTX (V4SImode), operands[1]));
5132 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5136 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5137 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5139 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5140 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5141 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5142 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5144 [(set_attr "type" "sseicvt")
5145 (set_attr "mode" "<MODEF:MODE>")
5146 (set_attr "athlon_decode" "double,direct")
5147 (set_attr "amdfam10_decode" "vector,double")
5148 (set_attr "bdver1_decode" "double,direct")
5149 (set_attr "fp_int_src" "true")])
5151 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5152 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5154 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5155 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5156 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5159 [(set_attr "type" "sseicvt")
5160 (set_attr "prefix" "maybe_vex")
5161 (set_attr "mode" "<MODEF:MODE>")
5162 (set (attr "prefix_rex")
5164 (and (eq_attr "prefix" "maybe_vex")
5165 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5167 (const_string "*")))
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5174 [(set (match_operand:MODEF 0 "register_operand" "")
5175 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5176 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5177 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5181 && (SSE_REG_P (operands[0])
5182 || (GET_CODE (operands[0]) == SUBREG
5183 && SSE_REG_P (operands[0])))"
5184 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5186 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5187 [(set (match_operand:MODEF 0 "register_operand" "=x")
5189 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5190 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5191 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5194 [(set_attr "type" "sseicvt")
5195 (set_attr "prefix" "maybe_vex")
5196 (set_attr "mode" "<MODEF:MODE>")
5197 (set (attr "prefix_rex")
5199 (and (eq_attr "prefix" "maybe_vex")
5200 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5202 (const_string "*")))
5203 (set_attr "athlon_decode" "direct")
5204 (set_attr "amdfam10_decode" "double")
5205 (set_attr "bdver1_decode" "direct")
5206 (set_attr "fp_int_src" "true")])
5209 [(set (match_operand:MODEF 0 "register_operand" "")
5210 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (operands[0])))"
5219 [(set (match_dup 2) (match_dup 1))
5220 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5225 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5229 && (SSE_REG_P (operands[0])
5230 || (GET_CODE (operands[0]) == SUBREG
5231 && SSE_REG_P (operands[0])))"
5232 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5234 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5235 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5237 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5238 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5240 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5244 [(set_attr "type" "fmov,multi")
5245 (set_attr "mode" "<X87MODEF:MODE>")
5246 (set_attr "unit" "*,i387")
5247 (set_attr "fp_int_src" "true")])
5249 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5250 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5252 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5254 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5256 [(set_attr "type" "fmov")
5257 (set_attr "mode" "<X87MODEF:MODE>")
5258 (set_attr "fp_int_src" "true")])
5261 [(set (match_operand:X87MODEF 0 "register_operand" "")
5262 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5263 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5265 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5267 && FP_REG_P (operands[0])"
5268 [(set (match_dup 2) (match_dup 1))
5269 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5272 [(set (match_operand:X87MODEF 0 "register_operand" "")
5273 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5274 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5278 && FP_REG_P (operands[0])"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers. */
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288 (clobber (match_scratch:V4SI 3 "=X,x"))
5289 (clobber (match_scratch:V4SI 4 "=X,x"))
5290 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5293 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<X87MODEF:MODE>")
5297 (set_attr "unit" "i387")
5298 (set_attr "fp_int_src" "true")])
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5303 (clobber (match_scratch:V4SI 3 ""))
5304 (clobber (match_scratch:V4SI 4 ""))
5305 (clobber (match_operand:DI 2 "memory_operand" ""))]
5306 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5310 && FP_REG_P (operands[0])"
5311 [(set (match_dup 2) (match_dup 3))
5312 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5314 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5315 Assemble the 64-bit DImode value in an xmm register. */
5316 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5317 gen_rtx_SUBREG (SImode, operands[1], 0)));
5318 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5319 gen_rtx_SUBREG (SImode, operands[1], 4)));
5320 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5323 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5327 [(set (match_operand:X87MODEF 0 "register_operand" "")
5328 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5329 (clobber (match_scratch:V4SI 3 ""))
5330 (clobber (match_scratch:V4SI 4 ""))
5331 (clobber (match_operand:DI 2 "memory_operand" ""))]
5332 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5334 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5336 && FP_REG_P (operands[0])"
5337 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5339 ;; Avoid store forwarding (partial memory) stall penalty by extending
5340 ;; SImode value to DImode through XMM register instead of pushing two
5341 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5342 ;; targets benefit from this optimization. Also note that fild
5343 ;; loads from memory only.
5345 (define_insn "*floatunssi<mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347 (unsigned_float:X87MODEF
5348 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5349 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5350 (clobber (match_scratch:SI 3 "=X,x"))]
5352 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<MODE>")])
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (unsigned_float:X87MODEF
5361 (match_operand:SI 1 "register_operand" "")))
5362 (clobber (match_operand:DI 2 "memory_operand" ""))
5363 (clobber (match_scratch:SI 3 ""))]
5365 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5367 && reload_completed"
5368 [(set (match_dup 2) (match_dup 1))
5370 (float:X87MODEF (match_dup 2)))]
5371 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5374 [(set (match_operand:X87MODEF 0 "register_operand" "")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "memory_operand" "")))
5377 (clobber (match_operand:DI 2 "memory_operand" ""))
5378 (clobber (match_scratch:SI 3 ""))]
5380 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5382 && reload_completed"
5383 [(set (match_dup 2) (match_dup 3))
5385 (float:X87MODEF (match_dup 2)))]
5387 emit_move_insn (operands[3], operands[1]);
5388 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5391 (define_expand "floatunssi<mode>2"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "")
5394 (unsigned_float:X87MODEF
5395 (match_operand:SI 1 "nonimmediate_operand" "")))
5396 (clobber (match_dup 2))
5397 (clobber (match_scratch:SI 3 ""))])]
5399 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5403 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5405 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5410 enum ix86_stack_slot slot = (virtuals_instantiated
5413 operands[2] = assign_386_stack_local (DImode, slot);
5417 (define_expand "floatunsdisf2"
5418 [(use (match_operand:SF 0 "register_operand" ""))
5419 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5420 "TARGET_64BIT && TARGET_SSE_MATH"
5421 "x86_emit_floatuns (operands); DONE;")
5423 (define_expand "floatunsdidf2"
5424 [(use (match_operand:DF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5427 && TARGET_SSE2 && TARGET_SSE_MATH"
5430 x86_emit_floatuns (operands);
5432 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5438 (define_expand "add<mode>3"
5439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5440 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5441 (match_operand:SDWIM 2 "<general_operand>" "")))]
5443 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5445 (define_insn_and_split "*add<dwi>3_doubleword"
5446 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5448 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5449 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5450 (clobber (reg:CC FLAGS_REG))]
5451 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5454 [(parallel [(set (reg:CC FLAGS_REG)
5455 (unspec:CC [(match_dup 1) (match_dup 2)]
5458 (plus:DWIH (match_dup 1) (match_dup 2)))])
5459 (parallel [(set (match_dup 3)
5463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5465 (clobber (reg:CC FLAGS_REG))])]
5466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5468 (define_insn "*add<mode>3_cc"
5469 [(set (reg:CC FLAGS_REG)
5471 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5474 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5475 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5477 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5478 [(set_attr "type" "alu")
5479 (set_attr "mode" "<MODE>")])
5481 (define_insn "addqi3_cc"
5482 [(set (reg:CC FLAGS_REG)
5484 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5485 (match_operand:QI 2 "general_operand" "qn,qm")]
5487 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5488 (plus:QI (match_dup 1) (match_dup 2)))]
5489 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5490 "add{b}\t{%2, %0|%0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "QI")])
5494 (define_insn "*lea_1"
5495 [(set (match_operand:P 0 "register_operand" "=r")
5496 (match_operand:P 1 "no_seg_address_operand" "p"))]
5498 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "<MODE>")])
5502 (define_insn "*lea_2"
5503 [(set (match_operand:SI 0 "register_operand" "=r")
5504 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5506 "lea{l}\t{%a1, %0|%0, %a1}"
5507 [(set_attr "type" "lea")
5508 (set_attr "mode" "SI")])
5510 (define_insn "*lea_2_zext"
5511 [(set (match_operand:DI 0 "register_operand" "=r")
5513 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5515 "lea{l}\t{%a1, %k0|%k0, %a1}"
5516 [(set_attr "type" "lea")
5517 (set_attr "mode" "SI")])
5519 (define_insn "*add<mode>_1"
5520 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5522 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5523 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5524 (clobber (reg:CC FLAGS_REG))]
5525 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5527 switch (get_attr_type (insn))
5533 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5534 if (operands[2] == const1_rtx)
5535 return "inc{<imodesuffix>}\t%0";
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{<imodesuffix>}\t%0";
5543 /* For most processors, ADD is faster than LEA. This alternative
5544 was added to use ADD as much as possible. */
5545 if (which_alternative == 2)
5548 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5551 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5552 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5553 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5555 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5559 (cond [(eq_attr "alternative" "3")
5560 (const_string "lea")
5561 (match_operand:SWI48 2 "incdec_operand" "")
5562 (const_string "incdec")
5564 (const_string "alu")))
5565 (set (attr "length_immediate")
5567 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5569 (const_string "*")))
5570 (set_attr "mode" "<MODE>")])
5572 ;; It may seem that nonimmediate operand is proper one for operand 1.
5573 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5574 ;; we take care in ix86_binary_operator_ok to not allow two memory
5575 ;; operands so proper swapping will be done in reload. This allow
5576 ;; patterns constructed from addsi_1 to match.
5578 (define_insn "*addsi_1_zext"
5579 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5581 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5582 (match_operand:SI 2 "general_operand" "g,0,li"))))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5586 switch (get_attr_type (insn))
5592 if (operands[2] == const1_rtx)
5593 return "inc{l}\t%k0";
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{l}\t%k0";
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 1)
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5609 if (x86_maybe_negate_const_int (&operands[2], SImode))
5610 return "sub{l}\t{%2, %k0|%k0, %2}";
5612 return "add{l}\t{%2, %k0|%k0, %2}";
5616 (cond [(eq_attr "alternative" "2")
5617 (const_string "lea")
5618 (match_operand:SI 2 "incdec_operand" "")
5619 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5626 (const_string "*")))
5627 (set_attr "mode" "SI")])
5629 (define_insn "*addhi_1"
5630 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5631 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5632 (match_operand:HI 2 "general_operand" "rn,rm")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "TARGET_PARTIAL_REG_STALL
5635 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5637 switch (get_attr_type (insn))
5640 if (operands[2] == const1_rtx)
5641 return "inc{w}\t%0";
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return "dec{w}\t%0";
5649 if (x86_maybe_negate_const_int (&operands[2], HImode))
5650 return "sub{w}\t{%2, %0|%0, %2}";
5652 return "add{w}\t{%2, %0|%0, %2}";
5656 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5657 (const_string "incdec")
5658 (const_string "alu")))
5659 (set (attr "length_immediate")
5661 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5663 (const_string "*")))
5664 (set_attr "mode" "HI")])
5666 (define_insn "*addhi_1_lea"
5667 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5668 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5669 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5670 (clobber (reg:CC FLAGS_REG))]
5671 "!TARGET_PARTIAL_REG_STALL
5672 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5674 switch (get_attr_type (insn))
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return "inc{w}\t%0";
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return "dec{w}\t%0";
5690 /* For most processors, ADD is faster than LEA. This alternative
5691 was added to use ADD as much as possible. */
5692 if (which_alternative == 2)
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], HImode))
5700 return "sub{w}\t{%2, %0|%0, %2}";
5702 return "add{w}\t{%2, %0|%0, %2}";
5706 (cond [(eq_attr "alternative" "3")
5707 (const_string "lea")
5708 (match_operand:HI 2 "incdec_operand" "")
5709 (const_string "incdec")
5711 (const_string "alu")))
5712 (set (attr "length_immediate")
5714 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5716 (const_string "*")))
5717 (set_attr "mode" "HI,HI,HI,SI")])
5719 ;; %%% Potential partial reg stall on alternative 2. What to do?
5720 (define_insn "*addqi_1"
5721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5722 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5723 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "TARGET_PARTIAL_REG_STALL
5726 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5728 int widen = (which_alternative == 2);
5729 switch (get_attr_type (insn))
5732 if (operands[2] == const1_rtx)
5733 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5736 gcc_assert (operands[2] == constm1_rtx);
5737 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5741 if (x86_maybe_negate_const_int (&operands[2], QImode))
5744 return "sub{l}\t{%2, %k0|%k0, %2}";
5746 return "sub{b}\t{%2, %0|%0, %2}";
5749 return "add{l}\t{%k2, %k0|%k0, %k2}";
5751 return "add{b}\t{%2, %0|%0, %2}";
5755 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5756 (const_string "incdec")
5757 (const_string "alu")))
5758 (set (attr "length_immediate")
5760 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5762 (const_string "*")))
5763 (set_attr "mode" "QI,QI,SI")])
5765 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5766 (define_insn "*addqi_1_lea"
5767 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5768 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5769 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5770 (clobber (reg:CC FLAGS_REG))]
5771 "!TARGET_PARTIAL_REG_STALL
5772 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5774 int widen = (which_alternative == 3 || which_alternative == 4);
5776 switch (get_attr_type (insn))
5782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783 if (operands[2] == const1_rtx)
5784 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5787 gcc_assert (operands[2] == constm1_rtx);
5788 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5792 /* For most processors, ADD is faster than LEA. These alternatives
5793 were added to use ADD as much as possible. */
5794 if (which_alternative == 2 || which_alternative == 4)
5797 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5800 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5801 if (x86_maybe_negate_const_int (&operands[2], QImode))
5804 return "sub{l}\t{%2, %k0|%k0, %2}";
5806 return "sub{b}\t{%2, %0|%0, %2}";
5809 return "add{l}\t{%k2, %k0|%k0, %k2}";
5811 return "add{b}\t{%2, %0|%0, %2}";
5815 (cond [(eq_attr "alternative" "5")
5816 (const_string "lea")
5817 (match_operand:QI 2 "incdec_operand" "")
5818 (const_string "incdec")
5820 (const_string "alu")))
5821 (set (attr "length_immediate")
5823 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5825 (const_string "*")))
5826 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5828 (define_insn "*addqi_1_slp"
5829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5830 (plus:QI (match_dup 0)
5831 (match_operand:QI 1 "general_operand" "qn,qnm")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5836 switch (get_attr_type (insn))
5839 if (operands[1] == const1_rtx)
5840 return "inc{b}\t%0";
5843 gcc_assert (operands[1] == constm1_rtx);
5844 return "dec{b}\t%0";
5848 if (x86_maybe_negate_const_int (&operands[1], QImode))
5849 return "sub{b}\t{%1, %0|%0, %1}";
5851 return "add{b}\t{%1, %0|%0, %1}";
5855 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu1")))
5858 (set (attr "memory")
5859 (if_then_else (match_operand 1 "memory_operand" "")
5860 (const_string "load")
5861 (const_string "none")))
5862 (set_attr "mode" "QI")])
5864 ;; Convert lea to the lea pattern to avoid flags dependency.
5866 [(set (match_operand 0 "register_operand" "")
5867 (plus (match_operand 1 "register_operand" "")
5868 (match_operand 2 "nonmemory_operand" "")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5874 enum machine_mode mode = GET_MODE (operands[0]);
5876 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5877 may confuse gen_lowpart. */
5880 operands[1] = gen_lowpart (Pmode, operands[1]);
5881 operands[2] = gen_lowpart (Pmode, operands[2]);
5884 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5886 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5887 operands[0] = gen_lowpart (SImode, operands[0]);
5889 if (TARGET_64BIT && mode != Pmode)
5890 pat = gen_rtx_SUBREG (SImode, pat, 0);
5892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5896 ;; Convert lea to the lea pattern to avoid flags dependency.
5897 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5898 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5900 [(set (match_operand:DI 0 "register_operand" "")
5901 (plus:DI (match_operand:DI 1 "register_operand" "")
5902 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5903 (clobber (reg:CC FLAGS_REG))]
5904 "TARGET_64BIT && reload_completed
5905 && true_regnum (operands[0]) != true_regnum (operands[1])"
5907 (plus:DI (match_dup 1) (match_dup 2)))])
5909 ;; Convert lea to the lea pattern to avoid flags dependency.
5911 [(set (match_operand:DI 0 "register_operand" "")
5913 (plus:SI (match_operand:SI 1 "register_operand" "")
5914 (match_operand:SI 2 "nonmemory_operand" ""))))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "TARGET_64BIT && reload_completed
5917 && ix86_lea_for_add_ok (insn, operands)"
5919 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5921 operands[1] = gen_lowpart (DImode, operands[1]);
5922 operands[2] = gen_lowpart (DImode, operands[2]);
5925 (define_insn "*add<mode>_2"
5926 [(set (reg FLAGS_REG)
5929 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5930 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5932 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5933 (plus:SWI (match_dup 1) (match_dup 2)))]
5934 "ix86_match_ccmode (insn, CCGOCmode)
5935 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5937 switch (get_attr_type (insn))
5940 if (operands[2] == const1_rtx)
5941 return "inc{<imodesuffix>}\t%0";
5944 gcc_assert (operands[2] == constm1_rtx);
5945 return "dec{<imodesuffix>}\t%0";
5949 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5950 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5952 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5956 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5957 (const_string "incdec")
5958 (const_string "alu")))
5959 (set (attr "length_immediate")
5961 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5963 (const_string "*")))
5964 (set_attr "mode" "<MODE>")])
5966 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5967 (define_insn "*addsi_2_zext"
5968 [(set (reg FLAGS_REG)
5970 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5971 (match_operand:SI 2 "general_operand" "g"))
5973 (set (match_operand:DI 0 "register_operand" "=r")
5974 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5975 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5976 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5978 switch (get_attr_type (insn))
5981 if (operands[2] == const1_rtx)
5982 return "inc{l}\t%k0";
5985 gcc_assert (operands[2] == constm1_rtx);
5986 return "dec{l}\t%k0";
5990 if (x86_maybe_negate_const_int (&operands[2], SImode))
5991 return "sub{l}\t{%2, %k0|%k0, %2}";
5993 return "add{l}\t{%2, %k0|%k0, %2}";
5997 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5998 (const_string "incdec")
5999 (const_string "alu")))
6000 (set (attr "length_immediate")
6002 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004 (const_string "*")))
6005 (set_attr "mode" "SI")])
6007 (define_insn "*add<mode>_3"
6008 [(set (reg FLAGS_REG)
6010 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6011 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6012 (clobber (match_scratch:SWI 0 "=<r>"))]
6013 "ix86_match_ccmode (insn, CCZmode)
6014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6016 switch (get_attr_type (insn))
6019 if (operands[2] == const1_rtx)
6020 return "inc{<imodesuffix>}\t%0";
6023 gcc_assert (operands[2] == constm1_rtx);
6024 return "dec{<imodesuffix>}\t%0";
6028 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6029 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6031 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6035 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6036 (const_string "incdec")
6037 (const_string "alu")))
6038 (set (attr "length_immediate")
6040 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6042 (const_string "*")))
6043 (set_attr "mode" "<MODE>")])
6045 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6046 (define_insn "*addsi_3_zext"
6047 [(set (reg FLAGS_REG)
6049 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6050 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6051 (set (match_operand:DI 0 "register_operand" "=r")
6052 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6054 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6056 switch (get_attr_type (insn))
6059 if (operands[2] == const1_rtx)
6060 return "inc{l}\t%k0";
6063 gcc_assert (operands[2] == constm1_rtx);
6064 return "dec{l}\t%k0";
6068 if (x86_maybe_negate_const_int (&operands[2], SImode))
6069 return "sub{l}\t{%2, %k0|%k0, %2}";
6071 return "add{l}\t{%2, %k0|%k0, %2}";
6075 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set (attr "length_immediate")
6080 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6082 (const_string "*")))
6083 (set_attr "mode" "SI")])
6085 ; For comparisons against 1, -1 and 128, we may generate better code
6086 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6087 ; is matched then. We can't accept general immediate, because for
6088 ; case of overflows, the result is messed up.
6089 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6090 ; only for comparisons not depending on it.
6092 (define_insn "*adddi_4"
6093 [(set (reg FLAGS_REG)
6095 (match_operand:DI 1 "nonimmediate_operand" "0")
6096 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6097 (clobber (match_scratch:DI 0 "=rm"))]
6099 && ix86_match_ccmode (insn, CCGCmode)"
6101 switch (get_attr_type (insn))
6104 if (operands[2] == constm1_rtx)
6105 return "inc{q}\t%0";
6108 gcc_assert (operands[2] == const1_rtx);
6109 return "dec{q}\t%0";
6113 if (x86_maybe_negate_const_int (&operands[2], DImode))
6114 return "add{q}\t{%2, %0|%0, %2}";
6116 return "sub{q}\t{%2, %0|%0, %2}";
6120 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set (attr "length_immediate")
6125 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6127 (const_string "*")))
6128 (set_attr "mode" "DI")])
6130 ; For comparisons against 1, -1 and 128, we may generate better code
6131 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6132 ; is matched then. We can't accept general immediate, because for
6133 ; case of overflows, the result is messed up.
6134 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6135 ; only for comparisons not depending on it.
6137 (define_insn "*add<mode>_4"
6138 [(set (reg FLAGS_REG)
6140 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6141 (match_operand:SWI124 2 "const_int_operand" "n")))
6142 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6143 "ix86_match_ccmode (insn, CCGCmode)"
6145 switch (get_attr_type (insn))
6148 if (operands[2] == constm1_rtx)
6149 return "inc{<imodesuffix>}\t%0";
6152 gcc_assert (operands[2] == const1_rtx);
6153 return "dec{<imodesuffix>}\t%0";
6157 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6158 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6160 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6164 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6165 (const_string "incdec")
6166 (const_string "alu")))
6167 (set (attr "length_immediate")
6169 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6171 (const_string "*")))
6172 (set_attr "mode" "<MODE>")])
6174 (define_insn "*add<mode>_5"
6175 [(set (reg FLAGS_REG)
6178 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6179 (match_operand:SWI 2 "<general_operand>" "<g>"))
6181 (clobber (match_scratch:SWI 0 "=<r>"))]
6182 "ix86_match_ccmode (insn, CCGOCmode)
6183 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6185 switch (get_attr_type (insn))
6188 if (operands[2] == const1_rtx)
6189 return "inc{<imodesuffix>}\t%0";
6192 gcc_assert (operands[2] == constm1_rtx);
6193 return "dec{<imodesuffix>}\t%0";
6197 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6198 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6200 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6204 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6205 (const_string "incdec")
6206 (const_string "alu")))
6207 (set (attr "length_immediate")
6209 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6211 (const_string "*")))
6212 (set_attr "mode" "<MODE>")])
6214 (define_insn "*addqi_ext_1_rex64"
6215 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6220 (match_operand 1 "ext_register_operand" "0")
6223 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6224 (clobber (reg:CC FLAGS_REG))]
6227 switch (get_attr_type (insn))
6230 if (operands[2] == const1_rtx)
6231 return "inc{b}\t%h0";
6234 gcc_assert (operands[2] == constm1_rtx);
6235 return "dec{b}\t%h0";
6239 return "add{b}\t{%2, %h0|%h0, %2}";
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "modrm" "1")
6247 (set_attr "mode" "QI")])
6249 (define_insn "addqi_ext_1"
6250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6255 (match_operand 1 "ext_register_operand" "0")
6258 (match_operand:QI 2 "general_operand" "Qmn")))
6259 (clobber (reg:CC FLAGS_REG))]
6262 switch (get_attr_type (insn))
6265 if (operands[2] == const1_rtx)
6266 return "inc{b}\t%h0";
6269 gcc_assert (operands[2] == constm1_rtx);
6270 return "dec{b}\t%h0";
6274 return "add{b}\t{%2, %h0|%h0, %2}";
6278 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "modrm" "1")
6282 (set_attr "mode" "QI")])
6284 (define_insn "*addqi_ext_2"
6285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6290 (match_operand 1 "ext_register_operand" "%0")
6294 (match_operand 2 "ext_register_operand" "Q")
6297 (clobber (reg:CC FLAGS_REG))]
6299 "add{b}\t{%h2, %h0|%h0, %h2}"
6300 [(set_attr "type" "alu")
6301 (set_attr "mode" "QI")])
6303 ;; The lea patterns for non-Pmodes needs to be matched by
6304 ;; several insns converted to real lea by splitters.
6306 (define_insn_and_split "*lea_general_1"
6307 [(set (match_operand 0 "register_operand" "=r")
6308 (plus (plus (match_operand 1 "index_register_operand" "l")
6309 (match_operand 2 "register_operand" "r"))
6310 (match_operand 3 "immediate_operand" "i")))]
6311 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6312 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6313 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6314 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6315 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6316 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6317 || GET_MODE (operands[3]) == VOIDmode)"
6319 "&& reload_completed"
6323 operands[0] = gen_lowpart (SImode, operands[0]);
6324 operands[1] = gen_lowpart (Pmode, operands[1]);
6325 operands[2] = gen_lowpart (Pmode, operands[2]);
6326 operands[3] = gen_lowpart (Pmode, operands[3]);
6327 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6329 if (Pmode != SImode)
6330 pat = gen_rtx_SUBREG (SImode, pat, 0);
6331 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6334 [(set_attr "type" "lea")
6335 (set_attr "mode" "SI")])
6337 (define_insn_and_split "*lea_general_1_zext"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6341 (match_operand:SI 1 "index_register_operand" "l")
6342 (match_operand:SI 2 "register_operand" "r"))
6343 (match_operand:SI 3 "immediate_operand" "i"))))]
6346 "&& reload_completed"
6348 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6350 (match_dup 3)) 0)))]
6352 operands[1] = gen_lowpart (Pmode, operands[1]);
6353 operands[2] = gen_lowpart (Pmode, operands[2]);
6354 operands[3] = gen_lowpart (Pmode, operands[3]);
6356 [(set_attr "type" "lea")
6357 (set_attr "mode" "SI")])
6359 (define_insn_and_split "*lea_general_2"
6360 [(set (match_operand 0 "register_operand" "=r")
6361 (plus (mult (match_operand 1 "index_register_operand" "l")
6362 (match_operand 2 "const248_operand" "i"))
6363 (match_operand 3 "nonmemory_operand" "ri")))]
6364 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6365 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6366 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6367 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6368 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6369 || GET_MODE (operands[3]) == VOIDmode)"
6371 "&& reload_completed"
6375 operands[0] = gen_lowpart (SImode, operands[0]);
6376 operands[1] = gen_lowpart (Pmode, operands[1]);
6377 operands[3] = gen_lowpart (Pmode, operands[3]);
6378 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6380 if (Pmode != SImode)
6381 pat = gen_rtx_SUBREG (SImode, pat, 0);
6382 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6385 [(set_attr "type" "lea")
6386 (set_attr "mode" "SI")])
6388 (define_insn_and_split "*lea_general_2_zext"
6389 [(set (match_operand:DI 0 "register_operand" "=r")
6392 (match_operand:SI 1 "index_register_operand" "l")
6393 (match_operand:SI 2 "const248_operand" "n"))
6394 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6397 "&& reload_completed"
6399 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6401 (match_dup 3)) 0)))]
6403 operands[1] = gen_lowpart (Pmode, operands[1]);
6404 operands[3] = gen_lowpart (Pmode, operands[3]);
6406 [(set_attr "type" "lea")
6407 (set_attr "mode" "SI")])
6409 (define_insn_and_split "*lea_general_3"
6410 [(set (match_operand 0 "register_operand" "=r")
6411 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6412 (match_operand 2 "const248_operand" "i"))
6413 (match_operand 3 "register_operand" "r"))
6414 (match_operand 4 "immediate_operand" "i")))]
6415 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6416 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6417 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6418 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6419 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6421 "&& reload_completed"
6425 operands[0] = gen_lowpart (SImode, operands[0]);
6426 operands[1] = gen_lowpart (Pmode, operands[1]);
6427 operands[3] = gen_lowpart (Pmode, operands[3]);
6428 operands[4] = gen_lowpart (Pmode, operands[4]);
6429 pat = gen_rtx_PLUS (Pmode,
6430 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6434 if (Pmode != SImode)
6435 pat = gen_rtx_SUBREG (SImode, pat, 0);
6436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6439 [(set_attr "type" "lea")
6440 (set_attr "mode" "SI")])
6442 (define_insn_and_split "*lea_general_3_zext"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6447 (match_operand:SI 1 "index_register_operand" "l")
6448 (match_operand:SI 2 "const248_operand" "n"))
6449 (match_operand:SI 3 "register_operand" "r"))
6450 (match_operand:SI 4 "immediate_operand" "i"))))]
6453 "&& reload_completed"
6455 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6458 (match_dup 4)) 0)))]
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[3] = gen_lowpart (Pmode, operands[3]);
6462 operands[4] = gen_lowpart (Pmode, operands[4]);
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6467 ;; Subtract instructions
6469 (define_expand "sub<mode>3"
6470 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6471 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6472 (match_operand:SDWIM 2 "<general_operand>" "")))]
6474 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6476 (define_insn_and_split "*sub<dwi>3_doubleword"
6477 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6479 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6480 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6481 (clobber (reg:CC FLAGS_REG))]
6482 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6485 [(parallel [(set (reg:CC FLAGS_REG)
6486 (compare:CC (match_dup 1) (match_dup 2)))
6488 (minus:DWIH (match_dup 1) (match_dup 2)))])
6489 (parallel [(set (match_dup 3)
6493 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6498 (define_insn "*sub<mode>_1"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6501 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6502 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6503 (clobber (reg:CC FLAGS_REG))]
6504 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6509 (define_insn "*subsi_1_zext"
6510 [(set (match_operand:DI 0 "register_operand" "=r")
6512 (minus:SI (match_operand:SI 1 "register_operand" "0")
6513 (match_operand:SI 2 "general_operand" "g"))))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516 "sub{l}\t{%2, %k0|%k0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "SI")])
6520 (define_insn "*subqi_1_slp"
6521 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6522 (minus:QI (match_dup 0)
6523 (match_operand:QI 1 "general_operand" "qn,qm")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6527 "sub{b}\t{%1, %0|%0, %1}"
6528 [(set_attr "type" "alu1")
6529 (set_attr "mode" "QI")])
6531 (define_insn "*sub<mode>_2"
6532 [(set (reg FLAGS_REG)
6535 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6539 (minus:SWI (match_dup 1) (match_dup 2)))]
6540 "ix86_match_ccmode (insn, CCGOCmode)
6541 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6542 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "<MODE>")])
6546 (define_insn "*subsi_2_zext"
6547 [(set (reg FLAGS_REG)
6549 (minus:SI (match_operand:SI 1 "register_operand" "0")
6550 (match_operand:SI 2 "general_operand" "g"))
6552 (set (match_operand:DI 0 "register_operand" "=r")
6554 (minus:SI (match_dup 1)
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{l}\t{%2, %k0|%k0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "SI")])
6562 (define_insn "*sub<mode>_3"
6563 [(set (reg FLAGS_REG)
6564 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6565 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6566 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6567 (minus:SWI (match_dup 1) (match_dup 2)))]
6568 "ix86_match_ccmode (insn, CCmode)
6569 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6570 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "<MODE>")])
6574 (define_insn "*subsi_3_zext"
6575 [(set (reg FLAGS_REG)
6576 (compare (match_operand:SI 1 "register_operand" "0")
6577 (match_operand:SI 2 "general_operand" "g")))
6578 (set (match_operand:DI 0 "register_operand" "=r")
6580 (minus:SI (match_dup 1)
6582 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6583 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6584 "sub{l}\t{%2, %1|%1, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "mode" "SI")])
6588 ;; Add with carry and subtract with borrow
6590 (define_expand "<plusminus_insn><mode>3_carry"
6592 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6594 (match_operand:SWI 1 "nonimmediate_operand" "")
6595 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6596 [(match_operand 3 "flags_reg_operand" "")
6598 (match_operand:SWI 2 "<general_operand>" ""))))
6599 (clobber (reg:CC FLAGS_REG))])]
6600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6602 (define_insn "*<plusminus_insn><mode>3_carry"
6603 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6605 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6607 (match_operator 3 "ix86_carry_flag_operator"
6608 [(reg FLAGS_REG) (const_int 0)])
6609 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6612 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "use_carry" "1")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "<MODE>")])
6618 (define_insn "*addsi3_carry_zext"
6619 [(set (match_operand:DI 0 "register_operand" "=r")
6621 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6622 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6623 [(reg FLAGS_REG) (const_int 0)])
6624 (match_operand:SI 2 "general_operand" "g")))))
6625 (clobber (reg:CC FLAGS_REG))]
6626 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6627 "adc{l}\t{%2, %k0|%k0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "use_carry" "1")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6633 (define_insn "*subsi3_carry_zext"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6636 (minus:SI (match_operand:SI 1 "register_operand" "0")
6637 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6638 [(reg FLAGS_REG) (const_int 0)])
6639 (match_operand:SI 2 "general_operand" "g")))))
6640 (clobber (reg:CC FLAGS_REG))]
6641 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642 "sbb{l}\t{%2, %k0|%k0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "pent_pair" "pu")
6645 (set_attr "mode" "SI")])
6647 ;; Overflow setting add and subtract instructions
6649 (define_insn "*add<mode>3_cconly_overflow"
6650 [(set (reg:CCC FLAGS_REG)
6653 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6654 (match_operand:SWI 2 "<general_operand>" "<g>"))
6656 (clobber (match_scratch:SWI 0 "=<r>"))]
6657 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6658 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6659 [(set_attr "type" "alu")
6660 (set_attr "mode" "<MODE>")])
6662 (define_insn "*sub<mode>3_cconly_overflow"
6663 [(set (reg:CCC FLAGS_REG)
6666 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6667 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6670 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6671 [(set_attr "type" "icmp")
6672 (set_attr "mode" "<MODE>")])
6674 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6675 [(set (reg:CCC FLAGS_REG)
6678 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6679 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6681 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6682 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6683 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6684 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "<MODE>")])
6688 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6689 [(set (reg:CCC FLAGS_REG)
6692 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6693 (match_operand:SI 2 "general_operand" "g"))
6695 (set (match_operand:DI 0 "register_operand" "=r")
6696 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6697 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6698 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6702 ;; The patterns that match these are at the end of this file.
6704 (define_expand "<plusminus_insn>xf3"
6705 [(set (match_operand:XF 0 "register_operand" "")
6707 (match_operand:XF 1 "register_operand" "")
6708 (match_operand:XF 2 "register_operand" "")))]
6711 (define_expand "<plusminus_insn><mode>3"
6712 [(set (match_operand:MODEF 0 "register_operand" "")
6714 (match_operand:MODEF 1 "register_operand" "")
6715 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6716 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6717 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6719 ;; Multiply instructions
6721 (define_expand "mul<mode>3"
6722 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6724 (match_operand:SWIM248 1 "register_operand" "")
6725 (match_operand:SWIM248 2 "<general_operand>" "")))
6726 (clobber (reg:CC FLAGS_REG))])])
6728 (define_expand "mulqi3"
6729 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6731 (match_operand:QI 1 "register_operand" "")
6732 (match_operand:QI 2 "nonimmediate_operand" "")))
6733 (clobber (reg:CC FLAGS_REG))])]
6734 "TARGET_QIMODE_MATH")
6737 ;; IMUL reg32/64, reg32/64, imm8 Direct
6738 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6739 ;; IMUL reg32/64, reg32/64, imm32 Direct
6740 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6741 ;; IMUL reg32/64, reg32/64 Direct
6742 ;; IMUL reg32/64, mem32/64 Direct
6744 ;; On BDVER1, all above IMULs use DirectPath
6746 (define_insn "*mul<mode>3_1"
6747 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6749 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6750 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6751 (clobber (reg:CC FLAGS_REG))]
6752 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6754 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6755 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6756 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "imul")
6758 (set_attr "prefix_0f" "0,0,1")
6759 (set (attr "athlon_decode")
6760 (cond [(eq_attr "cpu" "athlon")
6761 (const_string "vector")
6762 (eq_attr "alternative" "1")
6763 (const_string "vector")
6764 (and (eq_attr "alternative" "2")
6765 (match_operand 1 "memory_operand" ""))
6766 (const_string "vector")]
6767 (const_string "direct")))
6768 (set (attr "amdfam10_decode")
6769 (cond [(and (eq_attr "alternative" "0,1")
6770 (match_operand 1 "memory_operand" ""))
6771 (const_string "vector")]
6772 (const_string "direct")))
6773 (set_attr "bdver1_decode" "direct")
6774 (set_attr "mode" "<MODE>")])
6776 (define_insn "*mulsi3_1_zext"
6777 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6779 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6780 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6781 (clobber (reg:CC FLAGS_REG))]
6783 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6785 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6786 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6787 imul{l}\t{%2, %k0|%k0, %2}"
6788 [(set_attr "type" "imul")
6789 (set_attr "prefix_0f" "0,0,1")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "cpu" "athlon")
6792 (const_string "vector")
6793 (eq_attr "alternative" "1")
6794 (const_string "vector")
6795 (and (eq_attr "alternative" "2")
6796 (match_operand 1 "memory_operand" ""))
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(and (eq_attr "alternative" "0,1")
6801 (match_operand 1 "memory_operand" ""))
6802 (const_string "vector")]
6803 (const_string "direct")))
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "SI")])
6808 ;; IMUL reg16, reg16, imm8 VectorPath
6809 ;; IMUL reg16, mem16, imm8 VectorPath
6810 ;; IMUL reg16, reg16, imm16 VectorPath
6811 ;; IMUL reg16, mem16, imm16 VectorPath
6812 ;; IMUL reg16, reg16 Direct
6813 ;; IMUL reg16, mem16 Direct
6815 ;; On BDVER1, all HI MULs use DoublePath
6817 (define_insn "*mulhi3_1"
6818 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6819 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6820 (match_operand:HI 2 "general_operand" "K,n,mr")))
6821 (clobber (reg:CC FLAGS_REG))]
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 imul{w}\t{%2, %1, %0|%0, %1, %2}
6826 imul{w}\t{%2, %1, %0|%0, %1, %2}
6827 imul{w}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "imul")
6829 (set_attr "prefix_0f" "0,0,1")
6830 (set (attr "athlon_decode")
6831 (cond [(eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (eq_attr "alternative" "1,2")
6834 (const_string "vector")]
6835 (const_string "direct")))
6836 (set (attr "amdfam10_decode")
6837 (cond [(eq_attr "alternative" "0,1")
6838 (const_string "vector")]
6839 (const_string "direct")))
6840 (set_attr "bdver1_decode" "double")
6841 (set_attr "mode" "HI")])
6843 ;;On AMDFAM10 and BDVER1
6847 (define_insn "*mulqi3_1"
6848 [(set (match_operand:QI 0 "register_operand" "=a")
6849 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6850 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6851 (clobber (reg:CC FLAGS_REG))]
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 [(set_attr "type" "imul")
6856 (set_attr "length_immediate" "0")
6857 (set (attr "athlon_decode")
6858 (if_then_else (eq_attr "cpu" "athlon")
6859 (const_string "vector")
6860 (const_string "direct")))
6861 (set_attr "amdfam10_decode" "direct")
6862 (set_attr "bdver1_decode" "direct")
6863 (set_attr "mode" "QI")])
6865 (define_expand "<u>mul<mode><dwi>3"
6866 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6869 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6871 (match_operand:DWIH 2 "register_operand" ""))))
6872 (clobber (reg:CC FLAGS_REG))])])
6874 (define_expand "<u>mulqihi3"
6875 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6878 (match_operand:QI 1 "nonimmediate_operand" ""))
6880 (match_operand:QI 2 "register_operand" ""))))
6881 (clobber (reg:CC FLAGS_REG))])]
6882 "TARGET_QIMODE_MATH")
6884 (define_insn "*<u>mul<mode><dwi>3_1"
6885 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6888 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6890 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6891 (clobber (reg:CC FLAGS_REG))]
6892 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "<sgnprefix>mul{<imodesuffix>}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "double")))
6900 (set_attr "amdfam10_decode" "double")
6901 (set_attr "bdver1_decode" "direct")
6902 (set_attr "mode" "<MODE>")])
6904 (define_insn "*<u>mulqihi3_1"
6905 [(set (match_operand:HI 0 "register_operand" "=a")
6908 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6910 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6911 (clobber (reg:CC FLAGS_REG))]
6913 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 "<sgnprefix>mul{b}\t%2"
6915 [(set_attr "type" "imul")
6916 (set_attr "length_immediate" "0")
6917 (set (attr "athlon_decode")
6918 (if_then_else (eq_attr "cpu" "athlon")
6919 (const_string "vector")
6920 (const_string "direct")))
6921 (set_attr "amdfam10_decode" "direct")
6922 (set_attr "bdver1_decode" "direct")
6923 (set_attr "mode" "QI")])
6925 (define_expand "<s>mul<mode>3_highpart"
6926 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6931 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6933 (match_operand:SWI48 2 "register_operand" "")))
6935 (clobber (match_scratch:SWI48 3 ""))
6936 (clobber (reg:CC FLAGS_REG))])]
6938 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6940 (define_insn "*<s>muldi3_highpart_1"
6941 [(set (match_operand:DI 0 "register_operand" "=d")
6946 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6948 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6950 (clobber (match_scratch:DI 3 "=1"))
6951 (clobber (reg:CC FLAGS_REG))]
6953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6954 "<sgnprefix>mul{q}\t%2"
6955 [(set_attr "type" "imul")
6956 (set_attr "length_immediate" "0")
6957 (set (attr "athlon_decode")
6958 (if_then_else (eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (const_string "double")))
6961 (set_attr "amdfam10_decode" "double")
6962 (set_attr "bdver1_decode" "direct")
6963 (set_attr "mode" "DI")])
6965 (define_insn "*<s>mulsi3_highpart_1"
6966 [(set (match_operand:SI 0 "register_operand" "=d")
6971 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6973 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6975 (clobber (match_scratch:SI 3 "=1"))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978 "<sgnprefix>mul{l}\t%2"
6979 [(set_attr "type" "imul")
6980 (set_attr "length_immediate" "0")
6981 (set (attr "athlon_decode")
6982 (if_then_else (eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (const_string "double")))
6985 (set_attr "amdfam10_decode" "double")
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "SI")])
6989 (define_insn "*<s>mulsi3_highpart_zext"
6990 [(set (match_operand:DI 0 "register_operand" "=d")
6991 (zero_extend:DI (truncate:SI
6993 (mult:DI (any_extend:DI
6994 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6996 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6998 (clobber (match_scratch:SI 3 "=1"))
6999 (clobber (reg:CC FLAGS_REG))]
7001 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 "<sgnprefix>mul{l}\t%2"
7003 [(set_attr "type" "imul")
7004 (set_attr "length_immediate" "0")
7005 (set (attr "athlon_decode")
7006 (if_then_else (eq_attr "cpu" "athlon")
7007 (const_string "vector")
7008 (const_string "double")))
7009 (set_attr "amdfam10_decode" "double")
7010 (set_attr "bdver1_decode" "direct")
7011 (set_attr "mode" "SI")])
7013 ;; The patterns that match these are at the end of this file.
7015 (define_expand "mulxf3"
7016 [(set (match_operand:XF 0 "register_operand" "")
7017 (mult:XF (match_operand:XF 1 "register_operand" "")
7018 (match_operand:XF 2 "register_operand" "")))]
7021 (define_expand "mul<mode>3"
7022 [(set (match_operand:MODEF 0 "register_operand" "")
7023 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7024 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7025 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7028 ;; Divide instructions
7030 ;; The patterns that match these are at the end of this file.
7032 (define_expand "divxf3"
7033 [(set (match_operand:XF 0 "register_operand" "")
7034 (div:XF (match_operand:XF 1 "register_operand" "")
7035 (match_operand:XF 2 "register_operand" "")))]
7038 (define_expand "divdf3"
7039 [(set (match_operand:DF 0 "register_operand" "")
7040 (div:DF (match_operand:DF 1 "register_operand" "")
7041 (match_operand:DF 2 "nonimmediate_operand" "")))]
7042 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7043 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7045 (define_expand "divsf3"
7046 [(set (match_operand:SF 0 "register_operand" "")
7047 (div:SF (match_operand:SF 1 "register_operand" "")
7048 (match_operand:SF 2 "nonimmediate_operand" "")))]
7049 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7052 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7053 && flag_finite_math_only && !flag_trapping_math
7054 && flag_unsafe_math_optimizations)
7056 ix86_emit_swdivsf (operands[0], operands[1],
7057 operands[2], SFmode);
7062 ;; Divmod instructions.
7064 (define_expand "divmod<mode>4"
7065 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7067 (match_operand:SWIM248 1 "register_operand" "")
7068 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7069 (set (match_operand:SWIM248 3 "register_operand" "")
7070 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7071 (clobber (reg:CC FLAGS_REG))])])
7073 ;; Split with 8bit unsigned divide:
7074 ;; if (dividend an divisor are in [0-255])
7075 ;; use 8bit unsigned integer divide
7077 ;; use original integer divide
7079 [(set (match_operand:SWI48 0 "register_operand" "")
7080 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7081 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7082 (set (match_operand:SWI48 1 "register_operand" "")
7083 (mod:SWI48 (match_dup 2) (match_dup 3)))
7084 (clobber (reg:CC FLAGS_REG))]
7085 "TARGET_USE_8BIT_IDIV
7086 && TARGET_QIMODE_MATH
7087 && can_create_pseudo_p ()
7088 && !optimize_insn_for_size_p ()"
7090 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7092 (define_insn_and_split "divmod<mode>4_1"
7093 [(set (match_operand:SWI48 0 "register_operand" "=a")
7094 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7095 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7096 (set (match_operand:SWI48 1 "register_operand" "=&d")
7097 (mod:SWI48 (match_dup 2) (match_dup 3)))
7098 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7099 (clobber (reg:CC FLAGS_REG))]
7103 [(parallel [(set (match_dup 1)
7104 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7105 (clobber (reg:CC FLAGS_REG))])
7106 (parallel [(set (match_dup 0)
7107 (div:SWI48 (match_dup 2) (match_dup 3)))
7109 (mod:SWI48 (match_dup 2) (match_dup 3)))
7111 (clobber (reg:CC FLAGS_REG))])]
7113 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7115 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7116 operands[4] = operands[2];
7119 /* Avoid use of cltd in favor of a mov+shift. */
7120 emit_move_insn (operands[1], operands[2]);
7121 operands[4] = operands[1];
7124 [(set_attr "type" "multi")
7125 (set_attr "mode" "<MODE>")])
7127 (define_insn_and_split "*divmod<mode>4"
7128 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7129 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7130 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7131 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7132 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7133 (clobber (reg:CC FLAGS_REG))]
7137 [(parallel [(set (match_dup 1)
7138 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7139 (clobber (reg:CC FLAGS_REG))])
7140 (parallel [(set (match_dup 0)
7141 (div:SWIM248 (match_dup 2) (match_dup 3)))
7143 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7145 (clobber (reg:CC FLAGS_REG))])]
7147 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7149 if (<MODE>mode != HImode
7150 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7151 operands[4] = operands[2];
7154 /* Avoid use of cltd in favor of a mov+shift. */
7155 emit_move_insn (operands[1], operands[2]);
7156 operands[4] = operands[1];
7159 [(set_attr "type" "multi")
7160 (set_attr "mode" "<MODE>")])
7162 (define_insn "*divmod<mode>4_noext"
7163 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7164 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7165 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7166 (set (match_operand:SWIM248 1 "register_operand" "=d")
7167 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7168 (use (match_operand:SWIM248 4 "register_operand" "1"))
7169 (clobber (reg:CC FLAGS_REG))]
7171 "idiv{<imodesuffix>}\t%3"
7172 [(set_attr "type" "idiv")
7173 (set_attr "mode" "<MODE>")])
7175 (define_expand "divmodqi4"
7176 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7178 (match_operand:QI 1 "register_operand" "")
7179 (match_operand:QI 2 "nonimmediate_operand" "")))
7180 (set (match_operand:QI 3 "register_operand" "")
7181 (mod:QI (match_dup 1) (match_dup 2)))
7182 (clobber (reg:CC FLAGS_REG))])]
7183 "TARGET_QIMODE_MATH"
7188 tmp0 = gen_reg_rtx (HImode);
7189 tmp1 = gen_reg_rtx (HImode);
7191 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7193 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7194 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7196 /* Extract remainder from AH. */
7197 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7198 insn = emit_move_insn (operands[3], tmp1);
7200 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7201 set_unique_reg_note (insn, REG_EQUAL, mod);
7203 /* Extract quotient from AL. */
7204 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7206 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7207 set_unique_reg_note (insn, REG_EQUAL, div);
7212 ;; Divide AX by r/m8, with result stored in
7215 ;; Change div/mod to HImode and extend the second argument to HImode
7216 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7217 ;; combine may fail.
7218 (define_insn "divmodhiqi3"
7219 [(set (match_operand:HI 0 "register_operand" "=a")
7224 (mod:HI (match_operand:HI 1 "register_operand" "0")
7226 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7230 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "TARGET_QIMODE_MATH"
7234 [(set_attr "type" "idiv")
7235 (set_attr "mode" "QI")])
7237 (define_expand "udivmod<mode>4"
7238 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7240 (match_operand:SWIM248 1 "register_operand" "")
7241 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7242 (set (match_operand:SWIM248 3 "register_operand" "")
7243 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7244 (clobber (reg:CC FLAGS_REG))])])
7246 ;; Split with 8bit unsigned divide:
7247 ;; if (dividend an divisor are in [0-255])
7248 ;; use 8bit unsigned integer divide
7250 ;; use original integer divide
7252 [(set (match_operand:SWI48 0 "register_operand" "")
7253 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7254 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7255 (set (match_operand:SWI48 1 "register_operand" "")
7256 (umod:SWI48 (match_dup 2) (match_dup 3)))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "TARGET_USE_8BIT_IDIV
7259 && TARGET_QIMODE_MATH
7260 && can_create_pseudo_p ()
7261 && !optimize_insn_for_size_p ()"
7263 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7265 (define_insn_and_split "udivmod<mode>4_1"
7266 [(set (match_operand:SWI48 0 "register_operand" "=a")
7267 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7268 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7269 (set (match_operand:SWI48 1 "register_operand" "=&d")
7270 (umod:SWI48 (match_dup 2) (match_dup 3)))
7271 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7272 (clobber (reg:CC FLAGS_REG))]
7276 [(set (match_dup 1) (const_int 0))
7277 (parallel [(set (match_dup 0)
7278 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7280 (umod:SWI48 (match_dup 2) (match_dup 3)))
7282 (clobber (reg:CC FLAGS_REG))])]
7284 [(set_attr "type" "multi")
7285 (set_attr "mode" "<MODE>")])
7287 (define_insn_and_split "*udivmod<mode>4"
7288 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7289 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7290 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7291 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7292 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7293 (clobber (reg:CC FLAGS_REG))]
7297 [(set (match_dup 1) (const_int 0))
7298 (parallel [(set (match_dup 0)
7299 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7301 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (clobber (reg:CC FLAGS_REG))])]
7305 [(set_attr "type" "multi")
7306 (set_attr "mode" "<MODE>")])
7308 (define_insn "*udivmod<mode>4_noext"
7309 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7310 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7311 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7312 (set (match_operand:SWIM248 1 "register_operand" "=d")
7313 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7314 (use (match_operand:SWIM248 4 "register_operand" "1"))
7315 (clobber (reg:CC FLAGS_REG))]
7317 "div{<imodesuffix>}\t%3"
7318 [(set_attr "type" "idiv")
7319 (set_attr "mode" "<MODE>")])
7321 (define_expand "udivmodqi4"
7322 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7324 (match_operand:QI 1 "register_operand" "")
7325 (match_operand:QI 2 "nonimmediate_operand" "")))
7326 (set (match_operand:QI 3 "register_operand" "")
7327 (umod:QI (match_dup 1) (match_dup 2)))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7334 tmp0 = gen_reg_rtx (HImode);
7335 tmp1 = gen_reg_rtx (HImode);
7337 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7339 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7340 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7342 /* Extract remainder from AH. */
7343 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7344 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7345 insn = emit_move_insn (operands[3], tmp1);
7347 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7348 set_unique_reg_note (insn, REG_EQUAL, mod);
7350 /* Extract quotient from AL. */
7351 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7353 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7354 set_unique_reg_note (insn, REG_EQUAL, div);
7359 (define_insn "udivmodhiqi3"
7360 [(set (match_operand:HI 0 "register_operand" "=a")
7365 (mod:HI (match_operand:HI 1 "register_operand" "0")
7367 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7371 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "TARGET_QIMODE_MATH"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "QI")])
7378 ;; We cannot use div/idiv for double division, because it causes
7379 ;; "division by zero" on the overflow and that's not what we expect
7380 ;; from truncate. Because true (non truncating) double division is
7381 ;; never generated, we can't create this insn anyway.
7384 ; [(set (match_operand:SI 0 "register_operand" "=a")
7386 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7388 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7389 ; (set (match_operand:SI 3 "register_operand" "=d")
7391 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7392 ; (clobber (reg:CC FLAGS_REG))]
7394 ; "div{l}\t{%2, %0|%0, %2}"
7395 ; [(set_attr "type" "idiv")])
7397 ;;- Logical AND instructions
7399 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7400 ;; Note that this excludes ah.
7402 (define_expand "testsi_ccno_1"
7403 [(set (reg:CCNO FLAGS_REG)
7405 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7406 (match_operand:SI 1 "nonmemory_operand" ""))
7409 (define_expand "testqi_ccz_1"
7410 [(set (reg:CCZ FLAGS_REG)
7411 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7412 (match_operand:QI 1 "nonmemory_operand" ""))
7415 (define_expand "testdi_ccno_1"
7416 [(set (reg:CCNO FLAGS_REG)
7418 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7419 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7421 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7423 (define_insn "*testdi_1"
7424 [(set (reg FLAGS_REG)
7427 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7428 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7430 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7433 test{l}\t{%k1, %k0|%k0, %k1}
7434 test{l}\t{%k1, %k0|%k0, %k1}
7435 test{q}\t{%1, %0|%0, %1}
7436 test{q}\t{%1, %0|%0, %1}
7437 test{q}\t{%1, %0|%0, %1}"
7438 [(set_attr "type" "test")
7439 (set_attr "modrm" "0,1,0,1,1")
7440 (set_attr "mode" "SI,SI,DI,DI,DI")])
7442 (define_insn "*testqi_1_maybe_si"
7443 [(set (reg FLAGS_REG)
7446 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7447 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7449 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7450 && ix86_match_ccmode (insn,
7451 CONST_INT_P (operands[1])
7452 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7454 if (which_alternative == 3)
7456 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7457 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7458 return "test{l}\t{%1, %k0|%k0, %1}";
7460 return "test{b}\t{%1, %0|%0, %1}";
7462 [(set_attr "type" "test")
7463 (set_attr "modrm" "0,1,1,1")
7464 (set_attr "mode" "QI,QI,QI,SI")
7465 (set_attr "pent_pair" "uv,np,uv,np")])
7467 (define_insn "*test<mode>_1"
7468 [(set (reg FLAGS_REG)
7471 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7472 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7474 "ix86_match_ccmode (insn, CCNOmode)
7475 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7476 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7477 [(set_attr "type" "test")
7478 (set_attr "modrm" "0,1,1")
7479 (set_attr "mode" "<MODE>")
7480 (set_attr "pent_pair" "uv,np,uv")])
7482 (define_expand "testqi_ext_ccno_0"
7483 [(set (reg:CCNO FLAGS_REG)
7487 (match_operand 0 "ext_register_operand" "")
7490 (match_operand 1 "const_int_operand" ""))
7493 (define_insn "*testqi_ext_0"
7494 [(set (reg FLAGS_REG)
7498 (match_operand 0 "ext_register_operand" "Q")
7501 (match_operand 1 "const_int_operand" "n"))
7503 "ix86_match_ccmode (insn, CCNOmode)"
7504 "test{b}\t{%1, %h0|%h0, %1}"
7505 [(set_attr "type" "test")
7506 (set_attr "mode" "QI")
7507 (set_attr "length_immediate" "1")
7508 (set_attr "modrm" "1")
7509 (set_attr "pent_pair" "np")])
7511 (define_insn "*testqi_ext_1_rex64"
7512 [(set (reg FLAGS_REG)
7516 (match_operand 0 "ext_register_operand" "Q")
7520 (match_operand:QI 1 "register_operand" "Q")))
7522 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7523 "test{b}\t{%1, %h0|%h0, %1}"
7524 [(set_attr "type" "test")
7525 (set_attr "mode" "QI")])
7527 (define_insn "*testqi_ext_1"
7528 [(set (reg FLAGS_REG)
7532 (match_operand 0 "ext_register_operand" "Q")
7536 (match_operand:QI 1 "general_operand" "Qm")))
7538 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7539 "test{b}\t{%1, %h0|%h0, %1}"
7540 [(set_attr "type" "test")
7541 (set_attr "mode" "QI")])
7543 (define_insn "*testqi_ext_2"
7544 [(set (reg FLAGS_REG)
7548 (match_operand 0 "ext_register_operand" "Q")
7552 (match_operand 1 "ext_register_operand" "Q")
7556 "ix86_match_ccmode (insn, CCNOmode)"
7557 "test{b}\t{%h1, %h0|%h0, %h1}"
7558 [(set_attr "type" "test")
7559 (set_attr "mode" "QI")])
7561 (define_insn "*testqi_ext_3_rex64"
7562 [(set (reg FLAGS_REG)
7563 (compare (zero_extract:DI
7564 (match_operand 0 "nonimmediate_operand" "rm")
7565 (match_operand:DI 1 "const_int_operand" "")
7566 (match_operand:DI 2 "const_int_operand" ""))
7569 && ix86_match_ccmode (insn, CCNOmode)
7570 && INTVAL (operands[1]) > 0
7571 && INTVAL (operands[2]) >= 0
7572 /* Ensure that resulting mask is zero or sign extended operand. */
7573 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7574 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7575 && INTVAL (operands[1]) > 32))
7576 && (GET_MODE (operands[0]) == SImode
7577 || GET_MODE (operands[0]) == DImode
7578 || GET_MODE (operands[0]) == HImode
7579 || GET_MODE (operands[0]) == QImode)"
7582 ;; Combine likes to form bit extractions for some tests. Humor it.
7583 (define_insn "*testqi_ext_3"
7584 [(set (reg FLAGS_REG)
7585 (compare (zero_extract:SI
7586 (match_operand 0 "nonimmediate_operand" "rm")
7587 (match_operand:SI 1 "const_int_operand" "")
7588 (match_operand:SI 2 "const_int_operand" ""))
7590 "ix86_match_ccmode (insn, CCNOmode)
7591 && INTVAL (operands[1]) > 0
7592 && INTVAL (operands[2]) >= 0
7593 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7594 && (GET_MODE (operands[0]) == SImode
7595 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7596 || GET_MODE (operands[0]) == HImode
7597 || GET_MODE (operands[0]) == QImode)"
7601 [(set (match_operand 0 "flags_reg_operand" "")
7602 (match_operator 1 "compare_operator"
7604 (match_operand 2 "nonimmediate_operand" "")
7605 (match_operand 3 "const_int_operand" "")
7606 (match_operand 4 "const_int_operand" ""))
7608 "ix86_match_ccmode (insn, CCNOmode)"
7609 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7611 rtx val = operands[2];
7612 HOST_WIDE_INT len = INTVAL (operands[3]);
7613 HOST_WIDE_INT pos = INTVAL (operands[4]);
7615 enum machine_mode mode, submode;
7617 mode = GET_MODE (val);
7620 /* ??? Combine likes to put non-volatile mem extractions in QImode
7621 no matter the size of the test. So find a mode that works. */
7622 if (! MEM_VOLATILE_P (val))
7624 mode = smallest_mode_for_size (pos + len, MODE_INT);
7625 val = adjust_address (val, mode, 0);
7628 else if (GET_CODE (val) == SUBREG
7629 && (submode = GET_MODE (SUBREG_REG (val)),
7630 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7631 && pos + len <= GET_MODE_BITSIZE (submode)
7632 && GET_MODE_CLASS (submode) == MODE_INT)
7634 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7636 val = SUBREG_REG (val);
7638 else if (mode == HImode && pos + len <= 8)
7640 /* Small HImode tests can be converted to QImode. */
7642 val = gen_lowpart (QImode, val);
7645 if (len == HOST_BITS_PER_WIDE_INT)
7648 mask = ((HOST_WIDE_INT)1 << len) - 1;
7651 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7654 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7655 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7656 ;; this is relatively important trick.
7657 ;; Do the conversion only post-reload to avoid limiting of the register class
7660 [(set (match_operand 0 "flags_reg_operand" "")
7661 (match_operator 1 "compare_operator"
7662 [(and (match_operand 2 "register_operand" "")
7663 (match_operand 3 "const_int_operand" ""))
7666 && QI_REG_P (operands[2])
7667 && GET_MODE (operands[2]) != QImode
7668 && ((ix86_match_ccmode (insn, CCZmode)
7669 && !(INTVAL (operands[3]) & ~(255 << 8)))
7670 || (ix86_match_ccmode (insn, CCNOmode)
7671 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7674 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7677 "operands[2] = gen_lowpart (SImode, operands[2]);
7678 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7681 [(set (match_operand 0 "flags_reg_operand" "")
7682 (match_operator 1 "compare_operator"
7683 [(and (match_operand 2 "nonimmediate_operand" "")
7684 (match_operand 3 "const_int_operand" ""))
7687 && GET_MODE (operands[2]) != QImode
7688 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689 && ((ix86_match_ccmode (insn, CCZmode)
7690 && !(INTVAL (operands[3]) & ~255))
7691 || (ix86_match_ccmode (insn, CCNOmode)
7692 && !(INTVAL (operands[3]) & ~127)))"
7694 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7696 "operands[2] = gen_lowpart (QImode, operands[2]);
7697 operands[3] = gen_lowpart (QImode, operands[3]);")
7699 ;; %%% This used to optimize known byte-wide and operations to memory,
7700 ;; and sometimes to QImode registers. If this is considered useful,
7701 ;; it should be done with splitters.
7703 (define_expand "and<mode>3"
7704 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7705 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7706 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7708 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7710 (define_insn "*anddi_1"
7711 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7713 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7714 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7718 switch (get_attr_type (insn))
7722 enum machine_mode mode;
7724 gcc_assert (CONST_INT_P (operands[2]));
7725 if (INTVAL (operands[2]) == 0xff)
7729 gcc_assert (INTVAL (operands[2]) == 0xffff);
7733 operands[1] = gen_lowpart (mode, operands[1]);
7735 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7737 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7741 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7742 if (get_attr_mode (insn) == MODE_SI)
7743 return "and{l}\t{%k2, %k0|%k0, %k2}";
7745 return "and{q}\t{%2, %0|%0, %2}";
7748 [(set_attr "type" "alu,alu,alu,imovx")
7749 (set_attr "length_immediate" "*,*,*,0")
7750 (set (attr "prefix_rex")
7752 (and (eq_attr "type" "imovx")
7753 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7754 (match_operand 1 "ext_QIreg_operand" "")))
7756 (const_string "*")))
7757 (set_attr "mode" "SI,DI,DI,SI")])
7759 (define_insn "*andsi_1"
7760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7761 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7762 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7763 (clobber (reg:CC FLAGS_REG))]
7764 "ix86_binary_operator_ok (AND, SImode, operands)"
7766 switch (get_attr_type (insn))
7770 enum machine_mode mode;
7772 gcc_assert (CONST_INT_P (operands[2]));
7773 if (INTVAL (operands[2]) == 0xff)
7777 gcc_assert (INTVAL (operands[2]) == 0xffff);
7781 operands[1] = gen_lowpart (mode, operands[1]);
7783 return "movz{bl|x}\t{%1, %0|%0, %1}";
7785 return "movz{wl|x}\t{%1, %0|%0, %1}";
7789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7790 return "and{l}\t{%2, %0|%0, %2}";
7793 [(set_attr "type" "alu,alu,imovx")
7794 (set (attr "prefix_rex")
7796 (and (eq_attr "type" "imovx")
7797 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7798 (match_operand 1 "ext_QIreg_operand" "")))
7800 (const_string "*")))
7801 (set_attr "length_immediate" "*,*,0")
7802 (set_attr "mode" "SI")])
7804 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7805 (define_insn "*andsi_1_zext"
7806 [(set (match_operand:DI 0 "register_operand" "=r")
7808 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7809 (match_operand:SI 2 "general_operand" "g"))))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7812 "and{l}\t{%2, %k0|%k0, %2}"
7813 [(set_attr "type" "alu")
7814 (set_attr "mode" "SI")])
7816 (define_insn "*andhi_1"
7817 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7818 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7819 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "ix86_binary_operator_ok (AND, HImode, operands)"
7823 switch (get_attr_type (insn))
7826 gcc_assert (CONST_INT_P (operands[2]));
7827 gcc_assert (INTVAL (operands[2]) == 0xff);
7828 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7833 return "and{w}\t{%2, %0|%0, %2}";
7836 [(set_attr "type" "alu,alu,imovx")
7837 (set_attr "length_immediate" "*,*,0")
7838 (set (attr "prefix_rex")
7840 (and (eq_attr "type" "imovx")
7841 (match_operand 1 "ext_QIreg_operand" ""))
7843 (const_string "*")))
7844 (set_attr "mode" "HI,HI,SI")])
7846 ;; %%% Potential partial reg stall on alternative 2. What to do?
7847 (define_insn "*andqi_1"
7848 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7849 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7850 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "ix86_binary_operator_ok (AND, QImode, operands)"
7854 and{b}\t{%2, %0|%0, %2}
7855 and{b}\t{%2, %0|%0, %2}
7856 and{l}\t{%k2, %k0|%k0, %k2}"
7857 [(set_attr "type" "alu")
7858 (set_attr "mode" "QI,QI,SI")])
7860 (define_insn "*andqi_1_slp"
7861 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7862 (and:QI (match_dup 0)
7863 (match_operand:QI 1 "general_operand" "qn,qmn")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7867 "and{b}\t{%1, %0|%0, %1}"
7868 [(set_attr "type" "alu1")
7869 (set_attr "mode" "QI")])
7872 [(set (match_operand 0 "register_operand" "")
7874 (const_int -65536)))
7875 (clobber (reg:CC FLAGS_REG))]
7876 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7877 || optimize_function_for_size_p (cfun)"
7878 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7879 "operands[1] = gen_lowpart (HImode, operands[0]);")
7882 [(set (match_operand 0 "ext_register_operand" "")
7885 (clobber (reg:CC FLAGS_REG))]
7886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887 && reload_completed"
7888 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7889 "operands[1] = gen_lowpart (QImode, operands[0]);")
7892 [(set (match_operand 0 "ext_register_operand" "")
7894 (const_int -65281)))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7897 && reload_completed"
7898 [(parallel [(set (zero_extract:SI (match_dup 0)
7902 (zero_extract:SI (match_dup 0)
7905 (zero_extract:SI (match_dup 0)
7908 (clobber (reg:CC FLAGS_REG))])]
7909 "operands[0] = gen_lowpart (SImode, operands[0]);")
7911 (define_insn "*anddi_2"
7912 [(set (reg FLAGS_REG)
7915 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7918 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7919 (and:DI (match_dup 1) (match_dup 2)))]
7920 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7921 && ix86_binary_operator_ok (AND, DImode, operands)"
7923 and{l}\t{%k2, %k0|%k0, %k2}
7924 and{q}\t{%2, %0|%0, %2}
7925 and{q}\t{%2, %0|%0, %2}"
7926 [(set_attr "type" "alu")
7927 (set_attr "mode" "SI,DI,DI")])
7929 (define_insn "*andqi_2_maybe_si"
7930 [(set (reg FLAGS_REG)
7932 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7933 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7935 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7936 (and:QI (match_dup 1) (match_dup 2)))]
7937 "ix86_binary_operator_ok (AND, QImode, operands)
7938 && ix86_match_ccmode (insn,
7939 CONST_INT_P (operands[2])
7940 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7942 if (which_alternative == 2)
7944 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7945 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7946 return "and{l}\t{%2, %k0|%k0, %2}";
7948 return "and{b}\t{%2, %0|%0, %2}";
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "QI,QI,SI")])
7953 (define_insn "*and<mode>_2"
7954 [(set (reg FLAGS_REG)
7955 (compare (and:SWI124
7956 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7957 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7959 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7960 (and:SWI124 (match_dup 1) (match_dup 2)))]
7961 "ix86_match_ccmode (insn, CCNOmode)
7962 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7963 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "<MODE>")])
7967 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7968 (define_insn "*andsi_2_zext"
7969 [(set (reg FLAGS_REG)
7971 (match_operand:SI 1 "nonimmediate_operand" "%0")
7972 (match_operand:SI 2 "general_operand" "g"))
7974 (set (match_operand:DI 0 "register_operand" "=r")
7975 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (AND, SImode, operands)"
7978 "and{l}\t{%2, %k0|%k0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI")])
7982 (define_insn "*andqi_2_slp"
7983 [(set (reg FLAGS_REG)
7985 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7986 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7988 (set (strict_low_part (match_dup 0))
7989 (and:QI (match_dup 0) (match_dup 1)))]
7990 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7991 && ix86_match_ccmode (insn, CCNOmode)
7992 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7993 "and{b}\t{%1, %0|%0, %1}"
7994 [(set_attr "type" "alu1")
7995 (set_attr "mode" "QI")])
7997 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7998 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7999 ;; for a QImode operand, which of course failed.
8000 (define_insn "andqi_ext_0"
8001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8006 (match_operand 1 "ext_register_operand" "0")
8009 (match_operand 2 "const_int_operand" "n")))
8010 (clobber (reg:CC FLAGS_REG))]
8012 "and{b}\t{%2, %h0|%h0, %2}"
8013 [(set_attr "type" "alu")
8014 (set_attr "length_immediate" "1")
8015 (set_attr "modrm" "1")
8016 (set_attr "mode" "QI")])
8018 ;; Generated by peephole translating test to and. This shows up
8019 ;; often in fp comparisons.
8020 (define_insn "*andqi_ext_0_cc"
8021 [(set (reg FLAGS_REG)
8025 (match_operand 1 "ext_register_operand" "0")
8028 (match_operand 2 "const_int_operand" "n"))
8030 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8039 "ix86_match_ccmode (insn, CCNOmode)"
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "1")
8043 (set_attr "modrm" "1")
8044 (set_attr "mode" "QI")])
8046 (define_insn "*andqi_ext_1_rex64"
8047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8052 (match_operand 1 "ext_register_operand" "0")
8056 (match_operand 2 "ext_register_operand" "Q"))))
8057 (clobber (reg:CC FLAGS_REG))]
8059 "and{b}\t{%2, %h0|%h0, %2}"
8060 [(set_attr "type" "alu")
8061 (set_attr "length_immediate" "0")
8062 (set_attr "mode" "QI")])
8064 (define_insn "*andqi_ext_1"
8065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8070 (match_operand 1 "ext_register_operand" "0")
8074 (match_operand:QI 2 "general_operand" "Qm"))))
8075 (clobber (reg:CC FLAGS_REG))]
8077 "and{b}\t{%2, %h0|%h0, %2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "length_immediate" "0")
8080 (set_attr "mode" "QI")])
8082 (define_insn "*andqi_ext_2"
8083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8088 (match_operand 1 "ext_register_operand" "%0")
8092 (match_operand 2 "ext_register_operand" "Q")
8095 (clobber (reg:CC FLAGS_REG))]
8097 "and{b}\t{%h2, %h0|%h0, %h2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "length_immediate" "0")
8100 (set_attr "mode" "QI")])
8102 ;; Convert wide AND instructions with immediate operand to shorter QImode
8103 ;; equivalents when possible.
8104 ;; Don't do the splitting with memory operands, since it introduces risk
8105 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8106 ;; for size, but that can (should?) be handled by generic code instead.
8108 [(set (match_operand 0 "register_operand" "")
8109 (and (match_operand 1 "register_operand" "")
8110 (match_operand 2 "const_int_operand" "")))
8111 (clobber (reg:CC FLAGS_REG))]
8113 && QI_REG_P (operands[0])
8114 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8115 && !(~INTVAL (operands[2]) & ~(255 << 8))
8116 && GET_MODE (operands[0]) != QImode"
8117 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8118 (and:SI (zero_extract:SI (match_dup 1)
8119 (const_int 8) (const_int 8))
8121 (clobber (reg:CC FLAGS_REG))])]
8122 "operands[0] = gen_lowpart (SImode, operands[0]);
8123 operands[1] = gen_lowpart (SImode, operands[1]);
8124 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8126 ;; Since AND can be encoded with sign extended immediate, this is only
8127 ;; profitable when 7th bit is not set.
8129 [(set (match_operand 0 "register_operand" "")
8130 (and (match_operand 1 "general_operand" "")
8131 (match_operand 2 "const_int_operand" "")))
8132 (clobber (reg:CC FLAGS_REG))]
8134 && ANY_QI_REG_P (operands[0])
8135 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8136 && !(~INTVAL (operands[2]) & ~255)
8137 && !(INTVAL (operands[2]) & 128)
8138 && GET_MODE (operands[0]) != QImode"
8139 [(parallel [(set (strict_low_part (match_dup 0))
8140 (and:QI (match_dup 1)
8142 (clobber (reg:CC FLAGS_REG))])]
8143 "operands[0] = gen_lowpart (QImode, operands[0]);
8144 operands[1] = gen_lowpart (QImode, operands[1]);
8145 operands[2] = gen_lowpart (QImode, operands[2]);")
8147 ;; Logical inclusive and exclusive OR instructions
8149 ;; %%% This used to optimize known byte-wide and operations to memory.
8150 ;; If this is considered useful, it should be done with splitters.
8152 (define_expand "<code><mode>3"
8153 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8154 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8155 (match_operand:SWIM 2 "<general_operand>" "")))]
8157 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8159 (define_insn "*<code><mode>_1"
8160 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8162 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8163 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8166 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "<MODE>")])
8170 ;; %%% Potential partial reg stall on alternative 2. What to do?
8171 (define_insn "*<code>qi_1"
8172 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8173 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8174 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8178 <logic>{b}\t{%2, %0|%0, %2}
8179 <logic>{b}\t{%2, %0|%0, %2}
8180 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "QI,QI,SI")])
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*<code>si_1_zext"
8186 [(set (match_operand:DI 0 "register_operand" "=r")
8188 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189 (match_operand:SI 2 "general_operand" "g"))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8192 "<logic>{l}\t{%2, %k0|%k0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI")])
8196 (define_insn "*<code>si_1_zext_imm"
8197 [(set (match_operand:DI 0 "register_operand" "=r")
8199 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8200 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8201 (clobber (reg:CC FLAGS_REG))]
8202 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8203 "<logic>{l}\t{%2, %k0|%k0, %2}"
8204 [(set_attr "type" "alu")
8205 (set_attr "mode" "SI")])
8207 (define_insn "*<code>qi_1_slp"
8208 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8209 (any_or:QI (match_dup 0)
8210 (match_operand:QI 1 "general_operand" "qmn,qn")))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214 "<logic>{b}\t{%1, %0|%0, %1}"
8215 [(set_attr "type" "alu1")
8216 (set_attr "mode" "QI")])
8218 (define_insn "*<code><mode>_2"
8219 [(set (reg FLAGS_REG)
8220 (compare (any_or:SWI
8221 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8222 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8224 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8225 (any_or:SWI (match_dup 1) (match_dup 2)))]
8226 "ix86_match_ccmode (insn, CCNOmode)
8227 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8228 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "<MODE>")])
8232 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8233 ;; ??? Special case for immediate operand is missing - it is tricky.
8234 (define_insn "*<code>si_2_zext"
8235 [(set (reg FLAGS_REG)
8236 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8237 (match_operand:SI 2 "general_operand" "g"))
8239 (set (match_operand:DI 0 "register_operand" "=r")
8240 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8241 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8242 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8243 "<logic>{l}\t{%2, %k0|%k0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "SI")])
8247 (define_insn "*<code>si_2_zext_imm"
8248 [(set (reg FLAGS_REG)
8250 (match_operand:SI 1 "nonimmediate_operand" "%0")
8251 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8253 (set (match_operand:DI 0 "register_operand" "=r")
8254 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8255 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8257 "<logic>{l}\t{%2, %k0|%k0, %2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "SI")])
8261 (define_insn "*<code>qi_2_slp"
8262 [(set (reg FLAGS_REG)
8263 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8264 (match_operand:QI 1 "general_operand" "qmn,qn"))
8266 (set (strict_low_part (match_dup 0))
8267 (any_or:QI (match_dup 0) (match_dup 1)))]
8268 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8269 && ix86_match_ccmode (insn, CCNOmode)
8270 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8271 "<logic>{b}\t{%1, %0|%0, %1}"
8272 [(set_attr "type" "alu1")
8273 (set_attr "mode" "QI")])
8275 (define_insn "*<code><mode>_3"
8276 [(set (reg FLAGS_REG)
8277 (compare (any_or:SWI
8278 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8279 (match_operand:SWI 2 "<general_operand>" "<g>"))
8281 (clobber (match_scratch:SWI 0 "=<r>"))]
8282 "ix86_match_ccmode (insn, CCNOmode)
8283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8284 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "<MODE>")])
8288 (define_insn "*<code>qi_ext_0"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294 (match_operand 1 "ext_register_operand" "0")
8297 (match_operand 2 "const_int_operand" "n")))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8300 "<logic>{b}\t{%2, %h0|%h0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "length_immediate" "1")
8303 (set_attr "modrm" "1")
8304 (set_attr "mode" "QI")])
8306 (define_insn "*<code>qi_ext_1_rex64"
8307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312 (match_operand 1 "ext_register_operand" "0")
8316 (match_operand 2 "ext_register_operand" "Q"))))
8317 (clobber (reg:CC FLAGS_REG))]
8319 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8320 "<logic>{b}\t{%2, %h0|%h0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "0")
8323 (set_attr "mode" "QI")])
8325 (define_insn "*<code>qi_ext_1"
8326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8331 (match_operand 1 "ext_register_operand" "0")
8335 (match_operand:QI 2 "general_operand" "Qm"))))
8336 (clobber (reg:CC FLAGS_REG))]
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8339 "<logic>{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "length_immediate" "0")
8342 (set_attr "mode" "QI")])
8344 (define_insn "*<code>qi_ext_2"
8345 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8349 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8352 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8355 (clobber (reg:CC FLAGS_REG))]
8356 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8357 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "length_immediate" "0")
8360 (set_attr "mode" "QI")])
8363 [(set (match_operand 0 "register_operand" "")
8364 (any_or (match_operand 1 "register_operand" "")
8365 (match_operand 2 "const_int_operand" "")))
8366 (clobber (reg:CC FLAGS_REG))]
8368 && QI_REG_P (operands[0])
8369 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8370 && !(INTVAL (operands[2]) & ~(255 << 8))
8371 && GET_MODE (operands[0]) != QImode"
8372 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8373 (any_or:SI (zero_extract:SI (match_dup 1)
8374 (const_int 8) (const_int 8))
8376 (clobber (reg:CC FLAGS_REG))])]
8377 "operands[0] = gen_lowpart (SImode, operands[0]);
8378 operands[1] = gen_lowpart (SImode, operands[1]);
8379 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8381 ;; Since OR can be encoded with sign extended immediate, this is only
8382 ;; profitable when 7th bit is set.
8384 [(set (match_operand 0 "register_operand" "")
8385 (any_or (match_operand 1 "general_operand" "")
8386 (match_operand 2 "const_int_operand" "")))
8387 (clobber (reg:CC FLAGS_REG))]
8389 && ANY_QI_REG_P (operands[0])
8390 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391 && !(INTVAL (operands[2]) & ~255)
8392 && (INTVAL (operands[2]) & 128)
8393 && GET_MODE (operands[0]) != QImode"
8394 [(parallel [(set (strict_low_part (match_dup 0))
8395 (any_or:QI (match_dup 1)
8397 (clobber (reg:CC FLAGS_REG))])]
8398 "operands[0] = gen_lowpart (QImode, operands[0]);
8399 operands[1] = gen_lowpart (QImode, operands[1]);
8400 operands[2] = gen_lowpart (QImode, operands[2]);")
8402 (define_expand "xorqi_cc_ext_1"
8404 (set (reg:CCNO FLAGS_REG)
8408 (match_operand 1 "ext_register_operand" "")
8411 (match_operand:QI 2 "general_operand" ""))
8413 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8423 (define_insn "*xorqi_cc_ext_1_rex64"
8424 [(set (reg FLAGS_REG)
8428 (match_operand 1 "ext_register_operand" "0")
8431 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8433 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8443 "xor{b}\t{%2, %h0|%h0, %2}"
8444 [(set_attr "type" "alu")
8445 (set_attr "modrm" "1")
8446 (set_attr "mode" "QI")])
8448 (define_insn "*xorqi_cc_ext_1"
8449 [(set (reg FLAGS_REG)
8453 (match_operand 1 "ext_register_operand" "0")
8456 (match_operand:QI 2 "general_operand" "qmn"))
8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8467 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468 "xor{b}\t{%2, %h0|%h0, %2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "modrm" "1")
8471 (set_attr "mode" "QI")])
8473 ;; Negation instructions
8475 (define_expand "neg<mode>2"
8476 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8477 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8479 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8481 (define_insn_and_split "*neg<dwi>2_doubleword"
8482 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8483 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8484 (clobber (reg:CC FLAGS_REG))]
8485 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8489 [(set (reg:CCZ FLAGS_REG)
8490 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8491 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8494 (plus:DWIH (match_dup 3)
8495 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8497 (clobber (reg:CC FLAGS_REG))])
8500 (neg:DWIH (match_dup 2)))
8501 (clobber (reg:CC FLAGS_REG))])]
8502 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8504 (define_insn "*neg<mode>2_1"
8505 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8506 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8507 (clobber (reg:CC FLAGS_REG))]
8508 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8509 "neg{<imodesuffix>}\t%0"
8510 [(set_attr "type" "negnot")
8511 (set_attr "mode" "<MODE>")])
8513 ;; Combine is quite creative about this pattern.
8514 (define_insn "*negsi2_1_zext"
8515 [(set (match_operand:DI 0 "register_operand" "=r")
8517 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8520 (clobber (reg:CC FLAGS_REG))]
8521 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8523 [(set_attr "type" "negnot")
8524 (set_attr "mode" "SI")])
8526 ;; The problem with neg is that it does not perform (compare x 0),
8527 ;; it really performs (compare 0 x), which leaves us with the zero
8528 ;; flag being the only useful item.
8530 (define_insn "*neg<mode>2_cmpz"
8531 [(set (reg:CCZ FLAGS_REG)
8533 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8535 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8536 (neg:SWI (match_dup 1)))]
8537 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8538 "neg{<imodesuffix>}\t%0"
8539 [(set_attr "type" "negnot")
8540 (set_attr "mode" "<MODE>")])
8542 (define_insn "*negsi2_cmpz_zext"
8543 [(set (reg:CCZ FLAGS_REG)
8547 (match_operand:DI 1 "register_operand" "0")
8551 (set (match_operand:DI 0 "register_operand" "=r")
8552 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8555 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8557 [(set_attr "type" "negnot")
8558 (set_attr "mode" "SI")])
8560 ;; Changing of sign for FP values is doable using integer unit too.
8562 (define_expand "<code><mode>2"
8563 [(set (match_operand:X87MODEF 0 "register_operand" "")
8564 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8565 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8566 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8568 (define_insn "*absneg<mode>2_mixed"
8569 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8570 (match_operator:MODEF 3 "absneg_operator"
8571 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8572 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8573 (clobber (reg:CC FLAGS_REG))]
8574 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8577 (define_insn "*absneg<mode>2_sse"
8578 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8579 (match_operator:MODEF 3 "absneg_operator"
8580 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8581 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8586 (define_insn "*absneg<mode>2_i387"
8587 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8588 (match_operator:X87MODEF 3 "absneg_operator"
8589 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8590 (use (match_operand 2 "" ""))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8595 (define_expand "<code>tf2"
8596 [(set (match_operand:TF 0 "register_operand" "")
8597 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8599 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8601 (define_insn "*absnegtf2_sse"
8602 [(set (match_operand:TF 0 "register_operand" "=x,x")
8603 (match_operator:TF 3 "absneg_operator"
8604 [(match_operand:TF 1 "register_operand" "0,x")]))
8605 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8606 (clobber (reg:CC FLAGS_REG))]
8610 ;; Splitters for fp abs and neg.
8613 [(set (match_operand 0 "fp_register_operand" "")
8614 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8615 (use (match_operand 2 "" ""))
8616 (clobber (reg:CC FLAGS_REG))]
8618 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8621 [(set (match_operand 0 "register_operand" "")
8622 (match_operator 3 "absneg_operator"
8623 [(match_operand 1 "register_operand" "")]))
8624 (use (match_operand 2 "nonimmediate_operand" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8626 "reload_completed && SSE_REG_P (operands[0])"
8627 [(set (match_dup 0) (match_dup 3))]
8629 enum machine_mode mode = GET_MODE (operands[0]);
8630 enum machine_mode vmode = GET_MODE (operands[2]);
8633 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8634 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8635 if (operands_match_p (operands[0], operands[2]))
8638 operands[1] = operands[2];
8641 if (GET_CODE (operands[3]) == ABS)
8642 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8644 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8649 [(set (match_operand:SF 0 "register_operand" "")
8650 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8651 (use (match_operand:V4SF 2 "" ""))
8652 (clobber (reg:CC FLAGS_REG))]
8654 [(parallel [(set (match_dup 0) (match_dup 1))
8655 (clobber (reg:CC FLAGS_REG))])]
8658 operands[0] = gen_lowpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8673 [(set (match_operand:DF 0 "register_operand" "")
8674 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8675 (use (match_operand 2 "" ""))
8676 (clobber (reg:CC FLAGS_REG))]
8678 [(parallel [(set (match_dup 0) (match_dup 1))
8679 (clobber (reg:CC FLAGS_REG))])]
8684 tmp = gen_lowpart (DImode, operands[0]);
8685 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8688 if (GET_CODE (operands[1]) == ABS)
8691 tmp = gen_rtx_NOT (DImode, tmp);
8695 operands[0] = gen_highpart (SImode, operands[0]);
8696 if (GET_CODE (operands[1]) == ABS)
8698 tmp = gen_int_mode (0x7fffffff, SImode);
8699 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8703 tmp = gen_int_mode (0x80000000, SImode);
8704 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8711 [(set (match_operand:XF 0 "register_operand" "")
8712 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8713 (use (match_operand 2 "" ""))
8714 (clobber (reg:CC FLAGS_REG))]
8716 [(parallel [(set (match_dup 0) (match_dup 1))
8717 (clobber (reg:CC FLAGS_REG))])]
8720 operands[0] = gen_rtx_REG (SImode,
8721 true_regnum (operands[0])
8722 + (TARGET_64BIT ? 1 : 2));
8723 if (GET_CODE (operands[1]) == ABS)
8725 tmp = GEN_INT (0x7fff);
8726 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8730 tmp = GEN_INT (0x8000);
8731 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8736 ;; Conditionalize these after reload. If they match before reload, we
8737 ;; lose the clobber and ability to use integer instructions.
8739 (define_insn "*<code><mode>2_1"
8740 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8741 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8743 && (reload_completed
8744 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8745 "f<absneg_mnemonic>"
8746 [(set_attr "type" "fsgn")
8747 (set_attr "mode" "<MODE>")])
8749 (define_insn "*<code>extendsfdf2"
8750 [(set (match_operand:DF 0 "register_operand" "=f")
8751 (absneg:DF (float_extend:DF
8752 (match_operand:SF 1 "register_operand" "0"))))]
8753 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8754 "f<absneg_mnemonic>"
8755 [(set_attr "type" "fsgn")
8756 (set_attr "mode" "DF")])
8758 (define_insn "*<code>extendsfxf2"
8759 [(set (match_operand:XF 0 "register_operand" "=f")
8760 (absneg:XF (float_extend:XF
8761 (match_operand:SF 1 "register_operand" "0"))))]
8763 "f<absneg_mnemonic>"
8764 [(set_attr "type" "fsgn")
8765 (set_attr "mode" "XF")])
8767 (define_insn "*<code>extenddfxf2"
8768 [(set (match_operand:XF 0 "register_operand" "=f")
8769 (absneg:XF (float_extend:XF
8770 (match_operand:DF 1 "register_operand" "0"))))]
8772 "f<absneg_mnemonic>"
8773 [(set_attr "type" "fsgn")
8774 (set_attr "mode" "XF")])
8776 ;; Copysign instructions
8778 (define_mode_iterator CSGNMODE [SF DF TF])
8779 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8781 (define_expand "copysign<mode>3"
8782 [(match_operand:CSGNMODE 0 "register_operand" "")
8783 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8784 (match_operand:CSGNMODE 2 "register_operand" "")]
8785 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8786 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8787 "ix86_expand_copysign (operands); DONE;")
8789 (define_insn_and_split "copysign<mode>3_const"
8790 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8792 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8793 (match_operand:CSGNMODE 2 "register_operand" "0")
8794 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8796 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8799 "&& reload_completed"
8801 "ix86_split_copysign_const (operands); DONE;")
8803 (define_insn "copysign<mode>3_var"
8804 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8806 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8807 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8808 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8809 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8811 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8812 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8813 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8817 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8819 [(match_operand:CSGNMODE 2 "register_operand" "")
8820 (match_operand:CSGNMODE 3 "register_operand" "")
8821 (match_operand:<CSGNVMODE> 4 "" "")
8822 (match_operand:<CSGNVMODE> 5 "" "")]
8824 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8825 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8826 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8827 && reload_completed"
8829 "ix86_split_copysign_var (operands); DONE;")
8831 ;; One complement instructions
8833 (define_expand "one_cmpl<mode>2"
8834 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8835 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8837 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8839 (define_insn "*one_cmpl<mode>2_1"
8840 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8841 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8842 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8843 "not{<imodesuffix>}\t%0"
8844 [(set_attr "type" "negnot")
8845 (set_attr "mode" "<MODE>")])
8847 ;; %%% Potential partial reg stall on alternative 1. What to do?
8848 (define_insn "*one_cmplqi2_1"
8849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8850 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8851 "ix86_unary_operator_ok (NOT, QImode, operands)"
8855 [(set_attr "type" "negnot")
8856 (set_attr "mode" "QI,SI")])
8858 ;; ??? Currently never generated - xor is used instead.
8859 (define_insn "*one_cmplsi2_1_zext"
8860 [(set (match_operand:DI 0 "register_operand" "=r")
8862 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8863 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8865 [(set_attr "type" "negnot")
8866 (set_attr "mode" "SI")])
8868 (define_insn "*one_cmpl<mode>2_2"
8869 [(set (reg FLAGS_REG)
8870 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8873 (not:SWI (match_dup 1)))]
8874 "ix86_match_ccmode (insn, CCNOmode)
8875 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8877 [(set_attr "type" "alu1")
8878 (set_attr "mode" "<MODE>")])
8881 [(set (match_operand 0 "flags_reg_operand" "")
8882 (match_operator 2 "compare_operator"
8883 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8885 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8886 (not:SWI (match_dup 3)))]
8887 "ix86_match_ccmode (insn, CCNOmode)"
8888 [(parallel [(set (match_dup 0)
8889 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8892 (xor:SWI (match_dup 3) (const_int -1)))])])
8894 ;; ??? Currently never generated - xor is used instead.
8895 (define_insn "*one_cmplsi2_2_zext"
8896 [(set (reg FLAGS_REG)
8897 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8899 (set (match_operand:DI 0 "register_operand" "=r")
8900 (zero_extend:DI (not:SI (match_dup 1))))]
8901 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8902 && ix86_unary_operator_ok (NOT, SImode, operands)"
8904 [(set_attr "type" "alu1")
8905 (set_attr "mode" "SI")])
8908 [(set (match_operand 0 "flags_reg_operand" "")
8909 (match_operator 2 "compare_operator"
8910 [(not:SI (match_operand:SI 3 "register_operand" ""))
8912 (set (match_operand:DI 1 "register_operand" "")
8913 (zero_extend:DI (not:SI (match_dup 3))))]
8914 "ix86_match_ccmode (insn, CCNOmode)"
8915 [(parallel [(set (match_dup 0)
8916 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8919 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8921 ;; Shift instructions
8923 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8924 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8925 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8926 ;; from the assembler input.
8928 ;; This instruction shifts the target reg/mem as usual, but instead of
8929 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8930 ;; is a left shift double, bits are taken from the high order bits of
8931 ;; reg, else if the insn is a shift right double, bits are taken from the
8932 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8933 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8935 ;; Since sh[lr]d does not change the `reg' operand, that is done
8936 ;; separately, making all shifts emit pairs of shift double and normal
8937 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8938 ;; support a 63 bit shift, each shift where the count is in a reg expands
8939 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8941 ;; If the shift count is a constant, we need never emit more than one
8942 ;; shift pair, instead using moves and sign extension for counts greater
8945 (define_expand "ashl<mode>3"
8946 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8947 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8948 (match_operand:QI 2 "nonmemory_operand" "")))]
8950 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8952 (define_insn "*ashl<mode>3_doubleword"
8953 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8954 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8955 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8956 (clobber (reg:CC FLAGS_REG))]
8959 [(set_attr "type" "multi")])
8962 [(set (match_operand:DWI 0 "register_operand" "")
8963 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8964 (match_operand:QI 2 "nonmemory_operand" "")))
8965 (clobber (reg:CC FLAGS_REG))]
8966 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8968 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8970 ;; By default we don't ask for a scratch register, because when DWImode
8971 ;; values are manipulated, registers are already at a premium. But if
8972 ;; we have one handy, we won't turn it away.
8975 [(match_scratch:DWIH 3 "r")
8976 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8978 (match_operand:<DWI> 1 "nonmemory_operand" "")
8979 (match_operand:QI 2 "nonmemory_operand" "")))
8980 (clobber (reg:CC FLAGS_REG))])
8984 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8986 (define_insn "x86_64_shld"
8987 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8988 (ior:DI (ashift:DI (match_dup 0)
8989 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8990 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8991 (minus:QI (const_int 64) (match_dup 2)))))
8992 (clobber (reg:CC FLAGS_REG))]
8994 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8995 [(set_attr "type" "ishift")
8996 (set_attr "prefix_0f" "1")
8997 (set_attr "mode" "DI")
8998 (set_attr "athlon_decode" "vector")
8999 (set_attr "amdfam10_decode" "vector")
9000 (set_attr "bdver1_decode" "vector")])
9002 (define_insn "x86_shld"
9003 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9004 (ior:SI (ashift:SI (match_dup 0)
9005 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9006 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9007 (minus:QI (const_int 32) (match_dup 2)))))
9008 (clobber (reg:CC FLAGS_REG))]
9010 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9011 [(set_attr "type" "ishift")
9012 (set_attr "prefix_0f" "1")
9013 (set_attr "mode" "SI")
9014 (set_attr "pent_pair" "np")
9015 (set_attr "athlon_decode" "vector")
9016 (set_attr "amdfam10_decode" "vector")
9017 (set_attr "bdver1_decode" "vector")])
9019 (define_expand "x86_shift<mode>_adj_1"
9020 [(set (reg:CCZ FLAGS_REG)
9021 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9024 (set (match_operand:SWI48 0 "register_operand" "")
9025 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9026 (match_operand:SWI48 1 "register_operand" "")
9029 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9030 (match_operand:SWI48 3 "register_operand" "r")
9033 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9035 (define_expand "x86_shift<mode>_adj_2"
9036 [(use (match_operand:SWI48 0 "register_operand" ""))
9037 (use (match_operand:SWI48 1 "register_operand" ""))
9038 (use (match_operand:QI 2 "register_operand" ""))]
9041 rtx label = gen_label_rtx ();
9044 emit_insn (gen_testqi_ccz_1 (operands[2],
9045 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9047 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9048 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9049 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9050 gen_rtx_LABEL_REF (VOIDmode, label),
9052 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9053 JUMP_LABEL (tmp) = label;
9055 emit_move_insn (operands[0], operands[1]);
9056 ix86_expand_clear (operands[1]);
9059 LABEL_NUSES (label) = 1;
9064 ;; Avoid useless masking of count operand.
9065 (define_insn_and_split "*ashl<mode>3_mask"
9066 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9068 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9071 (match_operand:SI 2 "nonimmediate_operand" "c")
9072 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9075 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9076 == GET_MODE_BITSIZE (<MODE>mode)-1"
9079 [(parallel [(set (match_dup 0)
9080 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9081 (clobber (reg:CC FLAGS_REG))])]
9083 if (can_create_pseudo_p ())
9084 operands [2] = force_reg (SImode, operands[2]);
9086 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9088 [(set_attr "type" "ishift")
9089 (set_attr "mode" "<MODE>")])
9091 (define_insn "*ashl<mode>3_1"
9092 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9093 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9094 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9098 switch (get_attr_type (insn))
9104 gcc_assert (operands[2] == const1_rtx);
9105 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9106 return "add{<imodesuffix>}\t%0, %0";
9109 if (operands[2] == const1_rtx
9110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9111 return "sal{<imodesuffix>}\t%0";
9113 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9117 (cond [(eq_attr "alternative" "1")
9118 (const_string "lea")
9119 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9121 (match_operand 0 "register_operand" ""))
9122 (match_operand 2 "const1_operand" ""))
9123 (const_string "alu")
9125 (const_string "ishift")))
9126 (set (attr "length_immediate")
9128 (ior (eq_attr "type" "alu")
9129 (and (eq_attr "type" "ishift")
9130 (and (match_operand 2 "const1_operand" "")
9131 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9134 (const_string "*")))
9135 (set_attr "mode" "<MODE>")])
9137 (define_insn "*ashlsi3_1_zext"
9138 [(set (match_operand:DI 0 "register_operand" "=r,r")
9140 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9141 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9145 switch (get_attr_type (insn))
9151 gcc_assert (operands[2] == const1_rtx);
9152 return "add{l}\t%k0, %k0";
9155 if (operands[2] == const1_rtx
9156 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9157 return "sal{l}\t%k0";
9159 return "sal{l}\t{%2, %k0|%k0, %2}";
9163 (cond [(eq_attr "alternative" "1")
9164 (const_string "lea")
9165 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9167 (match_operand 2 "const1_operand" ""))
9168 (const_string "alu")
9170 (const_string "ishift")))
9171 (set (attr "length_immediate")
9173 (ior (eq_attr "type" "alu")
9174 (and (eq_attr "type" "ishift")
9175 (and (match_operand 2 "const1_operand" "")
9176 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9179 (const_string "*")))
9180 (set_attr "mode" "SI")])
9182 (define_insn "*ashlhi3_1"
9183 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9184 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9185 (match_operand:QI 2 "nonmemory_operand" "cI")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "TARGET_PARTIAL_REG_STALL
9188 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9190 switch (get_attr_type (insn))
9193 gcc_assert (operands[2] == const1_rtx);
9194 return "add{w}\t%0, %0";
9197 if (operands[2] == const1_rtx
9198 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9199 return "sal{w}\t%0";
9201 return "sal{w}\t{%2, %0|%0, %2}";
9205 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9207 (match_operand 0 "register_operand" ""))
9208 (match_operand 2 "const1_operand" ""))
9209 (const_string "alu")
9211 (const_string "ishift")))
9212 (set (attr "length_immediate")
9214 (ior (eq_attr "type" "alu")
9215 (and (eq_attr "type" "ishift")
9216 (and (match_operand 2 "const1_operand" "")
9217 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9220 (const_string "*")))
9221 (set_attr "mode" "HI")])
9223 (define_insn "*ashlhi3_1_lea"
9224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9225 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9226 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "!TARGET_PARTIAL_REG_STALL
9229 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9231 switch (get_attr_type (insn))
9237 gcc_assert (operands[2] == const1_rtx);
9238 return "add{w}\t%0, %0";
9241 if (operands[2] == const1_rtx
9242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243 return "sal{w}\t%0";
9245 return "sal{w}\t{%2, %0|%0, %2}";
9249 (cond [(eq_attr "alternative" "1")
9250 (const_string "lea")
9251 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9253 (match_operand 0 "register_operand" ""))
9254 (match_operand 2 "const1_operand" ""))
9255 (const_string "alu")
9257 (const_string "ishift")))
9258 (set (attr "length_immediate")
9260 (ior (eq_attr "type" "alu")
9261 (and (eq_attr "type" "ishift")
9262 (and (match_operand 2 "const1_operand" "")
9263 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9266 (const_string "*")))
9267 (set_attr "mode" "HI,SI")])
9269 (define_insn "*ashlqi3_1"
9270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9271 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9272 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9273 (clobber (reg:CC FLAGS_REG))]
9274 "TARGET_PARTIAL_REG_STALL
9275 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9277 switch (get_attr_type (insn))
9280 gcc_assert (operands[2] == const1_rtx);
9281 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9282 return "add{l}\t%k0, %k0";
9284 return "add{b}\t%0, %0";
9287 if (operands[2] == const1_rtx
9288 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9290 if (get_attr_mode (insn) == MODE_SI)
9291 return "sal{l}\t%k0";
9293 return "sal{b}\t%0";
9297 if (get_attr_mode (insn) == MODE_SI)
9298 return "sal{l}\t{%2, %k0|%k0, %2}";
9300 return "sal{b}\t{%2, %0|%0, %2}";
9305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9307 (match_operand 0 "register_operand" ""))
9308 (match_operand 2 "const1_operand" ""))
9309 (const_string "alu")
9311 (const_string "ishift")))
9312 (set (attr "length_immediate")
9314 (ior (eq_attr "type" "alu")
9315 (and (eq_attr "type" "ishift")
9316 (and (match_operand 2 "const1_operand" "")
9317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9320 (const_string "*")))
9321 (set_attr "mode" "QI,SI")])
9323 ;; %%% Potential partial reg stall on alternative 2. What to do?
9324 (define_insn "*ashlqi3_1_lea"
9325 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9326 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9327 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9328 (clobber (reg:CC FLAGS_REG))]
9329 "!TARGET_PARTIAL_REG_STALL
9330 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9332 switch (get_attr_type (insn))
9338 gcc_assert (operands[2] == const1_rtx);
9339 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9340 return "add{l}\t%k0, %k0";
9342 return "add{b}\t%0, %0";
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9348 if (get_attr_mode (insn) == MODE_SI)
9349 return "sal{l}\t%k0";
9351 return "sal{b}\t%0";
9355 if (get_attr_mode (insn) == MODE_SI)
9356 return "sal{l}\t{%2, %k0|%k0, %2}";
9358 return "sal{b}\t{%2, %0|%0, %2}";
9363 (cond [(eq_attr "alternative" "2")
9364 (const_string "lea")
9365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9367 (match_operand 0 "register_operand" ""))
9368 (match_operand 2 "const1_operand" ""))
9369 (const_string "alu")
9371 (const_string "ishift")))
9372 (set (attr "length_immediate")
9374 (ior (eq_attr "type" "alu")
9375 (and (eq_attr "type" "ishift")
9376 (and (match_operand 2 "const1_operand" "")
9377 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9380 (const_string "*")))
9381 (set_attr "mode" "QI,SI,SI")])
9383 (define_insn "*ashlqi3_1_slp"
9384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9385 (ashift:QI (match_dup 0)
9386 (match_operand:QI 1 "nonmemory_operand" "cI")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "(optimize_function_for_size_p (cfun)
9389 || !TARGET_PARTIAL_FLAG_REG_STALL
9390 || (operands[1] == const1_rtx
9392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9394 switch (get_attr_type (insn))
9397 gcc_assert (operands[1] == const1_rtx);
9398 return "add{b}\t%0, %0";
9401 if (operands[1] == const1_rtx
9402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403 return "sal{b}\t%0";
9405 return "sal{b}\t{%1, %0|%0, %1}";
9409 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9411 (match_operand 0 "register_operand" ""))
9412 (match_operand 1 "const1_operand" ""))
9413 (const_string "alu")
9415 (const_string "ishift1")))
9416 (set (attr "length_immediate")
9418 (ior (eq_attr "type" "alu")
9419 (and (eq_attr "type" "ishift1")
9420 (and (match_operand 1 "const1_operand" "")
9421 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9424 (const_string "*")))
9425 (set_attr "mode" "QI")])
9427 ;; Convert lea to the lea pattern to avoid flags dependency.
9429 [(set (match_operand 0 "register_operand" "")
9430 (ashift (match_operand 1 "index_register_operand" "")
9431 (match_operand:QI 2 "const_int_operand" "")))
9432 (clobber (reg:CC FLAGS_REG))]
9434 && true_regnum (operands[0]) != true_regnum (operands[1])"
9438 enum machine_mode mode = GET_MODE (operands[0]);
9441 operands[1] = gen_lowpart (Pmode, operands[1]);
9442 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9444 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9446 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9447 operands[0] = gen_lowpart (SImode, operands[0]);
9449 if (TARGET_64BIT && mode != Pmode)
9450 pat = gen_rtx_SUBREG (SImode, pat, 0);
9452 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9456 ;; Convert lea to the lea pattern to avoid flags dependency.
9458 [(set (match_operand:DI 0 "register_operand" "")
9460 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9461 (match_operand:QI 2 "const_int_operand" ""))))
9462 (clobber (reg:CC FLAGS_REG))]
9463 "TARGET_64BIT && reload_completed
9464 && true_regnum (operands[0]) != true_regnum (operands[1])"
9466 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9468 operands[1] = gen_lowpart (DImode, operands[1]);
9469 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9472 ;; This pattern can't accept a variable shift count, since shifts by
9473 ;; zero don't affect the flags. We assume that shifts by constant
9474 ;; zero are optimized away.
9475 (define_insn "*ashl<mode>3_cmp"
9476 [(set (reg FLAGS_REG)
9478 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9479 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482 (ashift:SWI (match_dup 1) (match_dup 2)))]
9483 "(optimize_function_for_size_p (cfun)
9484 || !TARGET_PARTIAL_FLAG_REG_STALL
9485 || (operands[2] == const1_rtx
9487 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9488 && ix86_match_ccmode (insn, CCGOCmode)
9489 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9491 switch (get_attr_type (insn))
9494 gcc_assert (operands[2] == const1_rtx);
9495 return "add{<imodesuffix>}\t%0, %0";
9498 if (operands[2] == const1_rtx
9499 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9500 return "sal{<imodesuffix>}\t%0";
9502 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9506 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9508 (match_operand 0 "register_operand" ""))
9509 (match_operand 2 "const1_operand" ""))
9510 (const_string "alu")
9512 (const_string "ishift")))
9513 (set (attr "length_immediate")
9515 (ior (eq_attr "type" "alu")
9516 (and (eq_attr "type" "ishift")
9517 (and (match_operand 2 "const1_operand" "")
9518 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9521 (const_string "*")))
9522 (set_attr "mode" "<MODE>")])
9524 (define_insn "*ashlsi3_cmp_zext"
9525 [(set (reg FLAGS_REG)
9527 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9530 (set (match_operand:DI 0 "register_operand" "=r")
9531 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9533 && (optimize_function_for_size_p (cfun)
9534 || !TARGET_PARTIAL_FLAG_REG_STALL
9535 || (operands[2] == const1_rtx
9537 || TARGET_DOUBLE_WITH_ADD)))
9538 && ix86_match_ccmode (insn, CCGOCmode)
9539 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9541 switch (get_attr_type (insn))
9544 gcc_assert (operands[2] == const1_rtx);
9545 return "add{l}\t%k0, %k0";
9548 if (operands[2] == const1_rtx
9549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9550 return "sal{l}\t%k0";
9552 return "sal{l}\t{%2, %k0|%k0, %2}";
9556 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9558 (match_operand 2 "const1_operand" ""))
9559 (const_string "alu")
9561 (const_string "ishift")))
9562 (set (attr "length_immediate")
9564 (ior (eq_attr "type" "alu")
9565 (and (eq_attr "type" "ishift")
9566 (and (match_operand 2 "const1_operand" "")
9567 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9570 (const_string "*")))
9571 (set_attr "mode" "SI")])
9573 (define_insn "*ashl<mode>3_cconly"
9574 [(set (reg FLAGS_REG)
9576 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9577 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9579 (clobber (match_scratch:SWI 0 "=<r>"))]
9580 "(optimize_function_for_size_p (cfun)
9581 || !TARGET_PARTIAL_FLAG_REG_STALL
9582 || (operands[2] == const1_rtx
9584 || TARGET_DOUBLE_WITH_ADD)))
9585 && ix86_match_ccmode (insn, CCGOCmode)"
9587 switch (get_attr_type (insn))
9590 gcc_assert (operands[2] == const1_rtx);
9591 return "add{<imodesuffix>}\t%0, %0";
9594 if (operands[2] == const1_rtx
9595 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9596 return "sal{<imodesuffix>}\t%0";
9598 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9602 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9604 (match_operand 0 "register_operand" ""))
9605 (match_operand 2 "const1_operand" ""))
9606 (const_string "alu")
9608 (const_string "ishift")))
9609 (set (attr "length_immediate")
9611 (ior (eq_attr "type" "alu")
9612 (and (eq_attr "type" "ishift")
9613 (and (match_operand 2 "const1_operand" "")
9614 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9617 (const_string "*")))
9618 (set_attr "mode" "<MODE>")])
9620 ;; See comment above `ashl<mode>3' about how this works.
9622 (define_expand "<shiftrt_insn><mode>3"
9623 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9624 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9625 (match_operand:QI 2 "nonmemory_operand" "")))]
9627 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9629 ;; Avoid useless masking of count operand.
9630 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9631 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9633 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9636 (match_operand:SI 2 "nonimmediate_operand" "c")
9637 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9638 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9640 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9641 == GET_MODE_BITSIZE (<MODE>mode)-1"
9644 [(parallel [(set (match_dup 0)
9645 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9646 (clobber (reg:CC FLAGS_REG))])]
9648 if (can_create_pseudo_p ())
9649 operands [2] = force_reg (SImode, operands[2]);
9651 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9653 [(set_attr "type" "ishift")
9654 (set_attr "mode" "<MODE>")])
9656 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9657 [(set (match_operand:DWI 0 "register_operand" "=r")
9658 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9659 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9660 (clobber (reg:CC FLAGS_REG))]
9663 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9665 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9666 [(set_attr "type" "multi")])
9668 ;; By default we don't ask for a scratch register, because when DWImode
9669 ;; values are manipulated, registers are already at a premium. But if
9670 ;; we have one handy, we won't turn it away.
9673 [(match_scratch:DWIH 3 "r")
9674 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9676 (match_operand:<DWI> 1 "register_operand" "")
9677 (match_operand:QI 2 "nonmemory_operand" "")))
9678 (clobber (reg:CC FLAGS_REG))])
9682 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9684 (define_insn "x86_64_shrd"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9686 (ior:DI (ashiftrt:DI (match_dup 0)
9687 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9688 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9689 (minus:QI (const_int 64) (match_dup 2)))))
9690 (clobber (reg:CC FLAGS_REG))]
9692 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9693 [(set_attr "type" "ishift")
9694 (set_attr "prefix_0f" "1")
9695 (set_attr "mode" "DI")
9696 (set_attr "athlon_decode" "vector")
9697 (set_attr "amdfam10_decode" "vector")
9698 (set_attr "bdver1_decode" "vector")])
9700 (define_insn "x86_shrd"
9701 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9702 (ior:SI (ashiftrt:SI (match_dup 0)
9703 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9704 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9705 (minus:QI (const_int 32) (match_dup 2)))))
9706 (clobber (reg:CC FLAGS_REG))]
9708 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9709 [(set_attr "type" "ishift")
9710 (set_attr "prefix_0f" "1")
9711 (set_attr "mode" "SI")
9712 (set_attr "pent_pair" "np")
9713 (set_attr "athlon_decode" "vector")
9714 (set_attr "amdfam10_decode" "vector")
9715 (set_attr "bdver1_decode" "vector")])
9717 (define_insn "ashrdi3_cvt"
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9719 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9720 (match_operand:QI 2 "const_int_operand" "")))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_64BIT && INTVAL (operands[2]) == 63
9723 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9724 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9727 sar{q}\t{%2, %0|%0, %2}"
9728 [(set_attr "type" "imovx,ishift")
9729 (set_attr "prefix_0f" "0,*")
9730 (set_attr "length_immediate" "0,*")
9731 (set_attr "modrm" "0,1")
9732 (set_attr "mode" "DI")])
9734 (define_insn "ashrsi3_cvt"
9735 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9736 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9737 (match_operand:QI 2 "const_int_operand" "")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "INTVAL (operands[2]) == 31
9740 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9741 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9744 sar{l}\t{%2, %0|%0, %2}"
9745 [(set_attr "type" "imovx,ishift")
9746 (set_attr "prefix_0f" "0,*")
9747 (set_attr "length_immediate" "0,*")
9748 (set_attr "modrm" "0,1")
9749 (set_attr "mode" "SI")])
9751 (define_insn "*ashrsi3_cvt_zext"
9752 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9754 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9755 (match_operand:QI 2 "const_int_operand" ""))))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_64BIT && INTVAL (operands[2]) == 31
9758 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9759 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9762 sar{l}\t{%2, %k0|%k0, %2}"
9763 [(set_attr "type" "imovx,ishift")
9764 (set_attr "prefix_0f" "0,*")
9765 (set_attr "length_immediate" "0,*")
9766 (set_attr "modrm" "0,1")
9767 (set_attr "mode" "SI")])
9769 (define_expand "x86_shift<mode>_adj_3"
9770 [(use (match_operand:SWI48 0 "register_operand" ""))
9771 (use (match_operand:SWI48 1 "register_operand" ""))
9772 (use (match_operand:QI 2 "register_operand" ""))]
9775 rtx label = gen_label_rtx ();
9778 emit_insn (gen_testqi_ccz_1 (operands[2],
9779 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9781 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9782 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9783 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9784 gen_rtx_LABEL_REF (VOIDmode, label),
9786 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9787 JUMP_LABEL (tmp) = label;
9789 emit_move_insn (operands[0], operands[1]);
9790 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9791 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9793 LABEL_NUSES (label) = 1;
9798 (define_insn "*<shiftrt_insn><mode>3_1"
9799 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9800 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9801 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9805 if (operands[2] == const1_rtx
9806 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807 return "<shiftrt>{<imodesuffix>}\t%0";
9809 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9811 [(set_attr "type" "ishift")
9812 (set (attr "length_immediate")
9814 (and (match_operand 2 "const1_operand" "")
9815 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9818 (const_string "*")))
9819 (set_attr "mode" "<MODE>")])
9821 (define_insn "*<shiftrt_insn>si3_1_zext"
9822 [(set (match_operand:DI 0 "register_operand" "=r")
9824 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9825 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9829 if (operands[2] == const1_rtx
9830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9831 return "<shiftrt>{l}\t%k0";
9833 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9835 [(set_attr "type" "ishift")
9836 (set (attr "length_immediate")
9838 (and (match_operand 2 "const1_operand" "")
9839 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9842 (const_string "*")))
9843 (set_attr "mode" "SI")])
9845 (define_insn "*<shiftrt_insn>qi3_1_slp"
9846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9847 (any_shiftrt:QI (match_dup 0)
9848 (match_operand:QI 1 "nonmemory_operand" "cI")))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "(optimize_function_for_size_p (cfun)
9851 || !TARGET_PARTIAL_REG_STALL
9852 || (operands[1] == const1_rtx
9855 if (operands[1] == const1_rtx
9856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9857 return "<shiftrt>{b}\t%0";
9859 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9861 [(set_attr "type" "ishift1")
9862 (set (attr "length_immediate")
9864 (and (match_operand 1 "const1_operand" "")
9865 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9868 (const_string "*")))
9869 (set_attr "mode" "QI")])
9871 ;; This pattern can't accept a variable shift count, since shifts by
9872 ;; zero don't affect the flags. We assume that shifts by constant
9873 ;; zero are optimized away.
9874 (define_insn "*<shiftrt_insn><mode>3_cmp"
9875 [(set (reg FLAGS_REG)
9878 (match_operand:SWI 1 "nonimmediate_operand" "0")
9879 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9882 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9883 "(optimize_function_for_size_p (cfun)
9884 || !TARGET_PARTIAL_FLAG_REG_STALL
9885 || (operands[2] == const1_rtx
9887 && ix86_match_ccmode (insn, CCGOCmode)
9888 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9890 if (operands[2] == const1_rtx
9891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892 return "<shiftrt>{<imodesuffix>}\t%0";
9894 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9896 [(set_attr "type" "ishift")
9897 (set (attr "length_immediate")
9899 (and (match_operand 2 "const1_operand" "")
9900 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9903 (const_string "*")))
9904 (set_attr "mode" "<MODE>")])
9906 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9907 [(set (reg FLAGS_REG)
9909 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9910 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9912 (set (match_operand:DI 0 "register_operand" "=r")
9913 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9915 && (optimize_function_for_size_p (cfun)
9916 || !TARGET_PARTIAL_FLAG_REG_STALL
9917 || (operands[2] == const1_rtx
9919 && ix86_match_ccmode (insn, CCGOCmode)
9920 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9922 if (operands[2] == const1_rtx
9923 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9924 return "<shiftrt>{l}\t%k0";
9926 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9928 [(set_attr "type" "ishift")
9929 (set (attr "length_immediate")
9931 (and (match_operand 2 "const1_operand" "")
9932 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9935 (const_string "*")))
9936 (set_attr "mode" "SI")])
9938 (define_insn "*<shiftrt_insn><mode>3_cconly"
9939 [(set (reg FLAGS_REG)
9942 (match_operand:SWI 1 "register_operand" "0")
9943 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9945 (clobber (match_scratch:SWI 0 "=<r>"))]
9946 "(optimize_function_for_size_p (cfun)
9947 || !TARGET_PARTIAL_FLAG_REG_STALL
9948 || (operands[2] == const1_rtx
9950 && ix86_match_ccmode (insn, CCGOCmode)"
9952 if (operands[2] == const1_rtx
9953 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 return "<shiftrt>{<imodesuffix>}\t%0";
9956 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9958 [(set_attr "type" "ishift")
9959 (set (attr "length_immediate")
9961 (and (match_operand 2 "const1_operand" "")
9962 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9965 (const_string "*")))
9966 (set_attr "mode" "<MODE>")])
9968 ;; Rotate instructions
9970 (define_expand "<rotate_insn>ti3"
9971 [(set (match_operand:TI 0 "register_operand" "")
9972 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9973 (match_operand:QI 2 "nonmemory_operand" "")))]
9976 if (const_1_to_63_operand (operands[2], VOIDmode))
9977 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9978 (operands[0], operands[1], operands[2]));
9985 (define_expand "<rotate_insn>di3"
9986 [(set (match_operand:DI 0 "shiftdi_operand" "")
9987 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9988 (match_operand:QI 2 "nonmemory_operand" "")))]
9992 ix86_expand_binary_operator (<CODE>, DImode, operands);
9993 else if (const_1_to_31_operand (operands[2], VOIDmode))
9994 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9995 (operands[0], operands[1], operands[2]));
10002 (define_expand "<rotate_insn><mode>3"
10003 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10004 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10005 (match_operand:QI 2 "nonmemory_operand" "")))]
10007 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10009 ;; Avoid useless masking of count operand.
10010 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10011 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10013 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10016 (match_operand:SI 2 "nonimmediate_operand" "c")
10017 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10018 (clobber (reg:CC FLAGS_REG))]
10019 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10020 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10021 == GET_MODE_BITSIZE (<MODE>mode)-1"
10024 [(parallel [(set (match_dup 0)
10025 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10026 (clobber (reg:CC FLAGS_REG))])]
10028 if (can_create_pseudo_p ())
10029 operands [2] = force_reg (SImode, operands[2]);
10031 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10033 [(set_attr "type" "rotate")
10034 (set_attr "mode" "<MODE>")])
10036 ;; Implement rotation using two double-precision
10037 ;; shift instructions and a scratch register.
10039 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10040 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10041 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10042 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10043 (clobber (reg:CC FLAGS_REG))
10044 (clobber (match_scratch:DWIH 3 "=&r"))]
10048 [(set (match_dup 3) (match_dup 4))
10050 [(set (match_dup 4)
10051 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10052 (lshiftrt:DWIH (match_dup 5)
10053 (minus:QI (match_dup 6) (match_dup 2)))))
10054 (clobber (reg:CC FLAGS_REG))])
10056 [(set (match_dup 5)
10057 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10058 (lshiftrt:DWIH (match_dup 3)
10059 (minus:QI (match_dup 6) (match_dup 2)))))
10060 (clobber (reg:CC FLAGS_REG))])]
10062 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10064 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10067 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10068 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10069 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10070 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10071 (clobber (reg:CC FLAGS_REG))
10072 (clobber (match_scratch:DWIH 3 "=&r"))]
10076 [(set (match_dup 3) (match_dup 4))
10078 [(set (match_dup 4)
10079 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10080 (ashift:DWIH (match_dup 5)
10081 (minus:QI (match_dup 6) (match_dup 2)))))
10082 (clobber (reg:CC FLAGS_REG))])
10084 [(set (match_dup 5)
10085 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10086 (ashift:DWIH (match_dup 3)
10087 (minus:QI (match_dup 6) (match_dup 2)))))
10088 (clobber (reg:CC FLAGS_REG))])]
10090 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10092 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10095 (define_insn "*<rotate_insn><mode>3_1"
10096 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10097 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10098 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10102 if (operands[2] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104 return "<rotate>{<imodesuffix>}\t%0";
10106 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10108 [(set_attr "type" "rotate")
10109 (set (attr "length_immediate")
10111 (and (match_operand 2 "const1_operand" "")
10112 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10115 (const_string "*")))
10116 (set_attr "mode" "<MODE>")])
10118 (define_insn "*<rotate_insn>si3_1_zext"
10119 [(set (match_operand:DI 0 "register_operand" "=r")
10121 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10122 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10123 (clobber (reg:CC FLAGS_REG))]
10124 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10126 if (operands[2] == const1_rtx
10127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10128 return "<rotate>{l}\t%k0";
10130 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10132 [(set_attr "type" "rotate")
10133 (set (attr "length_immediate")
10135 (and (match_operand 2 "const1_operand" "")
10136 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10139 (const_string "*")))
10140 (set_attr "mode" "SI")])
10142 (define_insn "*<rotate_insn>qi3_1_slp"
10143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10144 (any_rotate:QI (match_dup 0)
10145 (match_operand:QI 1 "nonmemory_operand" "cI")))
10146 (clobber (reg:CC FLAGS_REG))]
10147 "(optimize_function_for_size_p (cfun)
10148 || !TARGET_PARTIAL_REG_STALL
10149 || (operands[1] == const1_rtx
10150 && TARGET_SHIFT1))"
10152 if (operands[1] == const1_rtx
10153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10154 return "<rotate>{b}\t%0";
10156 return "<rotate>{b}\t{%1, %0|%0, %1}";
10158 [(set_attr "type" "rotate1")
10159 (set (attr "length_immediate")
10161 (and (match_operand 1 "const1_operand" "")
10162 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10165 (const_string "*")))
10166 (set_attr "mode" "QI")])
10169 [(set (match_operand:HI 0 "register_operand" "")
10170 (any_rotate:HI (match_dup 0) (const_int 8)))
10171 (clobber (reg:CC FLAGS_REG))]
10173 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10174 [(parallel [(set (strict_low_part (match_dup 0))
10175 (bswap:HI (match_dup 0)))
10176 (clobber (reg:CC FLAGS_REG))])])
10178 ;; Bit set / bit test instructions
10180 (define_expand "extv"
10181 [(set (match_operand:SI 0 "register_operand" "")
10182 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10183 (match_operand:SI 2 "const8_operand" "")
10184 (match_operand:SI 3 "const8_operand" "")))]
10187 /* Handle extractions from %ah et al. */
10188 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10191 /* From mips.md: extract_bit_field doesn't verify that our source
10192 matches the predicate, so check it again here. */
10193 if (! ext_register_operand (operands[1], VOIDmode))
10197 (define_expand "extzv"
10198 [(set (match_operand:SI 0 "register_operand" "")
10199 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10200 (match_operand:SI 2 "const8_operand" "")
10201 (match_operand:SI 3 "const8_operand" "")))]
10204 /* Handle extractions from %ah et al. */
10205 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10208 /* From mips.md: extract_bit_field doesn't verify that our source
10209 matches the predicate, so check it again here. */
10210 if (! ext_register_operand (operands[1], VOIDmode))
10214 (define_expand "insv"
10215 [(set (zero_extract (match_operand 0 "register_operand" "")
10216 (match_operand 1 "const_int_operand" "")
10217 (match_operand 2 "const_int_operand" ""))
10218 (match_operand 3 "register_operand" ""))]
10221 rtx (*gen_mov_insv_1) (rtx, rtx);
10223 if (ix86_expand_pinsr (operands))
10226 /* Handle insertions to %ah et al. */
10227 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10230 /* From mips.md: insert_bit_field doesn't verify that our source
10231 matches the predicate, so check it again here. */
10232 if (! ext_register_operand (operands[0], VOIDmode))
10235 gen_mov_insv_1 = (TARGET_64BIT
10236 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10238 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10242 ;; %%% bts, btr, btc, bt.
10243 ;; In general these instructions are *slow* when applied to memory,
10244 ;; since they enforce atomic operation. When applied to registers,
10245 ;; it depends on the cpu implementation. They're never faster than
10246 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10247 ;; no point. But in 64-bit, we can't hold the relevant immediates
10248 ;; within the instruction itself, so operating on bits in the high
10249 ;; 32-bits of a register becomes easier.
10251 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10252 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10253 ;; negdf respectively, so they can never be disabled entirely.
10255 (define_insn "*btsq"
10256 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10258 (match_operand:DI 1 "const_0_to_63_operand" ""))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10262 "bts{q}\t{%1, %0|%0, %1}"
10263 [(set_attr "type" "alu1")
10264 (set_attr "prefix_0f" "1")
10265 (set_attr "mode" "DI")])
10267 (define_insn "*btrq"
10268 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10270 (match_operand:DI 1 "const_0_to_63_operand" ""))
10272 (clobber (reg:CC FLAGS_REG))]
10273 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10274 "btr{q}\t{%1, %0|%0, %1}"
10275 [(set_attr "type" "alu1")
10276 (set_attr "prefix_0f" "1")
10277 (set_attr "mode" "DI")])
10279 (define_insn "*btcq"
10280 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10282 (match_operand:DI 1 "const_0_to_63_operand" ""))
10283 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10286 "btc{q}\t{%1, %0|%0, %1}"
10287 [(set_attr "type" "alu1")
10288 (set_attr "prefix_0f" "1")
10289 (set_attr "mode" "DI")])
10291 ;; Allow Nocona to avoid these instructions if a register is available.
10294 [(match_scratch:DI 2 "r")
10295 (parallel [(set (zero_extract:DI
10296 (match_operand:DI 0 "register_operand" "")
10298 (match_operand:DI 1 "const_0_to_63_operand" ""))
10300 (clobber (reg:CC FLAGS_REG))])]
10301 "TARGET_64BIT && !TARGET_USE_BT"
10304 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10307 if (HOST_BITS_PER_WIDE_INT >= 64)
10308 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10309 else if (i < HOST_BITS_PER_WIDE_INT)
10310 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10314 op1 = immed_double_const (lo, hi, DImode);
10317 emit_move_insn (operands[2], op1);
10321 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10326 [(match_scratch:DI 2 "r")
10327 (parallel [(set (zero_extract:DI
10328 (match_operand:DI 0 "register_operand" "")
10330 (match_operand:DI 1 "const_0_to_63_operand" ""))
10332 (clobber (reg:CC FLAGS_REG))])]
10333 "TARGET_64BIT && !TARGET_USE_BT"
10336 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10339 if (HOST_BITS_PER_WIDE_INT >= 64)
10340 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10341 else if (i < HOST_BITS_PER_WIDE_INT)
10342 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10344 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10346 op1 = immed_double_const (~lo, ~hi, DImode);
10349 emit_move_insn (operands[2], op1);
10353 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10358 [(match_scratch:DI 2 "r")
10359 (parallel [(set (zero_extract:DI
10360 (match_operand:DI 0 "register_operand" "")
10362 (match_operand:DI 1 "const_0_to_63_operand" ""))
10363 (not:DI (zero_extract:DI
10364 (match_dup 0) (const_int 1) (match_dup 1))))
10365 (clobber (reg:CC FLAGS_REG))])]
10366 "TARGET_64BIT && !TARGET_USE_BT"
10369 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10372 if (HOST_BITS_PER_WIDE_INT >= 64)
10373 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10374 else if (i < HOST_BITS_PER_WIDE_INT)
10375 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10377 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10379 op1 = immed_double_const (lo, hi, DImode);
10382 emit_move_insn (operands[2], op1);
10386 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10390 (define_insn "*bt<mode>"
10391 [(set (reg:CCC FLAGS_REG)
10393 (zero_extract:SWI48
10394 (match_operand:SWI48 0 "register_operand" "r")
10396 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10398 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10399 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10400 [(set_attr "type" "alu1")
10401 (set_attr "prefix_0f" "1")
10402 (set_attr "mode" "<MODE>")])
10404 ;; Store-flag instructions.
10406 ;; For all sCOND expanders, also expand the compare or test insn that
10407 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10409 (define_insn_and_split "*setcc_di_1"
10410 [(set (match_operand:DI 0 "register_operand" "=q")
10411 (match_operator:DI 1 "ix86_comparison_operator"
10412 [(reg FLAGS_REG) (const_int 0)]))]
10413 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10415 "&& reload_completed"
10416 [(set (match_dup 2) (match_dup 1))
10417 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10419 PUT_MODE (operands[1], QImode);
10420 operands[2] = gen_lowpart (QImode, operands[0]);
10423 (define_insn_and_split "*setcc_si_1_and"
10424 [(set (match_operand:SI 0 "register_operand" "=q")
10425 (match_operator:SI 1 "ix86_comparison_operator"
10426 [(reg FLAGS_REG) (const_int 0)]))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "!TARGET_PARTIAL_REG_STALL
10429 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10431 "&& reload_completed"
10432 [(set (match_dup 2) (match_dup 1))
10433 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10434 (clobber (reg:CC FLAGS_REG))])]
10436 PUT_MODE (operands[1], QImode);
10437 operands[2] = gen_lowpart (QImode, operands[0]);
10440 (define_insn_and_split "*setcc_si_1_movzbl"
10441 [(set (match_operand:SI 0 "register_operand" "=q")
10442 (match_operator:SI 1 "ix86_comparison_operator"
10443 [(reg FLAGS_REG) (const_int 0)]))]
10444 "!TARGET_PARTIAL_REG_STALL
10445 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10447 "&& reload_completed"
10448 [(set (match_dup 2) (match_dup 1))
10449 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10451 PUT_MODE (operands[1], QImode);
10452 operands[2] = gen_lowpart (QImode, operands[0]);
10455 (define_insn "*setcc_qi"
10456 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10457 (match_operator:QI 1 "ix86_comparison_operator"
10458 [(reg FLAGS_REG) (const_int 0)]))]
10461 [(set_attr "type" "setcc")
10462 (set_attr "mode" "QI")])
10464 (define_insn "*setcc_qi_slp"
10465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10466 (match_operator:QI 1 "ix86_comparison_operator"
10467 [(reg FLAGS_REG) (const_int 0)]))]
10470 [(set_attr "type" "setcc")
10471 (set_attr "mode" "QI")])
10473 ;; In general it is not safe to assume too much about CCmode registers,
10474 ;; so simplify-rtx stops when it sees a second one. Under certain
10475 ;; conditions this is safe on x86, so help combine not create
10482 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10483 (ne:QI (match_operator 1 "ix86_comparison_operator"
10484 [(reg FLAGS_REG) (const_int 0)])
10487 [(set (match_dup 0) (match_dup 1))]
10488 "PUT_MODE (operands[1], QImode);")
10491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10492 (ne:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10496 [(set (match_dup 0) (match_dup 1))]
10497 "PUT_MODE (operands[1], QImode);")
10500 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10501 (eq:QI (match_operator 1 "ix86_comparison_operator"
10502 [(reg FLAGS_REG) (const_int 0)])
10505 [(set (match_dup 0) (match_dup 1))]
10507 rtx new_op1 = copy_rtx (operands[1]);
10508 operands[1] = new_op1;
10509 PUT_MODE (new_op1, QImode);
10510 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10511 GET_MODE (XEXP (new_op1, 0))));
10513 /* Make sure that (a) the CCmode we have for the flags is strong
10514 enough for the reversed compare or (b) we have a valid FP compare. */
10515 if (! ix86_comparison_operator (new_op1, VOIDmode))
10520 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10521 (eq:QI (match_operator 1 "ix86_comparison_operator"
10522 [(reg FLAGS_REG) (const_int 0)])
10525 [(set (match_dup 0) (match_dup 1))]
10527 rtx new_op1 = copy_rtx (operands[1]);
10528 operands[1] = new_op1;
10529 PUT_MODE (new_op1, QImode);
10530 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10531 GET_MODE (XEXP (new_op1, 0))));
10533 /* Make sure that (a) the CCmode we have for the flags is strong
10534 enough for the reversed compare or (b) we have a valid FP compare. */
10535 if (! ix86_comparison_operator (new_op1, VOIDmode))
10539 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10540 ;; subsequent logical operations are used to imitate conditional moves.
10541 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10544 (define_insn "setcc_<mode>_sse"
10545 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10546 (match_operator:MODEF 3 "sse_comparison_operator"
10547 [(match_operand:MODEF 1 "register_operand" "0,x")
10548 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10549 "SSE_FLOAT_MODE_P (<MODE>mode)"
10551 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10552 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10553 [(set_attr "isa" "noavx,avx")
10554 (set_attr "type" "ssecmp")
10555 (set_attr "length_immediate" "1")
10556 (set_attr "prefix" "orig,vex")
10557 (set_attr "mode" "<MODE>")])
10559 ;; Basic conditional jump instructions.
10560 ;; We ignore the overflow flag for signed branch instructions.
10562 (define_insn "*jcc_1"
10564 (if_then_else (match_operator 1 "ix86_comparison_operator"
10565 [(reg FLAGS_REG) (const_int 0)])
10566 (label_ref (match_operand 0 "" ""))
10570 [(set_attr "type" "ibr")
10571 (set_attr "modrm" "0")
10572 (set (attr "length")
10573 (if_then_else (and (ge (minus (match_dup 0) (pc))
10575 (lt (minus (match_dup 0) (pc))
10580 (define_insn "*jcc_2"
10582 (if_then_else (match_operator 1 "ix86_comparison_operator"
10583 [(reg FLAGS_REG) (const_int 0)])
10585 (label_ref (match_operand 0 "" ""))))]
10588 [(set_attr "type" "ibr")
10589 (set_attr "modrm" "0")
10590 (set (attr "length")
10591 (if_then_else (and (ge (minus (match_dup 0) (pc))
10593 (lt (minus (match_dup 0) (pc))
10598 ;; In general it is not safe to assume too much about CCmode registers,
10599 ;; so simplify-rtx stops when it sees a second one. Under certain
10600 ;; conditions this is safe on x86, so help combine not create
10608 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)])
10611 (label_ref (match_operand 1 "" ""))
10615 (if_then_else (match_dup 0)
10616 (label_ref (match_dup 1))
10618 "PUT_MODE (operands[0], VOIDmode);")
10622 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)])
10625 (label_ref (match_operand 1 "" ""))
10629 (if_then_else (match_dup 0)
10630 (label_ref (match_dup 1))
10633 rtx new_op0 = copy_rtx (operands[0]);
10634 operands[0] = new_op0;
10635 PUT_MODE (new_op0, VOIDmode);
10636 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10637 GET_MODE (XEXP (new_op0, 0))));
10639 /* Make sure that (a) the CCmode we have for the flags is strong
10640 enough for the reversed compare or (b) we have a valid FP compare. */
10641 if (! ix86_comparison_operator (new_op0, VOIDmode))
10645 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10646 ;; pass generates from shift insn with QImode operand. Actually, the mode
10647 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10648 ;; appropriate modulo of the bit offset value.
10650 (define_insn_and_split "*jcc_bt<mode>"
10652 (if_then_else (match_operator 0 "bt_comparison_operator"
10653 [(zero_extract:SWI48
10654 (match_operand:SWI48 1 "register_operand" "r")
10657 (match_operand:QI 2 "register_operand" "r")))
10659 (label_ref (match_operand 3 "" ""))
10661 (clobber (reg:CC FLAGS_REG))]
10662 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10665 [(set (reg:CCC FLAGS_REG)
10667 (zero_extract:SWI48
10673 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10674 (label_ref (match_dup 3))
10677 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10679 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10682 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10683 ;; also for DImode, this is what combine produces.
10684 (define_insn_and_split "*jcc_bt<mode>_mask"
10686 (if_then_else (match_operator 0 "bt_comparison_operator"
10687 [(zero_extract:SWI48
10688 (match_operand:SWI48 1 "register_operand" "r")
10691 (match_operand:SI 2 "register_operand" "r")
10692 (match_operand:SI 3 "const_int_operand" "n")))])
10693 (label_ref (match_operand 4 "" ""))
10695 (clobber (reg:CC FLAGS_REG))]
10696 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10697 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10698 == GET_MODE_BITSIZE (<MODE>mode)-1"
10701 [(set (reg:CCC FLAGS_REG)
10703 (zero_extract:SWI48
10709 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10710 (label_ref (match_dup 4))
10713 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10715 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10718 (define_insn_and_split "*jcc_btsi_1"
10720 (if_then_else (match_operator 0 "bt_comparison_operator"
10723 (match_operand:SI 1 "register_operand" "r")
10724 (match_operand:QI 2 "register_operand" "r"))
10727 (label_ref (match_operand 3 "" ""))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10733 [(set (reg:CCC FLAGS_REG)
10741 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10742 (label_ref (match_dup 3))
10745 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10747 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10750 ;; avoid useless masking of bit offset operand
10751 (define_insn_and_split "*jcc_btsi_mask_1"
10754 (match_operator 0 "bt_comparison_operator"
10757 (match_operand:SI 1 "register_operand" "r")
10760 (match_operand:SI 2 "register_operand" "r")
10761 (match_operand:SI 3 "const_int_operand" "n")) 0))
10764 (label_ref (match_operand 4 "" ""))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10768 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10771 [(set (reg:CCC FLAGS_REG)
10779 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10780 (label_ref (match_dup 4))
10782 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10784 ;; Define combination compare-and-branch fp compare instructions to help
10787 (define_insn "*fp_jcc_1_387"
10789 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10790 [(match_operand 1 "register_operand" "f")
10791 (match_operand 2 "nonimmediate_operand" "fm")])
10792 (label_ref (match_operand 3 "" ""))
10794 (clobber (reg:CCFP FPSR_REG))
10795 (clobber (reg:CCFP FLAGS_REG))
10796 (clobber (match_scratch:HI 4 "=a"))]
10798 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10800 && SELECT_CC_MODE (GET_CODE (operands[0]),
10801 operands[1], operands[2]) == CCFPmode
10805 (define_insn "*fp_jcc_1r_387"
10807 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10808 [(match_operand 1 "register_operand" "f")
10809 (match_operand 2 "nonimmediate_operand" "fm")])
10811 (label_ref (match_operand 3 "" ""))))
10812 (clobber (reg:CCFP FPSR_REG))
10813 (clobber (reg:CCFP FLAGS_REG))
10814 (clobber (match_scratch:HI 4 "=a"))]
10816 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10817 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10818 && SELECT_CC_MODE (GET_CODE (operands[0]),
10819 operands[1], operands[2]) == CCFPmode
10823 (define_insn "*fp_jcc_2_387"
10825 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10826 [(match_operand 1 "register_operand" "f")
10827 (match_operand 2 "register_operand" "f")])
10828 (label_ref (match_operand 3 "" ""))
10830 (clobber (reg:CCFP FPSR_REG))
10831 (clobber (reg:CCFP FLAGS_REG))
10832 (clobber (match_scratch:HI 4 "=a"))]
10833 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10838 (define_insn "*fp_jcc_2r_387"
10840 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10841 [(match_operand 1 "register_operand" "f")
10842 (match_operand 2 "register_operand" "f")])
10844 (label_ref (match_operand 3 "" ""))))
10845 (clobber (reg:CCFP FPSR_REG))
10846 (clobber (reg:CCFP FLAGS_REG))
10847 (clobber (match_scratch:HI 4 "=a"))]
10848 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10849 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10853 (define_insn "*fp_jcc_3_387"
10855 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10856 [(match_operand 1 "register_operand" "f")
10857 (match_operand 2 "const0_operand" "")])
10858 (label_ref (match_operand 3 "" ""))
10860 (clobber (reg:CCFP FPSR_REG))
10861 (clobber (reg:CCFP FLAGS_REG))
10862 (clobber (match_scratch:HI 4 "=a"))]
10863 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10864 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10865 && SELECT_CC_MODE (GET_CODE (operands[0]),
10866 operands[1], operands[2]) == CCFPmode
10872 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10873 [(match_operand 1 "register_operand" "")
10874 (match_operand 2 "nonimmediate_operand" "")])
10875 (match_operand 3 "" "")
10876 (match_operand 4 "" "")))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))]
10882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10883 operands[3], operands[4], NULL_RTX, NULL_RTX);
10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890 [(match_operand 1 "register_operand" "")
10891 (match_operand 2 "general_operand" "")])
10892 (match_operand 3 "" "")
10893 (match_operand 4 "" "")))
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))
10896 (clobber (match_scratch:HI 5 "=a"))]
10900 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10901 operands[3], operands[4], operands[5], NULL_RTX);
10905 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10906 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10907 ;; with a precedence over other operators and is always put in the first
10908 ;; place. Swap condition and operands to match ficom instruction.
10910 (define_insn "*fp_jcc_4_<mode>_387"
10913 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10914 [(match_operator 1 "float_operator"
10915 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10916 (match_operand 3 "register_operand" "f,f")])
10917 (label_ref (match_operand 4 "" ""))
10919 (clobber (reg:CCFP FPSR_REG))
10920 (clobber (reg:CCFP FLAGS_REG))
10921 (clobber (match_scratch:HI 5 "=a,a"))]
10922 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10923 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10924 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10925 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10932 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10933 [(match_operator 1 "float_operator"
10934 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10935 (match_operand 3 "register_operand" "")])
10936 (match_operand 4 "" "")
10937 (match_operand 5 "" "")))
10938 (clobber (reg:CCFP FPSR_REG))
10939 (clobber (reg:CCFP FLAGS_REG))
10940 (clobber (match_scratch:HI 6 "=a"))]
10944 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10946 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10947 operands[3], operands[7],
10948 operands[4], operands[5], operands[6], NULL_RTX);
10952 ;; %%% Kill this when reload knows how to do it.
10956 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10957 [(match_operator 1 "float_operator"
10958 [(match_operand:X87MODEI12 2 "register_operand" "")])
10959 (match_operand 3 "register_operand" "")])
10960 (match_operand 4 "" "")
10961 (match_operand 5 "" "")))
10962 (clobber (reg:CCFP FPSR_REG))
10963 (clobber (reg:CCFP FLAGS_REG))
10964 (clobber (match_scratch:HI 6 "=a"))]
10968 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10969 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10971 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10972 operands[3], operands[7],
10973 operands[4], operands[5], operands[6], operands[2]);
10977 ;; Unconditional and other jump instructions
10979 (define_insn "jump"
10981 (label_ref (match_operand 0 "" "")))]
10984 [(set_attr "type" "ibr")
10985 (set (attr "length")
10986 (if_then_else (and (ge (minus (match_dup 0) (pc))
10988 (lt (minus (match_dup 0) (pc))
10992 (set_attr "modrm" "0")])
10994 (define_expand "indirect_jump"
10995 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10999 (define_insn "*indirect_jump"
11000 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11003 [(set_attr "type" "ibr")
11004 (set_attr "length_immediate" "0")])
11006 (define_expand "tablejump"
11007 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11008 (use (label_ref (match_operand 1 "" "")))])]
11011 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11012 relative. Convert the relative address to an absolute address. */
11016 enum rtx_code code;
11018 /* We can't use @GOTOFF for text labels on VxWorks;
11019 see gotoff_operand. */
11020 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11024 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11026 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11030 op1 = pic_offset_table_rtx;
11035 op0 = pic_offset_table_rtx;
11039 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11044 (define_insn "*tablejump_1"
11045 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11046 (use (label_ref (match_operand 1 "" "")))]
11049 [(set_attr "type" "ibr")
11050 (set_attr "length_immediate" "0")])
11052 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11055 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11056 (set (match_operand:QI 1 "register_operand" "")
11057 (match_operator:QI 2 "ix86_comparison_operator"
11058 [(reg FLAGS_REG) (const_int 0)]))
11059 (set (match_operand 3 "q_regs_operand" "")
11060 (zero_extend (match_dup 1)))]
11061 "(peep2_reg_dead_p (3, operands[1])
11062 || operands_match_p (operands[1], operands[3]))
11063 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11064 [(set (match_dup 4) (match_dup 0))
11065 (set (strict_low_part (match_dup 5))
11068 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11069 operands[5] = gen_lowpart (QImode, operands[3]);
11070 ix86_expand_clear (operands[3]);
11073 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11076 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11077 (set (match_operand:QI 1 "register_operand" "")
11078 (match_operator:QI 2 "ix86_comparison_operator"
11079 [(reg FLAGS_REG) (const_int 0)]))
11080 (parallel [(set (match_operand 3 "q_regs_operand" "")
11081 (zero_extend (match_dup 1)))
11082 (clobber (reg:CC FLAGS_REG))])]
11083 "(peep2_reg_dead_p (3, operands[1])
11084 || operands_match_p (operands[1], operands[3]))
11085 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11086 [(set (match_dup 4) (match_dup 0))
11087 (set (strict_low_part (match_dup 5))
11090 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11091 operands[5] = gen_lowpart (QImode, operands[3]);
11092 ix86_expand_clear (operands[3]);
11095 ;; Call instructions.
11097 ;; The predicates normally associated with named expanders are not properly
11098 ;; checked for calls. This is a bug in the generic code, but it isn't that
11099 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11101 ;; P6 processors will jump to the address after the decrement when %esp
11102 ;; is used as a call operand, so they will execute return address as a code.
11103 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11105 ;; Register constraint for call instruction.
11106 (define_mode_attr c [(SI "l") (DI "r")])
11108 ;; Call subroutine returning no value.
11110 (define_expand "call"
11111 [(call (match_operand:QI 0 "" "")
11112 (match_operand 1 "" ""))
11113 (use (match_operand 2 "" ""))]
11116 ix86_expand_call (NULL, operands[0], operands[1],
11117 operands[2], NULL, false);
11121 (define_expand "sibcall"
11122 [(call (match_operand:QI 0 "" "")
11123 (match_operand 1 "" ""))
11124 (use (match_operand 2 "" ""))]
11127 ix86_expand_call (NULL, operands[0], operands[1],
11128 operands[2], NULL, true);
11132 (define_insn_and_split "*call_vzeroupper"
11133 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11134 (match_operand 1 "" ""))
11135 (unspec [(match_operand 2 "const_int_operand" "")]
11136 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11137 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11139 "&& reload_completed"
11141 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11142 [(set_attr "type" "call")])
11144 (define_insn "*call"
11145 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11146 (match_operand 1 "" ""))]
11147 "!SIBLING_CALL_P (insn)"
11148 "* return ix86_output_call_insn (insn, operands[0]);"
11149 [(set_attr "type" "call")])
11151 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11153 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11154 (match_operand 1 "" ""))
11155 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11156 (clobber (reg:TI XMM6_REG))
11157 (clobber (reg:TI XMM7_REG))
11158 (clobber (reg:TI XMM8_REG))
11159 (clobber (reg:TI XMM9_REG))
11160 (clobber (reg:TI XMM10_REG))
11161 (clobber (reg:TI XMM11_REG))
11162 (clobber (reg:TI XMM12_REG))
11163 (clobber (reg:TI XMM13_REG))
11164 (clobber (reg:TI XMM14_REG))
11165 (clobber (reg:TI XMM15_REG))
11166 (clobber (reg:DI SI_REG))
11167 (clobber (reg:DI DI_REG))])
11168 (unspec [(match_operand 2 "const_int_operand" "")]
11169 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11170 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11172 "&& reload_completed"
11174 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11175 [(set_attr "type" "call")])
11177 (define_insn "*call_rex64_ms_sysv"
11178 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11179 (match_operand 1 "" ""))
11180 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11181 (clobber (reg:TI XMM6_REG))
11182 (clobber (reg:TI XMM7_REG))
11183 (clobber (reg:TI XMM8_REG))
11184 (clobber (reg:TI XMM9_REG))
11185 (clobber (reg:TI XMM10_REG))
11186 (clobber (reg:TI XMM11_REG))
11187 (clobber (reg:TI XMM12_REG))
11188 (clobber (reg:TI XMM13_REG))
11189 (clobber (reg:TI XMM14_REG))
11190 (clobber (reg:TI XMM15_REG))
11191 (clobber (reg:DI SI_REG))
11192 (clobber (reg:DI DI_REG))]
11193 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11194 "* return ix86_output_call_insn (insn, operands[0]);"
11195 [(set_attr "type" "call")])
11197 (define_insn_and_split "*sibcall_vzeroupper"
11198 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11199 (match_operand 1 "" ""))
11200 (unspec [(match_operand 2 "const_int_operand" "")]
11201 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11202 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11204 "&& reload_completed"
11206 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11207 [(set_attr "type" "call")])
11209 (define_insn "*sibcall"
11210 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11211 (match_operand 1 "" ""))]
11212 "SIBLING_CALL_P (insn)"
11213 "* return ix86_output_call_insn (insn, operands[0]);"
11214 [(set_attr "type" "call")])
11216 (define_expand "call_pop"
11217 [(parallel [(call (match_operand:QI 0 "" "")
11218 (match_operand:SI 1 "" ""))
11219 (set (reg:SI SP_REG)
11220 (plus:SI (reg:SI SP_REG)
11221 (match_operand:SI 3 "" "")))])]
11224 ix86_expand_call (NULL, operands[0], operands[1],
11225 operands[2], operands[3], false);
11229 (define_insn_and_split "*call_pop_vzeroupper"
11231 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11232 (match_operand:SI 1 "" ""))
11233 (set (reg:SI SP_REG)
11234 (plus:SI (reg:SI SP_REG)
11235 (match_operand:SI 2 "immediate_operand" "i")))])
11236 (unspec [(match_operand 3 "const_int_operand" "")]
11237 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11238 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11240 "&& reload_completed"
11242 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11243 [(set_attr "type" "call")])
11245 (define_insn "*call_pop"
11246 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11247 (match_operand 1 "" ""))
11248 (set (reg:SI SP_REG)
11249 (plus:SI (reg:SI SP_REG)
11250 (match_operand:SI 2 "immediate_operand" "i")))]
11251 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11252 "* return ix86_output_call_insn (insn, operands[0]);"
11253 [(set_attr "type" "call")])
11255 (define_insn_and_split "*sibcall_pop_vzeroupper"
11257 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11258 (match_operand 1 "" ""))
11259 (set (reg:SI SP_REG)
11260 (plus:SI (reg:SI SP_REG)
11261 (match_operand:SI 2 "immediate_operand" "i")))])
11262 (unspec [(match_operand 3 "const_int_operand" "")]
11263 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11264 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11266 "&& reload_completed"
11268 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11269 [(set_attr "type" "call")])
11271 (define_insn "*sibcall_pop"
11272 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11273 (match_operand 1 "" ""))
11274 (set (reg:SI SP_REG)
11275 (plus:SI (reg:SI SP_REG)
11276 (match_operand:SI 2 "immediate_operand" "i")))]
11277 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11278 "* return ix86_output_call_insn (insn, operands[0]);"
11279 [(set_attr "type" "call")])
11281 ;; Call subroutine, returning value in operand 0
11283 (define_expand "call_value"
11284 [(set (match_operand 0 "" "")
11285 (call (match_operand:QI 1 "" "")
11286 (match_operand 2 "" "")))
11287 (use (match_operand 3 "" ""))]
11290 ix86_expand_call (operands[0], operands[1], operands[2],
11291 operands[3], NULL, false);
11295 (define_expand "sibcall_value"
11296 [(set (match_operand 0 "" "")
11297 (call (match_operand:QI 1 "" "")
11298 (match_operand 2 "" "")))
11299 (use (match_operand 3 "" ""))]
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], NULL, true);
11307 (define_insn_and_split "*call_value_vzeroupper"
11308 [(set (match_operand 0 "" "")
11309 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11310 (match_operand 2 "" "")))
11311 (unspec [(match_operand 3 "const_int_operand" "")]
11312 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11313 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11315 "&& reload_completed"
11317 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11318 [(set_attr "type" "callv")])
11320 (define_insn "*call_value"
11321 [(set (match_operand 0 "" "")
11322 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11323 (match_operand 2 "" "")))]
11324 "!SIBLING_CALL_P (insn)"
11325 "* return ix86_output_call_insn (insn, operands[1]);"
11326 [(set_attr "type" "callv")])
11328 (define_insn_and_split "*sibcall_value_vzeroupper"
11329 [(set (match_operand 0 "" "")
11330 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11331 (match_operand 2 "" "")))
11332 (unspec [(match_operand 3 "const_int_operand" "")]
11333 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11334 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11336 "&& reload_completed"
11338 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11339 [(set_attr "type" "callv")])
11341 (define_insn "*sibcall_value"
11342 [(set (match_operand 0 "" "")
11343 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11344 (match_operand 2 "" "")))]
11345 "SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[1]);"
11347 [(set_attr "type" "callv")])
11349 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11351 [(set (match_operand 0 "" "")
11352 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11353 (match_operand 2 "" "")))
11354 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11355 (clobber (reg:TI XMM6_REG))
11356 (clobber (reg:TI XMM7_REG))
11357 (clobber (reg:TI XMM8_REG))
11358 (clobber (reg:TI XMM9_REG))
11359 (clobber (reg:TI XMM10_REG))
11360 (clobber (reg:TI XMM11_REG))
11361 (clobber (reg:TI XMM12_REG))
11362 (clobber (reg:TI XMM13_REG))
11363 (clobber (reg:TI XMM14_REG))
11364 (clobber (reg:TI XMM15_REG))
11365 (clobber (reg:DI SI_REG))
11366 (clobber (reg:DI DI_REG))])
11367 (unspec [(match_operand 3 "const_int_operand" "")]
11368 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11369 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11371 "&& reload_completed"
11373 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11374 [(set_attr "type" "callv")])
11376 (define_insn "*call_value_rex64_ms_sysv"
11377 [(set (match_operand 0 "" "")
11378 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11379 (match_operand 2 "" "")))
11380 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11381 (clobber (reg:TI XMM6_REG))
11382 (clobber (reg:TI XMM7_REG))
11383 (clobber (reg:TI XMM8_REG))
11384 (clobber (reg:TI XMM9_REG))
11385 (clobber (reg:TI XMM10_REG))
11386 (clobber (reg:TI XMM11_REG))
11387 (clobber (reg:TI XMM12_REG))
11388 (clobber (reg:TI XMM13_REG))
11389 (clobber (reg:TI XMM14_REG))
11390 (clobber (reg:TI XMM15_REG))
11391 (clobber (reg:DI SI_REG))
11392 (clobber (reg:DI DI_REG))]
11393 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11394 "* return ix86_output_call_insn (insn, operands[1]);"
11395 [(set_attr "type" "callv")])
11397 (define_expand "call_value_pop"
11398 [(parallel [(set (match_operand 0 "" "")
11399 (call (match_operand:QI 1 "" "")
11400 (match_operand:SI 2 "" "")))
11401 (set (reg:SI SP_REG)
11402 (plus:SI (reg:SI SP_REG)
11403 (match_operand:SI 4 "" "")))])]
11406 ix86_expand_call (operands[0], operands[1], operands[2],
11407 operands[3], operands[4], false);
11411 (define_insn_and_split "*call_value_pop_vzeroupper"
11413 [(set (match_operand 0 "" "")
11414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11415 (match_operand 2 "" "")))
11416 (set (reg:SI SP_REG)
11417 (plus:SI (reg:SI SP_REG)
11418 (match_operand:SI 3 "immediate_operand" "i")))])
11419 (unspec [(match_operand 4 "const_int_operand" "")]
11420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11423 "&& reload_completed"
11425 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11426 [(set_attr "type" "callv")])
11428 (define_insn "*call_value_pop"
11429 [(set (match_operand 0 "" "")
11430 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11431 (match_operand 2 "" "")))
11432 (set (reg:SI SP_REG)
11433 (plus:SI (reg:SI SP_REG)
11434 (match_operand:SI 3 "immediate_operand" "i")))]
11435 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11436 "* return ix86_output_call_insn (insn, operands[1]);"
11437 [(set_attr "type" "callv")])
11439 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11441 [(set (match_operand 0 "" "")
11442 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11443 (match_operand 2 "" "")))
11444 (set (reg:SI SP_REG)
11445 (plus:SI (reg:SI SP_REG)
11446 (match_operand:SI 3 "immediate_operand" "i")))])
11447 (unspec [(match_operand 4 "const_int_operand" "")]
11448 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11449 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11451 "&& reload_completed"
11453 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11454 [(set_attr "type" "callv")])
11456 (define_insn "*sibcall_value_pop"
11457 [(set (match_operand 0 "" "")
11458 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11459 (match_operand 2 "" "")))
11460 (set (reg:SI SP_REG)
11461 (plus:SI (reg:SI SP_REG)
11462 (match_operand:SI 3 "immediate_operand" "i")))]
11463 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11464 "* return ix86_output_call_insn (insn, operands[1]);"
11465 [(set_attr "type" "callv")])
11467 ;; Call subroutine returning any type.
11469 (define_expand "untyped_call"
11470 [(parallel [(call (match_operand 0 "" "")
11472 (match_operand 1 "" "")
11473 (match_operand 2 "" "")])]
11478 /* In order to give reg-stack an easier job in validating two
11479 coprocessor registers as containing a possible return value,
11480 simply pretend the untyped call returns a complex long double
11483 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11484 and should have the default ABI. */
11486 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11487 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11488 operands[0], const0_rtx,
11489 GEN_INT ((TARGET_64BIT
11490 ? (ix86_abi == SYSV_ABI
11491 ? X86_64_SSE_REGPARM_MAX
11492 : X86_64_MS_SSE_REGPARM_MAX)
11493 : X86_32_SSE_REGPARM_MAX)
11497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11499 rtx set = XVECEXP (operands[2], 0, i);
11500 emit_move_insn (SET_DEST (set), SET_SRC (set));
11503 /* The optimizer does not know that the call sets the function value
11504 registers we stored in the result block. We avoid problems by
11505 claiming that all hard registers are used and clobbered at this
11507 emit_insn (gen_blockage ());
11512 ;; Prologue and epilogue instructions
11514 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11515 ;; all of memory. This blocks insns from being moved across this point.
11517 (define_insn "blockage"
11518 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11521 [(set_attr "length" "0")])
11523 ;; Do not schedule instructions accessing memory across this point.
11525 (define_expand "memory_blockage"
11526 [(set (match_dup 0)
11527 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11530 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11531 MEM_VOLATILE_P (operands[0]) = 1;
11534 (define_insn "*memory_blockage"
11535 [(set (match_operand:BLK 0 "" "")
11536 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11539 [(set_attr "length" "0")])
11541 ;; As USE insns aren't meaningful after reload, this is used instead
11542 ;; to prevent deleting instructions setting registers for PIC code
11543 (define_insn "prologue_use"
11544 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11547 [(set_attr "length" "0")])
11549 ;; Insn emitted into the body of a function to return from a function.
11550 ;; This is only done if the function's epilogue is known to be simple.
11551 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11553 (define_expand "return"
11555 "ix86_can_use_return_insn_p ()"
11557 if (crtl->args.pops_args)
11559 rtx popc = GEN_INT (crtl->args.pops_args);
11560 emit_jump_insn (gen_return_pop_internal (popc));
11565 (define_insn "return_internal"
11569 [(set_attr "length" "1")
11570 (set_attr "atom_unit" "jeu")
11571 (set_attr "length_immediate" "0")
11572 (set_attr "modrm" "0")])
11574 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11575 ;; instruction Athlon and K8 have.
11577 (define_insn "return_internal_long"
11579 (unspec [(const_int 0)] UNSPEC_REP)]
11582 [(set_attr "length" "2")
11583 (set_attr "atom_unit" "jeu")
11584 (set_attr "length_immediate" "0")
11585 (set_attr "prefix_rep" "1")
11586 (set_attr "modrm" "0")])
11588 (define_insn "return_pop_internal"
11590 (use (match_operand:SI 0 "const_int_operand" ""))]
11593 [(set_attr "length" "3")
11594 (set_attr "atom_unit" "jeu")
11595 (set_attr "length_immediate" "2")
11596 (set_attr "modrm" "0")])
11598 (define_insn "return_indirect_internal"
11600 (use (match_operand:SI 0 "register_operand" "r"))]
11603 [(set_attr "type" "ibr")
11604 (set_attr "length_immediate" "0")])
11610 [(set_attr "length" "1")
11611 (set_attr "length_immediate" "0")
11612 (set_attr "modrm" "0")])
11614 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11615 (define_insn "nops"
11616 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11620 int num = INTVAL (operands[0]);
11622 gcc_assert (num >= 1 && num <= 8);
11625 fputs ("\tnop\n", asm_out_file);
11629 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11630 (set_attr "length_immediate" "0")
11631 (set_attr "modrm" "0")])
11633 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11634 ;; branch prediction penalty for the third jump in a 16-byte
11638 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11641 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11642 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11644 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11645 The align insn is used to avoid 3 jump instructions in the row to improve
11646 branch prediction and the benefits hardly outweigh the cost of extra 8
11647 nops on the average inserted by full alignment pseudo operation. */
11651 [(set_attr "length" "16")])
11653 (define_expand "prologue"
11656 "ix86_expand_prologue (); DONE;")
11658 (define_insn "set_got"
11659 [(set (match_operand:SI 0 "register_operand" "=r")
11660 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11661 (clobber (reg:CC FLAGS_REG))]
11663 "* return output_set_got (operands[0], NULL_RTX);"
11664 [(set_attr "type" "multi")
11665 (set_attr "length" "12")])
11667 (define_insn "set_got_labelled"
11668 [(set (match_operand:SI 0 "register_operand" "=r")
11669 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11671 (clobber (reg:CC FLAGS_REG))]
11673 "* return output_set_got (operands[0], operands[1]);"
11674 [(set_attr "type" "multi")
11675 (set_attr "length" "12")])
11677 (define_insn "set_got_rex64"
11678 [(set (match_operand:DI 0 "register_operand" "=r")
11679 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11681 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11682 [(set_attr "type" "lea")
11683 (set_attr "length_address" "4")
11684 (set_attr "mode" "DI")])
11686 (define_insn "set_rip_rex64"
11687 [(set (match_operand:DI 0 "register_operand" "=r")
11688 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11690 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11691 [(set_attr "type" "lea")
11692 (set_attr "length_address" "4")
11693 (set_attr "mode" "DI")])
11695 (define_insn "set_got_offset_rex64"
11696 [(set (match_operand:DI 0 "register_operand" "=r")
11698 [(label_ref (match_operand 1 "" ""))]
11699 UNSPEC_SET_GOT_OFFSET))]
11701 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11702 [(set_attr "type" "imov")
11703 (set_attr "length_immediate" "0")
11704 (set_attr "length_address" "8")
11705 (set_attr "mode" "DI")])
11707 (define_expand "epilogue"
11710 "ix86_expand_epilogue (1); DONE;")
11712 (define_expand "sibcall_epilogue"
11715 "ix86_expand_epilogue (0); DONE;")
11717 (define_expand "eh_return"
11718 [(use (match_operand 0 "register_operand" ""))]
11721 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11723 /* Tricky bit: we write the address of the handler to which we will
11724 be returning into someone else's stack frame, one word below the
11725 stack address we wish to restore. */
11726 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11727 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11728 tmp = gen_rtx_MEM (Pmode, tmp);
11729 emit_move_insn (tmp, ra);
11731 emit_jump_insn (gen_eh_return_internal ());
11736 (define_insn_and_split "eh_return_internal"
11740 "epilogue_completed"
11742 "ix86_expand_epilogue (2); DONE;")
11744 (define_insn "leave"
11745 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11746 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11747 (clobber (mem:BLK (scratch)))]
11750 [(set_attr "type" "leave")])
11752 (define_insn "leave_rex64"
11753 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11754 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11755 (clobber (mem:BLK (scratch)))]
11758 [(set_attr "type" "leave")])
11760 ;; Handle -fsplit-stack.
11762 (define_expand "split_stack_prologue"
11766 ix86_expand_split_stack_prologue ();
11770 ;; In order to support the call/return predictor, we use a return
11771 ;; instruction which the middle-end doesn't see.
11772 (define_insn "split_stack_return"
11773 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11774 UNSPECV_SPLIT_STACK_RETURN)]
11777 if (operands[0] == const0_rtx)
11782 [(set_attr "atom_unit" "jeu")
11783 (set_attr "modrm" "0")
11784 (set (attr "length")
11785 (if_then_else (match_operand:SI 0 "const0_operand" "")
11788 (set (attr "length_immediate")
11789 (if_then_else (match_operand:SI 0 "const0_operand" "")
11793 ;; If there are operand 0 bytes available on the stack, jump to
11796 (define_expand "split_stack_space_check"
11797 [(set (pc) (if_then_else
11798 (ltu (minus (reg SP_REG)
11799 (match_operand 0 "register_operand" ""))
11800 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11801 (label_ref (match_operand 1 "" ""))
11805 rtx reg, size, limit;
11807 reg = gen_reg_rtx (Pmode);
11808 size = force_reg (Pmode, operands[0]);
11809 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11810 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11811 UNSPEC_STACK_CHECK);
11812 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11813 ix86_expand_branch (GEU, reg, limit, operands[1]);
11818 ;; Bit manipulation instructions.
11820 (define_expand "ffs<mode>2"
11821 [(set (match_dup 2) (const_int -1))
11822 (parallel [(set (reg:CCZ FLAGS_REG)
11824 (match_operand:SWI48 1 "nonimmediate_operand" "")
11826 (set (match_operand:SWI48 0 "register_operand" "")
11827 (ctz:SWI48 (match_dup 1)))])
11828 (set (match_dup 0) (if_then_else:SWI48
11829 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11832 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11833 (clobber (reg:CC FLAGS_REG))])]
11836 if (<MODE>mode == SImode && !TARGET_CMOVE)
11838 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11841 operands[2] = gen_reg_rtx (<MODE>mode);
11844 (define_insn_and_split "ffssi2_no_cmove"
11845 [(set (match_operand:SI 0 "register_operand" "=r")
11846 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11847 (clobber (match_scratch:SI 2 "=&q"))
11848 (clobber (reg:CC FLAGS_REG))]
11851 "&& reload_completed"
11852 [(parallel [(set (reg:CCZ FLAGS_REG)
11853 (compare:CCZ (match_dup 1) (const_int 0)))
11854 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11855 (set (strict_low_part (match_dup 3))
11856 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11857 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11858 (clobber (reg:CC FLAGS_REG))])
11859 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11860 (clobber (reg:CC FLAGS_REG))])
11861 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11862 (clobber (reg:CC FLAGS_REG))])]
11864 operands[3] = gen_lowpart (QImode, operands[2]);
11865 ix86_expand_clear (operands[2]);
11868 (define_insn "*ffs<mode>_1"
11869 [(set (reg:CCZ FLAGS_REG)
11870 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11872 (set (match_operand:SWI48 0 "register_operand" "=r")
11873 (ctz:SWI48 (match_dup 1)))]
11875 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11876 [(set_attr "type" "alu1")
11877 (set_attr "prefix_0f" "1")
11878 (set_attr "mode" "<MODE>")])
11880 (define_insn "ctz<mode>2"
11881 [(set (match_operand:SWI248 0 "register_operand" "=r")
11882 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11883 (clobber (reg:CC FLAGS_REG))]
11887 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11889 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11891 [(set_attr "type" "alu1")
11892 (set_attr "prefix_0f" "1")
11893 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11894 (set_attr "mode" "<MODE>")])
11896 (define_expand "clz<mode>2"
11898 [(set (match_operand:SWI248 0 "register_operand" "")
11901 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11902 (clobber (reg:CC FLAGS_REG))])
11904 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11905 (clobber (reg:CC FLAGS_REG))])]
11910 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11913 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11916 (define_insn "clz<mode>2_abm"
11917 [(set (match_operand:SWI248 0 "register_operand" "=r")
11918 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11919 (clobber (reg:CC FLAGS_REG))]
11920 "TARGET_ABM || TARGET_BMI"
11921 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11922 [(set_attr "prefix_rep" "1")
11923 (set_attr "type" "bitmanip")
11924 (set_attr "mode" "<MODE>")])
11926 ;; BMI instructions.
11927 (define_insn "*bmi_andn_<mode>"
11928 [(set (match_operand:SWI48 0 "register_operand" "=r")
11931 (match_operand:SWI48 1 "register_operand" "r"))
11932 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11933 (clobber (reg:CC FLAGS_REG))]
11935 "andn\t{%2, %1, %0|%0, %1, %2}"
11936 [(set_attr "type" "bitmanip")
11937 (set_attr "mode" "<MODE>")])
11939 (define_insn "bmi_bextr_<mode>"
11940 [(set (match_operand:SWI48 0 "register_operand" "=r")
11941 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11942 (match_operand:SWI48 2 "register_operand" "r")]
11944 (clobber (reg:CC FLAGS_REG))]
11946 "bextr\t{%2, %1, %0|%0, %1, %2}"
11947 [(set_attr "type" "bitmanip")
11948 (set_attr "mode" "<MODE>")])
11950 (define_insn "*bmi_blsi_<mode>"
11951 [(set (match_operand:SWI48 0 "register_operand" "=r")
11954 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11956 (clobber (reg:CC FLAGS_REG))]
11958 "blsi\t{%1, %0|%0, %1}"
11959 [(set_attr "type" "bitmanip")
11960 (set_attr "mode" "<MODE>")])
11962 (define_insn "*bmi_blsmsk_<mode>"
11963 [(set (match_operand:SWI48 0 "register_operand" "=r")
11966 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11969 (clobber (reg:CC FLAGS_REG))]
11971 "blsmsk\t{%1, %0|%0, %1}"
11972 [(set_attr "type" "bitmanip")
11973 (set_attr "mode" "<MODE>")])
11975 (define_insn "*bmi_blsr_<mode>"
11976 [(set (match_operand:SWI48 0 "register_operand" "=r")
11979 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11982 (clobber (reg:CC FLAGS_REG))]
11984 "blsr\t{%1, %0|%0, %1}"
11985 [(set_attr "type" "bitmanip")
11986 (set_attr "mode" "<MODE>")])
11988 ;; TBM instructions.
11989 (define_insn "tbm_bextri_<mode>"
11990 [(set (match_operand:SWI48 0 "register_operand" "=r")
11991 (zero_extract:SWI48
11992 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11993 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11994 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11995 (clobber (reg:CC FLAGS_REG))]
11998 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11999 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12001 [(set_attr "type" "bitmanip")
12002 (set_attr "mode" "<MODE>")])
12004 (define_insn "*tbm_blcfill_<mode>"
12005 [(set (match_operand:SWI48 0 "register_operand" "=r")
12008 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12011 (clobber (reg:CC FLAGS_REG))]
12013 "blcfill\t{%1, %0|%0, %1}"
12014 [(set_attr "type" "bitmanip")
12015 (set_attr "mode" "<MODE>")])
12017 (define_insn "*tbm_blci_<mode>"
12018 [(set (match_operand:SWI48 0 "register_operand" "=r")
12022 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12025 (clobber (reg:CC FLAGS_REG))]
12027 "blci\t{%1, %0|%0, %1}"
12028 [(set_attr "type" "bitmanip")
12029 (set_attr "mode" "<MODE>")])
12031 (define_insn "*tbm_blcic_<mode>"
12032 [(set (match_operand:SWI48 0 "register_operand" "=r")
12035 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12039 (clobber (reg:CC FLAGS_REG))]
12041 "blcic\t{%1, %0|%0, %1}"
12042 [(set_attr "type" "bitmanip")
12043 (set_attr "mode" "<MODE>")])
12045 (define_insn "*tbm_blcmsk_<mode>"
12046 [(set (match_operand:SWI48 0 "register_operand" "=r")
12049 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12052 (clobber (reg:CC FLAGS_REG))]
12054 "blcmsk\t{%1, %0|%0, %1}"
12055 [(set_attr "type" "bitmanip")
12056 (set_attr "mode" "<MODE>")])
12058 (define_insn "*tbm_blcs_<mode>"
12059 [(set (match_operand:SWI48 0 "register_operand" "=r")
12062 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12065 (clobber (reg:CC FLAGS_REG))]
12067 "blcs\t{%1, %0|%0, %1}"
12068 [(set_attr "type" "bitmanip")
12069 (set_attr "mode" "<MODE>")])
12071 (define_insn "*tbm_blsfill_<mode>"
12072 [(set (match_operand:SWI48 0 "register_operand" "=r")
12075 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12078 (clobber (reg:CC FLAGS_REG))]
12080 "blsfill\t{%1, %0|%0, %1}"
12081 [(set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12084 (define_insn "*tbm_blsic_<mode>"
12085 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12092 (clobber (reg:CC FLAGS_REG))]
12094 "blsic\t{%1, %0|%0, %1}"
12095 [(set_attr "type" "bitmanip")
12096 (set_attr "mode" "<MODE>")])
12098 (define_insn "*tbm_t1mskc_<mode>"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12106 (clobber (reg:CC FLAGS_REG))]
12108 "t1mskc\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "*tbm_tzmsk_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12120 (clobber (reg:CC FLAGS_REG))]
12122 "tzmsk\t{%1, %0|%0, %1}"
12123 [(set_attr "type" "bitmanip")
12124 (set_attr "mode" "<MODE>")])
12126 (define_insn "bsr_rex64"
12127 [(set (match_operand:DI 0 "register_operand" "=r")
12128 (minus:DI (const_int 63)
12129 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12130 (clobber (reg:CC FLAGS_REG))]
12132 "bsr{q}\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "alu1")
12134 (set_attr "prefix_0f" "1")
12135 (set_attr "mode" "DI")])
12138 [(set (match_operand:SI 0 "register_operand" "=r")
12139 (minus:SI (const_int 31)
12140 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12141 (clobber (reg:CC FLAGS_REG))]
12143 "bsr{l}\t{%1, %0|%0, %1}"
12144 [(set_attr "type" "alu1")
12145 (set_attr "prefix_0f" "1")
12146 (set_attr "mode" "SI")])
12148 (define_insn "*bsrhi"
12149 [(set (match_operand:HI 0 "register_operand" "=r")
12150 (minus:HI (const_int 15)
12151 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12152 (clobber (reg:CC FLAGS_REG))]
12154 "bsr{w}\t{%1, %0|%0, %1}"
12155 [(set_attr "type" "alu1")
12156 (set_attr "prefix_0f" "1")
12157 (set_attr "mode" "HI")])
12159 (define_insn "popcount<mode>2"
12160 [(set (match_operand:SWI248 0 "register_operand" "=r")
12162 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12163 (clobber (reg:CC FLAGS_REG))]
12167 return "popcnt\t{%1, %0|%0, %1}";
12169 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12172 [(set_attr "prefix_rep" "1")
12173 (set_attr "type" "bitmanip")
12174 (set_attr "mode" "<MODE>")])
12176 (define_insn "*popcount<mode>2_cmp"
12177 [(set (reg FLAGS_REG)
12180 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12182 (set (match_operand:SWI248 0 "register_operand" "=r")
12183 (popcount:SWI248 (match_dup 1)))]
12184 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12187 return "popcnt\t{%1, %0|%0, %1}";
12189 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12192 [(set_attr "prefix_rep" "1")
12193 (set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12196 (define_insn "*popcountsi2_cmp_zext"
12197 [(set (reg FLAGS_REG)
12199 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12201 (set (match_operand:DI 0 "register_operand" "=r")
12202 (zero_extend:DI(popcount:SI (match_dup 1))))]
12203 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12206 return "popcnt\t{%1, %0|%0, %1}";
12208 return "popcnt{l}\t{%1, %0|%0, %1}";
12211 [(set_attr "prefix_rep" "1")
12212 (set_attr "type" "bitmanip")
12213 (set_attr "mode" "SI")])
12215 (define_expand "bswap<mode>2"
12216 [(set (match_operand:SWI48 0 "register_operand" "")
12217 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12220 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12222 rtx x = operands[0];
12224 emit_move_insn (x, operands[1]);
12225 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12226 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12227 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12232 (define_insn "*bswap<mode>2_movbe"
12233 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12234 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12239 movbe\t{%1, %0|%0, %1}
12240 movbe\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip,imov,imov")
12242 (set_attr "modrm" "0,1,1")
12243 (set_attr "prefix_0f" "*,1,1")
12244 (set_attr "prefix_extra" "*,1,1")
12245 (set_attr "mode" "<MODE>")])
12247 (define_insn "*bswap<mode>2_1"
12248 [(set (match_operand:SWI48 0 "register_operand" "=r")
12249 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12252 [(set_attr "type" "bitmanip")
12253 (set_attr "modrm" "0")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*bswaphi_lowpart_1"
12257 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12258 (bswap:HI (match_dup 0)))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12262 xchg{b}\t{%h0, %b0|%b0, %h0}
12263 rol{w}\t{$8, %0|%0, 8}"
12264 [(set_attr "length" "2,4")
12265 (set_attr "mode" "QI,HI")])
12267 (define_insn "bswaphi_lowpart"
12268 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12269 (bswap:HI (match_dup 0)))
12270 (clobber (reg:CC FLAGS_REG))]
12272 "rol{w}\t{$8, %0|%0, 8}"
12273 [(set_attr "length" "4")
12274 (set_attr "mode" "HI")])
12276 (define_expand "paritydi2"
12277 [(set (match_operand:DI 0 "register_operand" "")
12278 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12281 rtx scratch = gen_reg_rtx (QImode);
12284 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12285 NULL_RTX, operands[1]));
12287 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12288 gen_rtx_REG (CCmode, FLAGS_REG),
12290 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12293 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12296 rtx tmp = gen_reg_rtx (SImode);
12298 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12299 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12304 (define_expand "paritysi2"
12305 [(set (match_operand:SI 0 "register_operand" "")
12306 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12309 rtx scratch = gen_reg_rtx (QImode);
12312 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12314 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12315 gen_rtx_REG (CCmode, FLAGS_REG),
12317 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12319 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12323 (define_insn_and_split "paritydi2_cmp"
12324 [(set (reg:CC FLAGS_REG)
12325 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12327 (clobber (match_scratch:DI 0 "=r"))
12328 (clobber (match_scratch:SI 1 "=&r"))
12329 (clobber (match_scratch:HI 2 "=Q"))]
12332 "&& reload_completed"
12334 [(set (match_dup 1)
12335 (xor:SI (match_dup 1) (match_dup 4)))
12336 (clobber (reg:CC FLAGS_REG))])
12338 [(set (reg:CC FLAGS_REG)
12339 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12340 (clobber (match_dup 1))
12341 (clobber (match_dup 2))])]
12343 operands[4] = gen_lowpart (SImode, operands[3]);
12347 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12348 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12351 operands[1] = gen_highpart (SImode, operands[3]);
12354 (define_insn_and_split "paritysi2_cmp"
12355 [(set (reg:CC FLAGS_REG)
12356 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12358 (clobber (match_scratch:SI 0 "=r"))
12359 (clobber (match_scratch:HI 1 "=&Q"))]
12362 "&& reload_completed"
12364 [(set (match_dup 1)
12365 (xor:HI (match_dup 1) (match_dup 3)))
12366 (clobber (reg:CC FLAGS_REG))])
12368 [(set (reg:CC FLAGS_REG)
12369 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12370 (clobber (match_dup 1))])]
12372 operands[3] = gen_lowpart (HImode, operands[2]);
12374 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12375 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12378 (define_insn "*parityhi2_cmp"
12379 [(set (reg:CC FLAGS_REG)
12380 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12382 (clobber (match_scratch:HI 0 "=Q"))]
12384 "xor{b}\t{%h0, %b0|%b0, %h0}"
12385 [(set_attr "length" "2")
12386 (set_attr "mode" "HI")])
12388 ;; Thread-local storage patterns for ELF.
12390 ;; Note that these code sequences must appear exactly as shown
12391 ;; in order to allow linker relaxation.
12393 (define_insn "*tls_global_dynamic_32_gnu"
12394 [(set (match_operand:SI 0 "register_operand" "=a")
12396 [(match_operand:SI 1 "register_operand" "b")
12397 (match_operand:SI 2 "tls_symbolic_operand" "")
12398 (match_operand:SI 3 "constant_call_address_operand" "z")]
12400 (clobber (match_scratch:SI 4 "=d"))
12401 (clobber (match_scratch:SI 5 "=c"))
12402 (clobber (reg:CC FLAGS_REG))]
12403 "!TARGET_64BIT && TARGET_GNU_TLS"
12406 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12407 if (TARGET_SUN_TLS)
12408 #ifdef HAVE_AS_IX86_TLSGDPLT
12409 return "call\t%a2@tlsgdplt";
12411 return "call\t%p3@plt";
12413 return "call\t%P3";
12415 [(set_attr "type" "multi")
12416 (set_attr "length" "12")])
12418 (define_expand "tls_global_dynamic_32"
12420 [(set (match_operand:SI 0 "register_operand" "")
12421 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12422 (match_operand:SI 1 "tls_symbolic_operand" "")
12423 (match_operand:SI 3 "constant_call_address_operand" "")]
12425 (clobber (match_scratch:SI 4 ""))
12426 (clobber (match_scratch:SI 5 ""))
12427 (clobber (reg:CC FLAGS_REG))])])
12429 (define_insn "*tls_global_dynamic_64"
12430 [(set (match_operand:DI 0 "register_operand" "=a")
12432 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12433 (match_operand:DI 3 "" "")))
12434 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12438 fputs (ASM_BYTE "0x66\n", asm_out_file);
12440 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12441 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12442 fputs ("\trex64\n", asm_out_file);
12443 if (TARGET_SUN_TLS)
12444 return "call\t%p2@plt";
12445 return "call\t%P2";
12447 [(set_attr "type" "multi")
12448 (set_attr "length" "16")])
12450 (define_expand "tls_global_dynamic_64"
12452 [(set (match_operand:DI 0 "register_operand" "")
12454 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12456 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12459 (define_insn "*tls_local_dynamic_base_32_gnu"
12460 [(set (match_operand:SI 0 "register_operand" "=a")
12462 [(match_operand:SI 1 "register_operand" "b")
12463 (match_operand:SI 2 "constant_call_address_operand" "z")]
12464 UNSPEC_TLS_LD_BASE))
12465 (clobber (match_scratch:SI 3 "=d"))
12466 (clobber (match_scratch:SI 4 "=c"))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "!TARGET_64BIT && TARGET_GNU_TLS"
12471 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12472 if (TARGET_SUN_TLS)
12473 #ifdef HAVE_AS_IX86_TLSLDMPLT
12474 return "call\t%&@tlsldmplt";
12476 return "call\t%p2@plt";
12478 return "call\t%P2";
12480 [(set_attr "type" "multi")
12481 (set_attr "length" "11")])
12483 (define_expand "tls_local_dynamic_base_32"
12485 [(set (match_operand:SI 0 "register_operand" "")
12487 [(match_operand:SI 1 "register_operand" "")
12488 (match_operand:SI 2 "constant_call_address_operand" "")]
12489 UNSPEC_TLS_LD_BASE))
12490 (clobber (match_scratch:SI 3 ""))
12491 (clobber (match_scratch:SI 4 ""))
12492 (clobber (reg:CC FLAGS_REG))])])
12494 (define_insn "*tls_local_dynamic_base_64"
12495 [(set (match_operand:DI 0 "register_operand" "=a")
12497 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12498 (match_operand:DI 2 "" "")))
12499 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12503 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12504 if (TARGET_SUN_TLS)
12505 return "call\t%p1@plt";
12506 return "call\t%P1";
12508 [(set_attr "type" "multi")
12509 (set_attr "length" "12")])
12511 (define_expand "tls_local_dynamic_base_64"
12513 [(set (match_operand:DI 0 "register_operand" "")
12515 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12517 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12519 ;; Local dynamic of a single variable is a lose. Show combine how
12520 ;; to convert that back to global dynamic.
12522 (define_insn_and_split "*tls_local_dynamic_32_once"
12523 [(set (match_operand:SI 0 "register_operand" "=a")
12525 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12526 (match_operand:SI 2 "constant_call_address_operand" "z")]
12527 UNSPEC_TLS_LD_BASE)
12528 (const:SI (unspec:SI
12529 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12531 (clobber (match_scratch:SI 4 "=d"))
12532 (clobber (match_scratch:SI 5 "=c"))
12533 (clobber (reg:CC FLAGS_REG))]
12538 [(set (match_dup 0)
12539 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12541 (clobber (match_dup 4))
12542 (clobber (match_dup 5))
12543 (clobber (reg:CC FLAGS_REG))])])
12545 ;; Segment register for the thread base ptr load
12546 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12548 ;; Load and add the thread base pointer from %<tp_seg>:0.
12549 (define_insn "*load_tp_<mode>"
12550 [(set (match_operand:P 0 "register_operand" "=r")
12551 (unspec:P [(const_int 0)] UNSPEC_TP))]
12553 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12554 [(set_attr "type" "imov")
12555 (set_attr "modrm" "0")
12556 (set_attr "length" "7")
12557 (set_attr "memory" "load")
12558 (set_attr "imm_disp" "false")])
12560 (define_insn "*add_tp_<mode>"
12561 [(set (match_operand:P 0 "register_operand" "=r")
12562 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12563 (match_operand:P 1 "register_operand" "0")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12567 [(set_attr "type" "alu")
12568 (set_attr "modrm" "0")
12569 (set_attr "length" "7")
12570 (set_attr "memory" "load")
12571 (set_attr "imm_disp" "false")])
12573 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12574 ;; %rax as destination of the initial executable code sequence.
12575 (define_insn "tls_initial_exec_64_sun"
12576 [(set (match_operand:DI 0 "register_operand" "=a")
12578 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12579 UNSPEC_TLS_IE_SUN))
12580 (clobber (reg:CC FLAGS_REG))]
12581 "TARGET_64BIT && TARGET_SUN_TLS"
12584 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12585 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12587 [(set_attr "type" "multi")])
12589 ;; GNU2 TLS patterns can be split.
12591 (define_expand "tls_dynamic_gnu2_32"
12592 [(set (match_dup 3)
12593 (plus:SI (match_operand:SI 2 "register_operand" "")
12595 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12598 [(set (match_operand:SI 0 "register_operand" "")
12599 (unspec:SI [(match_dup 1) (match_dup 3)
12600 (match_dup 2) (reg:SI SP_REG)]
12602 (clobber (reg:CC FLAGS_REG))])]
12603 "!TARGET_64BIT && TARGET_GNU2_TLS"
12605 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12606 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12609 (define_insn "*tls_dynamic_lea_32"
12610 [(set (match_operand:SI 0 "register_operand" "=r")
12611 (plus:SI (match_operand:SI 1 "register_operand" "b")
12613 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12614 UNSPEC_TLSDESC))))]
12615 "!TARGET_64BIT && TARGET_GNU2_TLS"
12616 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12617 [(set_attr "type" "lea")
12618 (set_attr "mode" "SI")
12619 (set_attr "length" "6")
12620 (set_attr "length_address" "4")])
12622 (define_insn "*tls_dynamic_call_32"
12623 [(set (match_operand:SI 0 "register_operand" "=a")
12624 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12625 (match_operand:SI 2 "register_operand" "0")
12626 ;; we have to make sure %ebx still points to the GOT
12627 (match_operand:SI 3 "register_operand" "b")
12630 (clobber (reg:CC FLAGS_REG))]
12631 "!TARGET_64BIT && TARGET_GNU2_TLS"
12632 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12633 [(set_attr "type" "call")
12634 (set_attr "length" "2")
12635 (set_attr "length_address" "0")])
12637 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12638 [(set (match_operand:SI 0 "register_operand" "=&a")
12640 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12641 (match_operand:SI 4 "" "")
12642 (match_operand:SI 2 "register_operand" "b")
12645 (const:SI (unspec:SI
12646 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12648 (clobber (reg:CC FLAGS_REG))]
12649 "!TARGET_64BIT && TARGET_GNU2_TLS"
12652 [(set (match_dup 0) (match_dup 5))]
12654 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12655 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12658 (define_expand "tls_dynamic_gnu2_64"
12659 [(set (match_dup 2)
12660 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12663 [(set (match_operand:DI 0 "register_operand" "")
12664 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12666 (clobber (reg:CC FLAGS_REG))])]
12667 "TARGET_64BIT && TARGET_GNU2_TLS"
12669 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12670 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12673 (define_insn "*tls_dynamic_lea_64"
12674 [(set (match_operand:DI 0 "register_operand" "=r")
12675 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12677 "TARGET_64BIT && TARGET_GNU2_TLS"
12678 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12679 [(set_attr "type" "lea")
12680 (set_attr "mode" "DI")
12681 (set_attr "length" "7")
12682 (set_attr "length_address" "4")])
12684 (define_insn "*tls_dynamic_call_64"
12685 [(set (match_operand:DI 0 "register_operand" "=a")
12686 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12687 (match_operand:DI 2 "register_operand" "0")
12690 (clobber (reg:CC FLAGS_REG))]
12691 "TARGET_64BIT && TARGET_GNU2_TLS"
12692 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12693 [(set_attr "type" "call")
12694 (set_attr "length" "2")
12695 (set_attr "length_address" "0")])
12697 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12698 [(set (match_operand:DI 0 "register_operand" "=&a")
12700 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12701 (match_operand:DI 3 "" "")
12704 (const:DI (unspec:DI
12705 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12707 (clobber (reg:CC FLAGS_REG))]
12708 "TARGET_64BIT && TARGET_GNU2_TLS"
12711 [(set (match_dup 0) (match_dup 4))]
12713 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12714 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12717 ;; These patterns match the binary 387 instructions for addM3, subM3,
12718 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12719 ;; SFmode. The first is the normal insn, the second the same insn but
12720 ;; with one operand a conversion, and the third the same insn but with
12721 ;; the other operand a conversion. The conversion may be SFmode or
12722 ;; SImode if the target mode DFmode, but only SImode if the target mode
12725 ;; Gcc is slightly more smart about handling normal two address instructions
12726 ;; so use special patterns for add and mull.
12728 (define_insn "*fop_<mode>_comm_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (if_then_else (eq_attr "alternative" "1,2")
12739 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12740 (const_string "ssemul")
12741 (const_string "sseadd"))
12742 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12743 (const_string "fmul")
12744 (const_string "fop"))))
12745 (set_attr "isa" "base,noavx,avx")
12746 (set_attr "prefix" "orig,orig,vex")
12747 (set_attr "mode" "<MODE>")])
12749 (define_insn "*fop_<mode>_comm_sse"
12750 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12751 (match_operator:MODEF 3 "binary_fp_operator"
12752 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12753 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12755 && COMMUTATIVE_ARITH_P (operands[3])
12756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12757 "* return output_387_binary_op (insn, operands);"
12758 [(set (attr "type")
12759 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12760 (const_string "ssemul")
12761 (const_string "sseadd")))
12762 (set_attr "isa" "noavx,avx")
12763 (set_attr "prefix" "orig,vex")
12764 (set_attr "mode" "<MODE>")])
12766 (define_insn "*fop_<mode>_comm_i387"
12767 [(set (match_operand:MODEF 0 "register_operand" "=f")
12768 (match_operator:MODEF 3 "binary_fp_operator"
12769 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12770 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12771 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12772 && COMMUTATIVE_ARITH_P (operands[3])
12773 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12777 (const_string "fmul")
12778 (const_string "fop")))
12779 (set_attr "mode" "<MODE>")])
12781 (define_insn "*fop_<mode>_1_mixed"
12782 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12783 (match_operator:MODEF 3 "binary_fp_operator"
12784 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12785 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12786 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12787 && !COMMUTATIVE_ARITH_P (operands[3])
12788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12789 "* return output_387_binary_op (insn, operands);"
12790 [(set (attr "type")
12791 (cond [(and (eq_attr "alternative" "2,3")
12792 (match_operand:MODEF 3 "mult_operator" ""))
12793 (const_string "ssemul")
12794 (and (eq_attr "alternative" "2,3")
12795 (match_operand:MODEF 3 "div_operator" ""))
12796 (const_string "ssediv")
12797 (eq_attr "alternative" "2,3")
12798 (const_string "sseadd")
12799 (match_operand:MODEF 3 "mult_operator" "")
12800 (const_string "fmul")
12801 (match_operand:MODEF 3 "div_operator" "")
12802 (const_string "fdiv")
12804 (const_string "fop")))
12805 (set_attr "isa" "base,base,noavx,avx")
12806 (set_attr "prefix" "orig,orig,orig,vex")
12807 (set_attr "mode" "<MODE>")])
12809 (define_insn "*rcpsf2_sse"
12810 [(set (match_operand:SF 0 "register_operand" "=x")
12811 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12814 "%vrcpss\t{%1, %d0|%d0, %1}"
12815 [(set_attr "type" "sse")
12816 (set_attr "atom_sse_attr" "rcp")
12817 (set_attr "prefix" "maybe_vex")
12818 (set_attr "mode" "SF")])
12820 (define_insn "*fop_<mode>_1_sse"
12821 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12822 (match_operator:MODEF 3 "binary_fp_operator"
12823 [(match_operand:MODEF 1 "register_operand" "0,x")
12824 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12825 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12826 && !COMMUTATIVE_ARITH_P (operands[3])"
12827 "* return output_387_binary_op (insn, operands);"
12828 [(set (attr "type")
12829 (cond [(match_operand:MODEF 3 "mult_operator" "")
12830 (const_string "ssemul")
12831 (match_operand:MODEF 3 "div_operator" "")
12832 (const_string "ssediv")
12834 (const_string "sseadd")))
12835 (set_attr "isa" "noavx,avx")
12836 (set_attr "prefix" "orig,vex")
12837 (set_attr "mode" "<MODE>")])
12839 ;; This pattern is not fully shadowed by the pattern above.
12840 (define_insn "*fop_<mode>_1_i387"
12841 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12842 (match_operator:MODEF 3 "binary_fp_operator"
12843 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12844 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12845 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12846 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12847 && !COMMUTATIVE_ARITH_P (operands[3])
12848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12849 "* return output_387_binary_op (insn, operands);"
12850 [(set (attr "type")
12851 (cond [(match_operand:MODEF 3 "mult_operator" "")
12852 (const_string "fmul")
12853 (match_operand:MODEF 3 "div_operator" "")
12854 (const_string "fdiv")
12856 (const_string "fop")))
12857 (set_attr "mode" "<MODE>")])
12859 ;; ??? Add SSE splitters for these!
12860 (define_insn "*fop_<MODEF:mode>_2_i387"
12861 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12862 (match_operator:MODEF 3 "binary_fp_operator"
12864 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12865 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12866 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12867 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12868 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12869 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12870 [(set (attr "type")
12871 (cond [(match_operand:MODEF 3 "mult_operator" "")
12872 (const_string "fmul")
12873 (match_operand:MODEF 3 "div_operator" "")
12874 (const_string "fdiv")
12876 (const_string "fop")))
12877 (set_attr "fp_int_src" "true")
12878 (set_attr "mode" "<X87MODEI12:MODE>")])
12880 (define_insn "*fop_<MODEF:mode>_3_i387"
12881 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12882 (match_operator:MODEF 3 "binary_fp_operator"
12883 [(match_operand:MODEF 1 "register_operand" "0,0")
12885 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12886 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12887 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12888 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12889 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12890 [(set (attr "type")
12891 (cond [(match_operand:MODEF 3 "mult_operator" "")
12892 (const_string "fmul")
12893 (match_operand:MODEF 3 "div_operator" "")
12894 (const_string "fdiv")
12896 (const_string "fop")))
12897 (set_attr "fp_int_src" "true")
12898 (set_attr "mode" "<MODE>")])
12900 (define_insn "*fop_df_4_i387"
12901 [(set (match_operand:DF 0 "register_operand" "=f,f")
12902 (match_operator:DF 3 "binary_fp_operator"
12904 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12905 (match_operand:DF 2 "register_operand" "0,f")]))]
12906 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12907 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12909 "* return output_387_binary_op (insn, operands);"
12910 [(set (attr "type")
12911 (cond [(match_operand:DF 3 "mult_operator" "")
12912 (const_string "fmul")
12913 (match_operand:DF 3 "div_operator" "")
12914 (const_string "fdiv")
12916 (const_string "fop")))
12917 (set_attr "mode" "SF")])
12919 (define_insn "*fop_df_5_i387"
12920 [(set (match_operand:DF 0 "register_operand" "=f,f")
12921 (match_operator:DF 3 "binary_fp_operator"
12922 [(match_operand:DF 1 "register_operand" "0,f")
12924 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12925 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12926 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12927 "* return output_387_binary_op (insn, operands);"
12928 [(set (attr "type")
12929 (cond [(match_operand:DF 3 "mult_operator" "")
12930 (const_string "fmul")
12931 (match_operand:DF 3 "div_operator" "")
12932 (const_string "fdiv")
12934 (const_string "fop")))
12935 (set_attr "mode" "SF")])
12937 (define_insn "*fop_df_6_i387"
12938 [(set (match_operand:DF 0 "register_operand" "=f,f")
12939 (match_operator:DF 3 "binary_fp_operator"
12941 (match_operand:SF 1 "register_operand" "0,f"))
12943 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12944 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12945 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (cond [(match_operand:DF 3 "mult_operator" "")
12949 (const_string "fmul")
12950 (match_operand:DF 3 "div_operator" "")
12951 (const_string "fdiv")
12953 (const_string "fop")))
12954 (set_attr "mode" "SF")])
12956 (define_insn "*fop_xf_comm_i387"
12957 [(set (match_operand:XF 0 "register_operand" "=f")
12958 (match_operator:XF 3 "binary_fp_operator"
12959 [(match_operand:XF 1 "register_operand" "%0")
12960 (match_operand:XF 2 "register_operand" "f")]))]
12962 && COMMUTATIVE_ARITH_P (operands[3])"
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (if_then_else (match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (const_string "fop")))
12968 (set_attr "mode" "XF")])
12970 (define_insn "*fop_xf_1_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12973 [(match_operand:XF 1 "register_operand" "0,f")
12974 (match_operand:XF 2 "register_operand" "f,0")]))]
12976 && !COMMUTATIVE_ARITH_P (operands[3])"
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator" "")
12982 (const_string "fdiv")
12984 (const_string "fop")))
12985 (set_attr "mode" "XF")])
12987 (define_insn "*fop_xf_2_i387"
12988 [(set (match_operand:XF 0 "register_operand" "=f,f")
12989 (match_operator:XF 3 "binary_fp_operator"
12991 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12992 (match_operand:XF 2 "register_operand" "0,0")]))]
12993 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12994 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (cond [(match_operand:XF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (match_operand:XF 3 "div_operator" "")
12999 (const_string "fdiv")
13001 (const_string "fop")))
13002 (set_attr "fp_int_src" "true")
13003 (set_attr "mode" "<MODE>")])
13005 (define_insn "*fop_xf_3_i387"
13006 [(set (match_operand:XF 0 "register_operand" "=f,f")
13007 (match_operator:XF 3 "binary_fp_operator"
13008 [(match_operand:XF 1 "register_operand" "0,0")
13010 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13011 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13012 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13013 [(set (attr "type")
13014 (cond [(match_operand:XF 3 "mult_operator" "")
13015 (const_string "fmul")
13016 (match_operand:XF 3 "div_operator" "")
13017 (const_string "fdiv")
13019 (const_string "fop")))
13020 (set_attr "fp_int_src" "true")
13021 (set_attr "mode" "<MODE>")])
13023 (define_insn "*fop_xf_4_i387"
13024 [(set (match_operand:XF 0 "register_operand" "=f,f")
13025 (match_operator:XF 3 "binary_fp_operator"
13027 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13028 (match_operand:XF 2 "register_operand" "0,f")]))]
13030 "* return output_387_binary_op (insn, operands);"
13031 [(set (attr "type")
13032 (cond [(match_operand:XF 3 "mult_operator" "")
13033 (const_string "fmul")
13034 (match_operand:XF 3 "div_operator" "")
13035 (const_string "fdiv")
13037 (const_string "fop")))
13038 (set_attr "mode" "<MODE>")])
13040 (define_insn "*fop_xf_5_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f,f")
13042 (match_operator:XF 3 "binary_fp_operator"
13043 [(match_operand:XF 1 "register_operand" "0,f")
13045 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13047 "* return output_387_binary_op (insn, operands);"
13048 [(set (attr "type")
13049 (cond [(match_operand:XF 3 "mult_operator" "")
13050 (const_string "fmul")
13051 (match_operand:XF 3 "div_operator" "")
13052 (const_string "fdiv")
13054 (const_string "fop")))
13055 (set_attr "mode" "<MODE>")])
13057 (define_insn "*fop_xf_6_i387"
13058 [(set (match_operand:XF 0 "register_operand" "=f,f")
13059 (match_operator:XF 3 "binary_fp_operator"
13061 (match_operand:MODEF 1 "register_operand" "0,f"))
13063 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13065 "* return output_387_binary_op (insn, operands);"
13066 [(set (attr "type")
13067 (cond [(match_operand:XF 3 "mult_operator" "")
13068 (const_string "fmul")
13069 (match_operand:XF 3 "div_operator" "")
13070 (const_string "fdiv")
13072 (const_string "fop")))
13073 (set_attr "mode" "<MODE>")])
13076 [(set (match_operand 0 "register_operand" "")
13077 (match_operator 3 "binary_fp_operator"
13078 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13079 (match_operand 2 "register_operand" "")]))]
13081 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13082 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13085 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13086 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13087 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13088 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13089 GET_MODE (operands[3]),
13092 ix86_free_from_memory (GET_MODE (operands[1]));
13097 [(set (match_operand 0 "register_operand" "")
13098 (match_operator 3 "binary_fp_operator"
13099 [(match_operand 1 "register_operand" "")
13100 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13102 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13103 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13106 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13107 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13108 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13109 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13110 GET_MODE (operands[3]),
13113 ix86_free_from_memory (GET_MODE (operands[2]));
13117 ;; FPU special functions.
13119 ;; This pattern implements a no-op XFmode truncation for
13120 ;; all fancy i386 XFmode math functions.
13122 (define_insn "truncxf<mode>2_i387_noop_unspec"
13123 [(set (match_operand:MODEF 0 "register_operand" "=f")
13124 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13125 UNSPEC_TRUNC_NOOP))]
13126 "TARGET_USE_FANCY_MATH_387"
13127 "* return output_387_reg_move (insn, operands);"
13128 [(set_attr "type" "fmov")
13129 (set_attr "mode" "<MODE>")])
13131 (define_insn "sqrtxf2"
13132 [(set (match_operand:XF 0 "register_operand" "=f")
13133 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13134 "TARGET_USE_FANCY_MATH_387"
13136 [(set_attr "type" "fpspc")
13137 (set_attr "mode" "XF")
13138 (set_attr "athlon_decode" "direct")
13139 (set_attr "amdfam10_decode" "direct")
13140 (set_attr "bdver1_decode" "direct")])
13142 (define_insn "sqrt_extend<mode>xf2_i387"
13143 [(set (match_operand:XF 0 "register_operand" "=f")
13146 (match_operand:MODEF 1 "register_operand" "0"))))]
13147 "TARGET_USE_FANCY_MATH_387"
13149 [(set_attr "type" "fpspc")
13150 (set_attr "mode" "XF")
13151 (set_attr "athlon_decode" "direct")
13152 (set_attr "amdfam10_decode" "direct")
13153 (set_attr "bdver1_decode" "direct")])
13155 (define_insn "*rsqrtsf2_sse"
13156 [(set (match_operand:SF 0 "register_operand" "=x")
13157 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13160 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13161 [(set_attr "type" "sse")
13162 (set_attr "atom_sse_attr" "rcp")
13163 (set_attr "prefix" "maybe_vex")
13164 (set_attr "mode" "SF")])
13166 (define_expand "rsqrtsf2"
13167 [(set (match_operand:SF 0 "register_operand" "")
13168 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13172 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13176 (define_insn "*sqrt<mode>2_sse"
13177 [(set (match_operand:MODEF 0 "register_operand" "=x")
13179 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13180 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13181 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13182 [(set_attr "type" "sse")
13183 (set_attr "atom_sse_attr" "sqrt")
13184 (set_attr "prefix" "maybe_vex")
13185 (set_attr "mode" "<MODE>")
13186 (set_attr "athlon_decode" "*")
13187 (set_attr "amdfam10_decode" "*")
13188 (set_attr "bdver1_decode" "*")])
13190 (define_expand "sqrt<mode>2"
13191 [(set (match_operand:MODEF 0 "register_operand" "")
13193 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13194 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13195 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13197 if (<MODE>mode == SFmode
13198 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13199 && flag_finite_math_only && !flag_trapping_math
13200 && flag_unsafe_math_optimizations)
13202 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13206 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13208 rtx op0 = gen_reg_rtx (XFmode);
13209 rtx op1 = force_reg (<MODE>mode, operands[1]);
13211 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13212 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13217 (define_insn "fpremxf4_i387"
13218 [(set (match_operand:XF 0 "register_operand" "=f")
13219 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13220 (match_operand:XF 3 "register_operand" "1")]
13222 (set (match_operand:XF 1 "register_operand" "=u")
13223 (unspec:XF [(match_dup 2) (match_dup 3)]
13225 (set (reg:CCFP FPSR_REG)
13226 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13228 "TARGET_USE_FANCY_MATH_387"
13230 [(set_attr "type" "fpspc")
13231 (set_attr "mode" "XF")])
13233 (define_expand "fmodxf3"
13234 [(use (match_operand:XF 0 "register_operand" ""))
13235 (use (match_operand:XF 1 "general_operand" ""))
13236 (use (match_operand:XF 2 "general_operand" ""))]
13237 "TARGET_USE_FANCY_MATH_387"
13239 rtx label = gen_label_rtx ();
13241 rtx op1 = gen_reg_rtx (XFmode);
13242 rtx op2 = gen_reg_rtx (XFmode);
13244 emit_move_insn (op2, operands[2]);
13245 emit_move_insn (op1, operands[1]);
13247 emit_label (label);
13248 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13249 ix86_emit_fp_unordered_jump (label);
13250 LABEL_NUSES (label) = 1;
13252 emit_move_insn (operands[0], op1);
13256 (define_expand "fmod<mode>3"
13257 [(use (match_operand:MODEF 0 "register_operand" ""))
13258 (use (match_operand:MODEF 1 "general_operand" ""))
13259 (use (match_operand:MODEF 2 "general_operand" ""))]
13260 "TARGET_USE_FANCY_MATH_387"
13262 rtx (*gen_truncxf) (rtx, rtx);
13264 rtx label = gen_label_rtx ();
13266 rtx op1 = gen_reg_rtx (XFmode);
13267 rtx op2 = gen_reg_rtx (XFmode);
13269 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13270 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13272 emit_label (label);
13273 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13274 ix86_emit_fp_unordered_jump (label);
13275 LABEL_NUSES (label) = 1;
13277 /* Truncate the result properly for strict SSE math. */
13278 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13279 && !TARGET_MIX_SSE_I387)
13280 gen_truncxf = gen_truncxf<mode>2;
13282 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13284 emit_insn (gen_truncxf (operands[0], op1));
13288 (define_insn "fprem1xf4_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f")
13290 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13291 (match_operand:XF 3 "register_operand" "1")]
13293 (set (match_operand:XF 1 "register_operand" "=u")
13294 (unspec:XF [(match_dup 2) (match_dup 3)]
13296 (set (reg:CCFP FPSR_REG)
13297 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13299 "TARGET_USE_FANCY_MATH_387"
13301 [(set_attr "type" "fpspc")
13302 (set_attr "mode" "XF")])
13304 (define_expand "remainderxf3"
13305 [(use (match_operand:XF 0 "register_operand" ""))
13306 (use (match_operand:XF 1 "general_operand" ""))
13307 (use (match_operand:XF 2 "general_operand" ""))]
13308 "TARGET_USE_FANCY_MATH_387"
13310 rtx label = gen_label_rtx ();
13312 rtx op1 = gen_reg_rtx (XFmode);
13313 rtx op2 = gen_reg_rtx (XFmode);
13315 emit_move_insn (op2, operands[2]);
13316 emit_move_insn (op1, operands[1]);
13318 emit_label (label);
13319 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13320 ix86_emit_fp_unordered_jump (label);
13321 LABEL_NUSES (label) = 1;
13323 emit_move_insn (operands[0], op1);
13327 (define_expand "remainder<mode>3"
13328 [(use (match_operand:MODEF 0 "register_operand" ""))
13329 (use (match_operand:MODEF 1 "general_operand" ""))
13330 (use (match_operand:MODEF 2 "general_operand" ""))]
13331 "TARGET_USE_FANCY_MATH_387"
13333 rtx (*gen_truncxf) (rtx, rtx);
13335 rtx label = gen_label_rtx ();
13337 rtx op1 = gen_reg_rtx (XFmode);
13338 rtx op2 = gen_reg_rtx (XFmode);
13340 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13343 emit_label (label);
13345 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13346 ix86_emit_fp_unordered_jump (label);
13347 LABEL_NUSES (label) = 1;
13349 /* Truncate the result properly for strict SSE math. */
13350 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13351 && !TARGET_MIX_SSE_I387)
13352 gen_truncxf = gen_truncxf<mode>2;
13354 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13356 emit_insn (gen_truncxf (operands[0], op1));
13360 (define_insn "*sinxf2_i387"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13369 (define_insn "*sin_extend<mode>xf2_i387"
13370 [(set (match_operand:XF 0 "register_operand" "=f")
13371 (unspec:XF [(float_extend:XF
13372 (match_operand:MODEF 1 "register_operand" "0"))]
13374 "TARGET_USE_FANCY_MATH_387
13375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13376 || TARGET_MIX_SSE_I387)
13377 && flag_unsafe_math_optimizations"
13379 [(set_attr "type" "fpspc")
13380 (set_attr "mode" "XF")])
13382 (define_insn "*cosxf2_i387"
13383 [(set (match_operand:XF 0 "register_operand" "=f")
13384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13385 "TARGET_USE_FANCY_MATH_387
13386 && flag_unsafe_math_optimizations"
13388 [(set_attr "type" "fpspc")
13389 (set_attr "mode" "XF")])
13391 (define_insn "*cos_extend<mode>xf2_i387"
13392 [(set (match_operand:XF 0 "register_operand" "=f")
13393 (unspec:XF [(float_extend:XF
13394 (match_operand:MODEF 1 "register_operand" "0"))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")])
13404 ;; When sincos pattern is defined, sin and cos builtin functions will be
13405 ;; expanded to sincos pattern with one of its outputs left unused.
13406 ;; CSE pass will figure out if two sincos patterns can be combined,
13407 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13408 ;; depending on the unused output.
13410 (define_insn "sincosxf3"
13411 [(set (match_operand:XF 0 "register_operand" "=f")
13412 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13413 UNSPEC_SINCOS_COS))
13414 (set (match_operand:XF 1 "register_operand" "=u")
13415 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13416 "TARGET_USE_FANCY_MATH_387
13417 && flag_unsafe_math_optimizations"
13419 [(set_attr "type" "fpspc")
13420 (set_attr "mode" "XF")])
13423 [(set (match_operand:XF 0 "register_operand" "")
13424 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13425 UNSPEC_SINCOS_COS))
13426 (set (match_operand:XF 1 "register_operand" "")
13427 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13428 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13429 && can_create_pseudo_p ()"
13430 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13433 [(set (match_operand:XF 0 "register_operand" "")
13434 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13435 UNSPEC_SINCOS_COS))
13436 (set (match_operand:XF 1 "register_operand" "")
13437 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13438 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13439 && can_create_pseudo_p ()"
13440 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13442 (define_insn "sincos_extend<mode>xf3_i387"
13443 [(set (match_operand:XF 0 "register_operand" "=f")
13444 (unspec:XF [(float_extend:XF
13445 (match_operand:MODEF 2 "register_operand" "0"))]
13446 UNSPEC_SINCOS_COS))
13447 (set (match_operand:XF 1 "register_operand" "=u")
13448 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13449 "TARGET_USE_FANCY_MATH_387
13450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13451 || TARGET_MIX_SSE_I387)
13452 && flag_unsafe_math_optimizations"
13454 [(set_attr "type" "fpspc")
13455 (set_attr "mode" "XF")])
13458 [(set (match_operand:XF 0 "register_operand" "")
13459 (unspec:XF [(float_extend:XF
13460 (match_operand:MODEF 2 "register_operand" ""))]
13461 UNSPEC_SINCOS_COS))
13462 (set (match_operand:XF 1 "register_operand" "")
13463 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13464 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13465 && can_create_pseudo_p ()"
13466 [(set (match_dup 1)
13467 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13470 [(set (match_operand:XF 0 "register_operand" "")
13471 (unspec:XF [(float_extend:XF
13472 (match_operand:MODEF 2 "register_operand" ""))]
13473 UNSPEC_SINCOS_COS))
13474 (set (match_operand:XF 1 "register_operand" "")
13475 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13476 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13477 && can_create_pseudo_p ()"
13478 [(set (match_dup 0)
13479 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13481 (define_expand "sincos<mode>3"
13482 [(use (match_operand:MODEF 0 "register_operand" ""))
13483 (use (match_operand:MODEF 1 "register_operand" ""))
13484 (use (match_operand:MODEF 2 "register_operand" ""))]
13485 "TARGET_USE_FANCY_MATH_387
13486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13487 || TARGET_MIX_SSE_I387)
13488 && flag_unsafe_math_optimizations"
13490 rtx op0 = gen_reg_rtx (XFmode);
13491 rtx op1 = gen_reg_rtx (XFmode);
13493 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13494 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13499 (define_insn "fptanxf4_i387"
13500 [(set (match_operand:XF 0 "register_operand" "=f")
13501 (match_operand:XF 3 "const_double_operand" "F"))
13502 (set (match_operand:XF 1 "register_operand" "=u")
13503 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13505 "TARGET_USE_FANCY_MATH_387
13506 && flag_unsafe_math_optimizations
13507 && standard_80387_constant_p (operands[3]) == 2"
13509 [(set_attr "type" "fpspc")
13510 (set_attr "mode" "XF")])
13512 (define_insn "fptan_extend<mode>xf4_i387"
13513 [(set (match_operand:MODEF 0 "register_operand" "=f")
13514 (match_operand:MODEF 3 "const_double_operand" "F"))
13515 (set (match_operand:XF 1 "register_operand" "=u")
13516 (unspec:XF [(float_extend:XF
13517 (match_operand:MODEF 2 "register_operand" "0"))]
13519 "TARGET_USE_FANCY_MATH_387
13520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13521 || TARGET_MIX_SSE_I387)
13522 && flag_unsafe_math_optimizations
13523 && standard_80387_constant_p (operands[3]) == 2"
13525 [(set_attr "type" "fpspc")
13526 (set_attr "mode" "XF")])
13528 (define_expand "tanxf2"
13529 [(use (match_operand:XF 0 "register_operand" ""))
13530 (use (match_operand:XF 1 "register_operand" ""))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && flag_unsafe_math_optimizations"
13534 rtx one = gen_reg_rtx (XFmode);
13535 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13537 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13541 (define_expand "tan<mode>2"
13542 [(use (match_operand:MODEF 0 "register_operand" ""))
13543 (use (match_operand:MODEF 1 "register_operand" ""))]
13544 "TARGET_USE_FANCY_MATH_387
13545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13546 || TARGET_MIX_SSE_I387)
13547 && flag_unsafe_math_optimizations"
13549 rtx op0 = gen_reg_rtx (XFmode);
13551 rtx one = gen_reg_rtx (<MODE>mode);
13552 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13554 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13555 operands[1], op2));
13556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13560 (define_insn "*fpatanxf3_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f")
13562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13563 (match_operand:XF 2 "register_operand" "u")]
13565 (clobber (match_scratch:XF 3 "=2"))]
13566 "TARGET_USE_FANCY_MATH_387
13567 && flag_unsafe_math_optimizations"
13569 [(set_attr "type" "fpspc")
13570 (set_attr "mode" "XF")])
13572 (define_insn "fpatan_extend<mode>xf3_i387"
13573 [(set (match_operand:XF 0 "register_operand" "=f")
13574 (unspec:XF [(float_extend:XF
13575 (match_operand:MODEF 1 "register_operand" "0"))
13577 (match_operand:MODEF 2 "register_operand" "u"))]
13579 (clobber (match_scratch:XF 3 "=2"))]
13580 "TARGET_USE_FANCY_MATH_387
13581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13582 || TARGET_MIX_SSE_I387)
13583 && flag_unsafe_math_optimizations"
13585 [(set_attr "type" "fpspc")
13586 (set_attr "mode" "XF")])
13588 (define_expand "atan2xf3"
13589 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13590 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13591 (match_operand:XF 1 "register_operand" "")]
13593 (clobber (match_scratch:XF 3 ""))])]
13594 "TARGET_USE_FANCY_MATH_387
13595 && flag_unsafe_math_optimizations")
13597 (define_expand "atan2<mode>3"
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))
13600 (use (match_operand:MODEF 2 "register_operand" ""))]
13601 "TARGET_USE_FANCY_MATH_387
13602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13603 || TARGET_MIX_SSE_I387)
13604 && flag_unsafe_math_optimizations"
13606 rtx op0 = gen_reg_rtx (XFmode);
13608 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13609 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13613 (define_expand "atanxf2"
13614 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13615 (unspec:XF [(match_dup 2)
13616 (match_operand:XF 1 "register_operand" "")]
13618 (clobber (match_scratch:XF 3 ""))])]
13619 "TARGET_USE_FANCY_MATH_387
13620 && flag_unsafe_math_optimizations"
13622 operands[2] = gen_reg_rtx (XFmode);
13623 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13626 (define_expand "atan<mode>2"
13627 [(use (match_operand:MODEF 0 "register_operand" ""))
13628 (use (match_operand:MODEF 1 "register_operand" ""))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13631 || TARGET_MIX_SSE_I387)
13632 && flag_unsafe_math_optimizations"
13634 rtx op0 = gen_reg_rtx (XFmode);
13636 rtx op2 = gen_reg_rtx (<MODE>mode);
13637 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13639 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13640 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13644 (define_expand "asinxf2"
13645 [(set (match_dup 2)
13646 (mult:XF (match_operand:XF 1 "register_operand" "")
13648 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13649 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13650 (parallel [(set (match_operand:XF 0 "register_operand" "")
13651 (unspec:XF [(match_dup 5) (match_dup 1)]
13653 (clobber (match_scratch:XF 6 ""))])]
13654 "TARGET_USE_FANCY_MATH_387
13655 && flag_unsafe_math_optimizations"
13659 if (optimize_insn_for_size_p ())
13662 for (i = 2; i < 6; i++)
13663 operands[i] = gen_reg_rtx (XFmode);
13665 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13668 (define_expand "asin<mode>2"
13669 [(use (match_operand:MODEF 0 "register_operand" ""))
13670 (use (match_operand:MODEF 1 "general_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13679 if (optimize_insn_for_size_p ())
13682 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13683 emit_insn (gen_asinxf2 (op0, op1));
13684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13688 (define_expand "acosxf2"
13689 [(set (match_dup 2)
13690 (mult:XF (match_operand:XF 1 "register_operand" "")
13692 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13693 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13694 (parallel [(set (match_operand:XF 0 "register_operand" "")
13695 (unspec:XF [(match_dup 1) (match_dup 5)]
13697 (clobber (match_scratch:XF 6 ""))])]
13698 "TARGET_USE_FANCY_MATH_387
13699 && flag_unsafe_math_optimizations"
13703 if (optimize_insn_for_size_p ())
13706 for (i = 2; i < 6; i++)
13707 operands[i] = gen_reg_rtx (XFmode);
13709 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13712 (define_expand "acos<mode>2"
13713 [(use (match_operand:MODEF 0 "register_operand" ""))
13714 (use (match_operand:MODEF 1 "general_operand" ""))]
13715 "TARGET_USE_FANCY_MATH_387
13716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13717 || TARGET_MIX_SSE_I387)
13718 && flag_unsafe_math_optimizations"
13720 rtx op0 = gen_reg_rtx (XFmode);
13721 rtx op1 = gen_reg_rtx (XFmode);
13723 if (optimize_insn_for_size_p ())
13726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13727 emit_insn (gen_acosxf2 (op0, op1));
13728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13732 (define_insn "fyl2xxf3_i387"
13733 [(set (match_operand:XF 0 "register_operand" "=f")
13734 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13735 (match_operand:XF 2 "register_operand" "u")]
13737 (clobber (match_scratch:XF 3 "=2"))]
13738 "TARGET_USE_FANCY_MATH_387
13739 && flag_unsafe_math_optimizations"
13741 [(set_attr "type" "fpspc")
13742 (set_attr "mode" "XF")])
13744 (define_insn "fyl2x_extend<mode>xf3_i387"
13745 [(set (match_operand:XF 0 "register_operand" "=f")
13746 (unspec:XF [(float_extend:XF
13747 (match_operand:MODEF 1 "register_operand" "0"))
13748 (match_operand:XF 2 "register_operand" "u")]
13750 (clobber (match_scratch:XF 3 "=2"))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753 || TARGET_MIX_SSE_I387)
13754 && flag_unsafe_math_optimizations"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13759 (define_expand "logxf2"
13760 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13761 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13762 (match_dup 2)] UNSPEC_FYL2X))
13763 (clobber (match_scratch:XF 3 ""))])]
13764 "TARGET_USE_FANCY_MATH_387
13765 && flag_unsafe_math_optimizations"
13767 operands[2] = gen_reg_rtx (XFmode);
13768 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13771 (define_expand "log<mode>2"
13772 [(use (match_operand:MODEF 0 "register_operand" ""))
13773 (use (match_operand:MODEF 1 "register_operand" ""))]
13774 "TARGET_USE_FANCY_MATH_387
13775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13776 || TARGET_MIX_SSE_I387)
13777 && flag_unsafe_math_optimizations"
13779 rtx op0 = gen_reg_rtx (XFmode);
13781 rtx op2 = gen_reg_rtx (XFmode);
13782 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13784 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13789 (define_expand "log10xf2"
13790 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13791 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13792 (match_dup 2)] UNSPEC_FYL2X))
13793 (clobber (match_scratch:XF 3 ""))])]
13794 "TARGET_USE_FANCY_MATH_387
13795 && flag_unsafe_math_optimizations"
13797 operands[2] = gen_reg_rtx (XFmode);
13798 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13801 (define_expand "log10<mode>2"
13802 [(use (match_operand:MODEF 0 "register_operand" ""))
13803 (use (match_operand:MODEF 1 "register_operand" ""))]
13804 "TARGET_USE_FANCY_MATH_387
13805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13806 || TARGET_MIX_SSE_I387)
13807 && flag_unsafe_math_optimizations"
13809 rtx op0 = gen_reg_rtx (XFmode);
13811 rtx op2 = gen_reg_rtx (XFmode);
13812 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13814 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13819 (define_expand "log2xf2"
13820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13822 (match_dup 2)] UNSPEC_FYL2X))
13823 (clobber (match_scratch:XF 3 ""))])]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13827 operands[2] = gen_reg_rtx (XFmode);
13828 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13831 (define_expand "log2<mode>2"
13832 [(use (match_operand:MODEF 0 "register_operand" ""))
13833 (use (match_operand:MODEF 1 "register_operand" ""))]
13834 "TARGET_USE_FANCY_MATH_387
13835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13836 || TARGET_MIX_SSE_I387)
13837 && flag_unsafe_math_optimizations"
13839 rtx op0 = gen_reg_rtx (XFmode);
13841 rtx op2 = gen_reg_rtx (XFmode);
13842 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13844 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13849 (define_insn "fyl2xp1xf3_i387"
13850 [(set (match_operand:XF 0 "register_operand" "=f")
13851 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13852 (match_operand:XF 2 "register_operand" "u")]
13854 (clobber (match_scratch:XF 3 "=2"))]
13855 "TARGET_USE_FANCY_MATH_387
13856 && flag_unsafe_math_optimizations"
13858 [(set_attr "type" "fpspc")
13859 (set_attr "mode" "XF")])
13861 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13862 [(set (match_operand:XF 0 "register_operand" "=f")
13863 (unspec:XF [(float_extend:XF
13864 (match_operand:MODEF 1 "register_operand" "0"))
13865 (match_operand:XF 2 "register_operand" "u")]
13867 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
13874 (set_attr "mode" "XF")])
13876 (define_expand "log1pxf2"
13877 [(use (match_operand:XF 0 "register_operand" ""))
13878 (use (match_operand:XF 1 "register_operand" ""))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13882 if (optimize_insn_for_size_p ())
13885 ix86_emit_i387_log1p (operands[0], operands[1]);
13889 (define_expand "log1p<mode>2"
13890 [(use (match_operand:MODEF 0 "register_operand" ""))
13891 (use (match_operand:MODEF 1 "register_operand" ""))]
13892 "TARGET_USE_FANCY_MATH_387
13893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13894 || TARGET_MIX_SSE_I387)
13895 && flag_unsafe_math_optimizations"
13899 if (optimize_insn_for_size_p ())
13902 op0 = gen_reg_rtx (XFmode);
13904 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13906 ix86_emit_i387_log1p (op0, operands[1]);
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13911 (define_insn "fxtractxf3_i387"
13912 [(set (match_operand:XF 0 "register_operand" "=f")
13913 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13914 UNSPEC_XTRACT_FRACT))
13915 (set (match_operand:XF 1 "register_operand" "=u")
13916 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && flag_unsafe_math_optimizations"
13920 [(set_attr "type" "fpspc")
13921 (set_attr "mode" "XF")])
13923 (define_insn "fxtract_extend<mode>xf3_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (unspec:XF [(float_extend:XF
13926 (match_operand:MODEF 2 "register_operand" "0"))]
13927 UNSPEC_XTRACT_FRACT))
13928 (set (match_operand:XF 1 "register_operand" "=u")
13929 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13930 "TARGET_USE_FANCY_MATH_387
13931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13932 || TARGET_MIX_SSE_I387)
13933 && flag_unsafe_math_optimizations"
13935 [(set_attr "type" "fpspc")
13936 (set_attr "mode" "XF")])
13938 (define_expand "logbxf2"
13939 [(parallel [(set (match_dup 2)
13940 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13941 UNSPEC_XTRACT_FRACT))
13942 (set (match_operand:XF 0 "register_operand" "")
13943 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13946 "operands[2] = gen_reg_rtx (XFmode);")
13948 (define_expand "logb<mode>2"
13949 [(use (match_operand:MODEF 0 "register_operand" ""))
13950 (use (match_operand:MODEF 1 "register_operand" ""))]
13951 "TARGET_USE_FANCY_MATH_387
13952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953 || TARGET_MIX_SSE_I387)
13954 && flag_unsafe_math_optimizations"
13956 rtx op0 = gen_reg_rtx (XFmode);
13957 rtx op1 = gen_reg_rtx (XFmode);
13959 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13960 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13964 (define_expand "ilogbxf2"
13965 [(use (match_operand:SI 0 "register_operand" ""))
13966 (use (match_operand:XF 1 "register_operand" ""))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && flag_unsafe_math_optimizations"
13972 if (optimize_insn_for_size_p ())
13975 op0 = gen_reg_rtx (XFmode);
13976 op1 = gen_reg_rtx (XFmode);
13978 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13979 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13983 (define_expand "ilogb<mode>2"
13984 [(use (match_operand:SI 0 "register_operand" ""))
13985 (use (match_operand:MODEF 1 "register_operand" ""))]
13986 "TARGET_USE_FANCY_MATH_387
13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988 || TARGET_MIX_SSE_I387)
13989 && flag_unsafe_math_optimizations"
13993 if (optimize_insn_for_size_p ())
13996 op0 = gen_reg_rtx (XFmode);
13997 op1 = gen_reg_rtx (XFmode);
13999 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14000 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14004 (define_insn "*f2xm1xf2_i387"
14005 [(set (match_operand:XF 0 "register_operand" "=f")
14006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14008 "TARGET_USE_FANCY_MATH_387
14009 && flag_unsafe_math_optimizations"
14011 [(set_attr "type" "fpspc")
14012 (set_attr "mode" "XF")])
14014 (define_insn "*fscalexf4_i387"
14015 [(set (match_operand:XF 0 "register_operand" "=f")
14016 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14017 (match_operand:XF 3 "register_operand" "1")]
14018 UNSPEC_FSCALE_FRACT))
14019 (set (match_operand:XF 1 "register_operand" "=u")
14020 (unspec:XF [(match_dup 2) (match_dup 3)]
14021 UNSPEC_FSCALE_EXP))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && flag_unsafe_math_optimizations"
14025 [(set_attr "type" "fpspc")
14026 (set_attr "mode" "XF")])
14028 (define_expand "expNcorexf3"
14029 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14030 (match_operand:XF 2 "register_operand" "")))
14031 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14032 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14033 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14034 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14035 (parallel [(set (match_operand:XF 0 "register_operand" "")
14036 (unspec:XF [(match_dup 8) (match_dup 4)]
14037 UNSPEC_FSCALE_FRACT))
14039 (unspec:XF [(match_dup 8) (match_dup 4)]
14040 UNSPEC_FSCALE_EXP))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14046 if (optimize_insn_for_size_p ())
14049 for (i = 3; i < 10; i++)
14050 operands[i] = gen_reg_rtx (XFmode);
14052 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14055 (define_expand "expxf2"
14056 [(use (match_operand:XF 0 "register_operand" ""))
14057 (use (match_operand:XF 1 "register_operand" ""))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations"
14063 if (optimize_insn_for_size_p ())
14066 op2 = gen_reg_rtx (XFmode);
14067 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14069 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14073 (define_expand "exp<mode>2"
14074 [(use (match_operand:MODEF 0 "register_operand" ""))
14075 (use (match_operand:MODEF 1 "general_operand" ""))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14083 if (optimize_insn_for_size_p ())
14086 op0 = gen_reg_rtx (XFmode);
14087 op1 = gen_reg_rtx (XFmode);
14089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090 emit_insn (gen_expxf2 (op0, op1));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14095 (define_expand "exp10xf2"
14096 [(use (match_operand:XF 0 "register_operand" ""))
14097 (use (match_operand:XF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && flag_unsafe_math_optimizations"
14103 if (optimize_insn_for_size_p ())
14106 op2 = gen_reg_rtx (XFmode);
14107 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14109 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14113 (define_expand "exp10<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "general_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14123 if (optimize_insn_for_size_p ())
14126 op0 = gen_reg_rtx (XFmode);
14127 op1 = gen_reg_rtx (XFmode);
14129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130 emit_insn (gen_exp10xf2 (op0, op1));
14131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135 (define_expand "exp2xf2"
14136 [(use (match_operand:XF 0 "register_operand" ""))
14137 (use (match_operand:XF 1 "register_operand" ""))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && flag_unsafe_math_optimizations"
14143 if (optimize_insn_for_size_p ())
14146 op2 = gen_reg_rtx (XFmode);
14147 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14149 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14153 (define_expand "exp2<mode>2"
14154 [(use (match_operand:MODEF 0 "register_operand" ""))
14155 (use (match_operand:MODEF 1 "general_operand" ""))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14163 if (optimize_insn_for_size_p ())
14166 op0 = gen_reg_rtx (XFmode);
14167 op1 = gen_reg_rtx (XFmode);
14169 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14170 emit_insn (gen_exp2xf2 (op0, op1));
14171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14175 (define_expand "expm1xf2"
14176 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14178 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14179 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14180 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14181 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14182 (parallel [(set (match_dup 7)
14183 (unspec:XF [(match_dup 6) (match_dup 4)]
14184 UNSPEC_FSCALE_FRACT))
14186 (unspec:XF [(match_dup 6) (match_dup 4)]
14187 UNSPEC_FSCALE_EXP))])
14188 (parallel [(set (match_dup 10)
14189 (unspec:XF [(match_dup 9) (match_dup 8)]
14190 UNSPEC_FSCALE_FRACT))
14191 (set (match_dup 11)
14192 (unspec:XF [(match_dup 9) (match_dup 8)]
14193 UNSPEC_FSCALE_EXP))])
14194 (set (match_dup 12) (minus:XF (match_dup 10)
14195 (float_extend:XF (match_dup 13))))
14196 (set (match_operand:XF 0 "register_operand" "")
14197 (plus:XF (match_dup 12) (match_dup 7)))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14203 if (optimize_insn_for_size_p ())
14206 for (i = 2; i < 13; i++)
14207 operands[i] = gen_reg_rtx (XFmode);
14210 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14212 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14215 (define_expand "expm1<mode>2"
14216 [(use (match_operand:MODEF 0 "register_operand" ""))
14217 (use (match_operand:MODEF 1 "general_operand" ""))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220 || TARGET_MIX_SSE_I387)
14221 && flag_unsafe_math_optimizations"
14225 if (optimize_insn_for_size_p ())
14228 op0 = gen_reg_rtx (XFmode);
14229 op1 = gen_reg_rtx (XFmode);
14231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14232 emit_insn (gen_expm1xf2 (op0, op1));
14233 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14237 (define_expand "ldexpxf3"
14238 [(set (match_dup 3)
14239 (float:XF (match_operand:SI 2 "register_operand" "")))
14240 (parallel [(set (match_operand:XF 0 " register_operand" "")
14241 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14243 UNSPEC_FSCALE_FRACT))
14245 (unspec:XF [(match_dup 1) (match_dup 3)]
14246 UNSPEC_FSCALE_EXP))])]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14250 if (optimize_insn_for_size_p ())
14253 operands[3] = gen_reg_rtx (XFmode);
14254 operands[4] = gen_reg_rtx (XFmode);
14257 (define_expand "ldexp<mode>3"
14258 [(use (match_operand:MODEF 0 "register_operand" ""))
14259 (use (match_operand:MODEF 1 "general_operand" ""))
14260 (use (match_operand:SI 2 "register_operand" ""))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations"
14268 if (optimize_insn_for_size_p ())
14271 op0 = gen_reg_rtx (XFmode);
14272 op1 = gen_reg_rtx (XFmode);
14274 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14275 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14276 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14280 (define_expand "scalbxf3"
14281 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14282 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14283 (match_operand:XF 2 "register_operand" "")]
14284 UNSPEC_FSCALE_FRACT))
14286 (unspec:XF [(match_dup 1) (match_dup 2)]
14287 UNSPEC_FSCALE_EXP))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14291 if (optimize_insn_for_size_p ())
14294 operands[3] = gen_reg_rtx (XFmode);
14297 (define_expand "scalb<mode>3"
14298 [(use (match_operand:MODEF 0 "register_operand" ""))
14299 (use (match_operand:MODEF 1 "general_operand" ""))
14300 (use (match_operand:MODEF 2 "general_operand" ""))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14303 || TARGET_MIX_SSE_I387)
14304 && flag_unsafe_math_optimizations"
14308 if (optimize_insn_for_size_p ())
14311 op0 = gen_reg_rtx (XFmode);
14312 op1 = gen_reg_rtx (XFmode);
14313 op2 = gen_reg_rtx (XFmode);
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14317 emit_insn (gen_scalbxf3 (op0, op1, op2));
14318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14322 (define_expand "significandxf2"
14323 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14324 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14325 UNSPEC_XTRACT_FRACT))
14327 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14328 "TARGET_USE_FANCY_MATH_387
14329 && flag_unsafe_math_optimizations"
14330 "operands[2] = gen_reg_rtx (XFmode);")
14332 (define_expand "significand<mode>2"
14333 [(use (match_operand:MODEF 0 "register_operand" ""))
14334 (use (match_operand:MODEF 1 "register_operand" ""))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations"
14340 rtx op0 = gen_reg_rtx (XFmode);
14341 rtx op1 = gen_reg_rtx (XFmode);
14343 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14344 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14349 (define_insn "sse4_1_round<mode>2"
14350 [(set (match_operand:MODEF 0 "register_operand" "=x")
14351 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14352 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14355 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14356 [(set_attr "type" "ssecvt")
14357 (set_attr "prefix_extra" "1")
14358 (set_attr "prefix" "maybe_vex")
14359 (set_attr "mode" "<MODE>")])
14361 (define_insn "rintxf2"
14362 [(set (match_operand:XF 0 "register_operand" "=f")
14363 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14371 (define_expand "rint<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand" ""))
14373 (use (match_operand:MODEF 1 "register_operand" ""))]
14374 "(TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations)
14378 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14379 && !flag_trapping_math)"
14381 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14382 && !flag_trapping_math)
14384 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14387 emit_insn (gen_sse4_1_round<mode>2
14388 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14390 ix86_expand_rint (operand0, operand1);
14394 rtx op0 = gen_reg_rtx (XFmode);
14395 rtx op1 = gen_reg_rtx (XFmode);
14397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14398 emit_insn (gen_rintxf2 (op0, op1));
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14405 (define_expand "round<mode>2"
14406 [(match_operand:MODEF 0 "register_operand" "")
14407 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14409 && !flag_trapping_math && !flag_rounding_math"
14411 if (optimize_insn_for_size_p ())
14413 if (TARGET_64BIT || (<MODE>mode != DFmode))
14414 ix86_expand_round (operand0, operand1);
14416 ix86_expand_rounddf_32 (operand0, operand1);
14420 (define_insn_and_split "*fistdi2_1"
14421 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14422 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14424 "TARGET_USE_FANCY_MATH_387
14425 && can_create_pseudo_p ()"
14430 if (memory_operand (operands[0], VOIDmode))
14431 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14434 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14435 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14440 [(set_attr "type" "fpspc")
14441 (set_attr "mode" "DI")])
14443 (define_insn "fistdi2"
14444 [(set (match_operand:DI 0 "memory_operand" "=m")
14445 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14447 (clobber (match_scratch:XF 2 "=&1f"))]
14448 "TARGET_USE_FANCY_MATH_387"
14449 "* return output_fix_trunc (insn, operands, false);"
14450 [(set_attr "type" "fpspc")
14451 (set_attr "mode" "DI")])
14453 (define_insn "fistdi2_with_temp"
14454 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14455 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14457 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14458 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14459 "TARGET_USE_FANCY_MATH_387"
14461 [(set_attr "type" "fpspc")
14462 (set_attr "mode" "DI")])
14465 [(set (match_operand:DI 0 "register_operand" "")
14466 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14468 (clobber (match_operand:DI 2 "memory_operand" ""))
14469 (clobber (match_scratch 3 ""))]
14471 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14472 (clobber (match_dup 3))])
14473 (set (match_dup 0) (match_dup 2))])
14476 [(set (match_operand:DI 0 "memory_operand" "")
14477 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14479 (clobber (match_operand:DI 2 "memory_operand" ""))
14480 (clobber (match_scratch 3 ""))]
14482 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14483 (clobber (match_dup 3))])])
14485 (define_insn_and_split "*fist<mode>2_1"
14486 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14487 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14489 "TARGET_USE_FANCY_MATH_387
14490 && can_create_pseudo_p ()"
14495 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14496 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14500 [(set_attr "type" "fpspc")
14501 (set_attr "mode" "<MODE>")])
14503 (define_insn "fist<mode>2"
14504 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14505 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14507 "TARGET_USE_FANCY_MATH_387"
14508 "* return output_fix_trunc (insn, operands, false);"
14509 [(set_attr "type" "fpspc")
14510 (set_attr "mode" "<MODE>")])
14512 (define_insn "fist<mode>2_with_temp"
14513 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14516 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14517 "TARGET_USE_FANCY_MATH_387"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "<MODE>")])
14523 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14524 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14526 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14528 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14529 (set (match_dup 0) (match_dup 2))])
14532 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14535 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14537 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14539 (define_expand "lrintxf<mode>2"
14540 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14541 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14543 "TARGET_USE_FANCY_MATH_387")
14545 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14546 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14547 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14548 UNSPEC_FIX_NOTRUNC))]
14549 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14550 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14552 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14553 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14554 (match_operand:MODEF 1 "register_operand" "")]
14555 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14556 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14557 && !flag_trapping_math && !flag_rounding_math"
14559 if (optimize_insn_for_size_p ())
14561 ix86_expand_lround (operand0, operand1);
14565 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14566 (define_insn_and_split "frndintxf2_floor"
14567 [(set (match_operand:XF 0 "register_operand" "")
14568 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14569 UNSPEC_FRNDINT_FLOOR))
14570 (clobber (reg:CC FLAGS_REG))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations
14573 && can_create_pseudo_p ()"
14578 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14583 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14584 operands[2], operands[3]));
14587 [(set_attr "type" "frndint")
14588 (set_attr "i387_cw" "floor")
14589 (set_attr "mode" "XF")])
14591 (define_insn "frndintxf2_floor_i387"
14592 [(set (match_operand:XF 0 "register_operand" "=f")
14593 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14594 UNSPEC_FRNDINT_FLOOR))
14595 (use (match_operand:HI 2 "memory_operand" "m"))
14596 (use (match_operand:HI 3 "memory_operand" "m"))]
14597 "TARGET_USE_FANCY_MATH_387
14598 && flag_unsafe_math_optimizations"
14599 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14600 [(set_attr "type" "frndint")
14601 (set_attr "i387_cw" "floor")
14602 (set_attr "mode" "XF")])
14604 (define_expand "floorxf2"
14605 [(use (match_operand:XF 0 "register_operand" ""))
14606 (use (match_operand:XF 1 "register_operand" ""))]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14610 if (optimize_insn_for_size_p ())
14612 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14616 (define_expand "floor<mode>2"
14617 [(use (match_operand:MODEF 0 "register_operand" ""))
14618 (use (match_operand:MODEF 1 "register_operand" ""))]
14619 "(TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations)
14623 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14624 && !flag_trapping_math)"
14626 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14627 && !flag_trapping_math
14628 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14630 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14633 emit_insn (gen_sse4_1_round<mode>2
14634 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14635 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14636 ix86_expand_floorceil (operand0, operand1, true);
14638 ix86_expand_floorceildf_32 (operand0, operand1, true);
14644 if (optimize_insn_for_size_p ())
14647 op0 = gen_reg_rtx (XFmode);
14648 op1 = gen_reg_rtx (XFmode);
14649 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14650 emit_insn (gen_frndintxf2_floor (op0, op1));
14652 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14657 (define_insn_and_split "*fist<mode>2_floor_1"
14658 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14659 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14660 UNSPEC_FIST_FLOOR))
14661 (clobber (reg:CC FLAGS_REG))]
14662 "TARGET_USE_FANCY_MATH_387
14663 && flag_unsafe_math_optimizations
14664 && can_create_pseudo_p ()"
14669 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14671 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14672 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14673 if (memory_operand (operands[0], VOIDmode))
14674 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14675 operands[2], operands[3]));
14678 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14679 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14680 operands[2], operands[3],
14685 [(set_attr "type" "fistp")
14686 (set_attr "i387_cw" "floor")
14687 (set_attr "mode" "<MODE>")])
14689 (define_insn "fistdi2_floor"
14690 [(set (match_operand:DI 0 "memory_operand" "=m")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14692 UNSPEC_FIST_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" "m"))
14694 (use (match_operand:HI 3 "memory_operand" "m"))
14695 (clobber (match_scratch:XF 4 "=&1f"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_unsafe_math_optimizations"
14698 "* return output_fix_trunc (insn, operands, false);"
14699 [(set_attr "type" "fistp")
14700 (set_attr "i387_cw" "floor")
14701 (set_attr "mode" "DI")])
14703 (define_insn "fistdi2_floor_with_temp"
14704 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14706 UNSPEC_FIST_FLOOR))
14707 (use (match_operand:HI 2 "memory_operand" "m,m"))
14708 (use (match_operand:HI 3 "memory_operand" "m,m"))
14709 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14710 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && flag_unsafe_math_optimizations"
14714 [(set_attr "type" "fistp")
14715 (set_attr "i387_cw" "floor")
14716 (set_attr "mode" "DI")])
14719 [(set (match_operand:DI 0 "register_operand" "")
14720 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14721 UNSPEC_FIST_FLOOR))
14722 (use (match_operand:HI 2 "memory_operand" ""))
14723 (use (match_operand:HI 3 "memory_operand" ""))
14724 (clobber (match_operand:DI 4 "memory_operand" ""))
14725 (clobber (match_scratch 5 ""))]
14727 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14728 (use (match_dup 2))
14729 (use (match_dup 3))
14730 (clobber (match_dup 5))])
14731 (set (match_dup 0) (match_dup 4))])
14734 [(set (match_operand:DI 0 "memory_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736 UNSPEC_FIST_FLOOR))
14737 (use (match_operand:HI 2 "memory_operand" ""))
14738 (use (match_operand:HI 3 "memory_operand" ""))
14739 (clobber (match_operand:DI 4 "memory_operand" ""))
14740 (clobber (match_scratch 5 ""))]
14742 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14743 (use (match_dup 2))
14744 (use (match_dup 3))
14745 (clobber (match_dup 5))])])
14747 (define_insn "fist<mode>2_floor"
14748 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14749 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14750 UNSPEC_FIST_FLOOR))
14751 (use (match_operand:HI 2 "memory_operand" "m"))
14752 (use (match_operand:HI 3 "memory_operand" "m"))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && flag_unsafe_math_optimizations"
14755 "* return output_fix_trunc (insn, operands, false);"
14756 [(set_attr "type" "fistp")
14757 (set_attr "i387_cw" "floor")
14758 (set_attr "mode" "<MODE>")])
14760 (define_insn "fist<mode>2_floor_with_temp"
14761 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14762 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14763 UNSPEC_FIST_FLOOR))
14764 (use (match_operand:HI 2 "memory_operand" "m,m"))
14765 (use (match_operand:HI 3 "memory_operand" "m,m"))
14766 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14767 "TARGET_USE_FANCY_MATH_387
14768 && flag_unsafe_math_optimizations"
14770 [(set_attr "type" "fistp")
14771 (set_attr "i387_cw" "floor")
14772 (set_attr "mode" "<MODE>")])
14775 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14777 UNSPEC_FIST_FLOOR))
14778 (use (match_operand:HI 2 "memory_operand" ""))
14779 (use (match_operand:HI 3 "memory_operand" ""))
14780 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14782 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14783 UNSPEC_FIST_FLOOR))
14784 (use (match_dup 2))
14785 (use (match_dup 3))])
14786 (set (match_dup 0) (match_dup 4))])
14789 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14790 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14791 UNSPEC_FIST_FLOOR))
14792 (use (match_operand:HI 2 "memory_operand" ""))
14793 (use (match_operand:HI 3 "memory_operand" ""))
14794 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14796 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14797 UNSPEC_FIST_FLOOR))
14798 (use (match_dup 2))
14799 (use (match_dup 3))])])
14801 (define_expand "lfloorxf<mode>2"
14802 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14803 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14804 UNSPEC_FIST_FLOOR))
14805 (clobber (reg:CC FLAGS_REG))])]
14806 "TARGET_USE_FANCY_MATH_387
14807 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14808 && flag_unsafe_math_optimizations")
14810 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14811 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14812 (match_operand:MODEF 1 "register_operand" "")]
14813 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14814 && !flag_trapping_math"
14816 if (TARGET_64BIT && optimize_insn_for_size_p ())
14818 ix86_expand_lfloorceil (operand0, operand1, true);
14822 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14823 (define_insn_and_split "frndintxf2_ceil"
14824 [(set (match_operand:XF 0 "register_operand" "")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14826 UNSPEC_FRNDINT_CEIL))
14827 (clobber (reg:CC FLAGS_REG))]
14828 "TARGET_USE_FANCY_MATH_387
14829 && flag_unsafe_math_optimizations
14830 && can_create_pseudo_p ()"
14835 ix86_optimize_mode_switching[I387_CEIL] = 1;
14837 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14838 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14840 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14841 operands[2], operands[3]));
14844 [(set_attr "type" "frndint")
14845 (set_attr "i387_cw" "ceil")
14846 (set_attr "mode" "XF")])
14848 (define_insn "frndintxf2_ceil_i387"
14849 [(set (match_operand:XF 0 "register_operand" "=f")
14850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14851 UNSPEC_FRNDINT_CEIL))
14852 (use (match_operand:HI 2 "memory_operand" "m"))
14853 (use (match_operand:HI 3 "memory_operand" "m"))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14856 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "ceil")
14859 (set_attr "mode" "XF")])
14861 (define_expand "ceilxf2"
14862 [(use (match_operand:XF 0 "register_operand" ""))
14863 (use (match_operand:XF 1 "register_operand" ""))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations"
14867 if (optimize_insn_for_size_p ())
14869 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14873 (define_expand "ceil<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand" ""))
14875 (use (match_operand:MODEF 1 "register_operand" ""))]
14876 "(TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations)
14880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14881 && !flag_trapping_math)"
14883 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14884 && !flag_trapping_math
14885 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14888 emit_insn (gen_sse4_1_round<mode>2
14889 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14890 else if (optimize_insn_for_size_p ())
14892 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14893 ix86_expand_floorceil (operand0, operand1, false);
14895 ix86_expand_floorceildf_32 (operand0, operand1, false);
14901 if (optimize_insn_for_size_p ())
14904 op0 = gen_reg_rtx (XFmode);
14905 op1 = gen_reg_rtx (XFmode);
14906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907 emit_insn (gen_frndintxf2_ceil (op0, op1));
14909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14914 (define_insn_and_split "*fist<mode>2_ceil_1"
14915 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14916 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14918 (clobber (reg:CC FLAGS_REG))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations
14921 && can_create_pseudo_p ()"
14926 ix86_optimize_mode_switching[I387_CEIL] = 1;
14928 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14930 if (memory_operand (operands[0], VOIDmode))
14931 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14932 operands[2], operands[3]));
14935 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14936 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14937 operands[2], operands[3],
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "<MODE>")])
14946 (define_insn "fistdi2_ceil"
14947 [(set (match_operand:DI 0 "memory_operand" "=m")
14948 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14950 (use (match_operand:HI 2 "memory_operand" "m"))
14951 (use (match_operand:HI 3 "memory_operand" "m"))
14952 (clobber (match_scratch:XF 4 "=&1f"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "* return output_fix_trunc (insn, operands, false);"
14956 [(set_attr "type" "fistp")
14957 (set_attr "i387_cw" "ceil")
14958 (set_attr "mode" "DI")])
14960 (define_insn "fistdi2_ceil_with_temp"
14961 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14962 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14964 (use (match_operand:HI 2 "memory_operand" "m,m"))
14965 (use (match_operand:HI 3 "memory_operand" "m,m"))
14966 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14967 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_unsafe_math_optimizations"
14971 [(set_attr "type" "fistp")
14972 (set_attr "i387_cw" "ceil")
14973 (set_attr "mode" "DI")])
14976 [(set (match_operand:DI 0 "register_operand" "")
14977 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14979 (use (match_operand:HI 2 "memory_operand" ""))
14980 (use (match_operand:HI 3 "memory_operand" ""))
14981 (clobber (match_operand:DI 4 "memory_operand" ""))
14982 (clobber (match_scratch 5 ""))]
14984 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14985 (use (match_dup 2))
14986 (use (match_dup 3))
14987 (clobber (match_dup 5))])
14988 (set (match_dup 0) (match_dup 4))])
14991 [(set (match_operand:DI 0 "memory_operand" "")
14992 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14994 (use (match_operand:HI 2 "memory_operand" ""))
14995 (use (match_operand:HI 3 "memory_operand" ""))
14996 (clobber (match_operand:DI 4 "memory_operand" ""))
14997 (clobber (match_scratch 5 ""))]
14999 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15000 (use (match_dup 2))
15001 (use (match_dup 3))
15002 (clobber (match_dup 5))])])
15004 (define_insn "fist<mode>2_ceil"
15005 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15006 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15008 (use (match_operand:HI 2 "memory_operand" "m"))
15009 (use (match_operand:HI 3 "memory_operand" "m"))]
15010 "TARGET_USE_FANCY_MATH_387
15011 && flag_unsafe_math_optimizations"
15012 "* return output_fix_trunc (insn, operands, false);"
15013 [(set_attr "type" "fistp")
15014 (set_attr "i387_cw" "ceil")
15015 (set_attr "mode" "<MODE>")])
15017 (define_insn "fist<mode>2_ceil_with_temp"
15018 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15019 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15021 (use (match_operand:HI 2 "memory_operand" "m,m"))
15022 (use (match_operand:HI 3 "memory_operand" "m,m"))
15023 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15024 "TARGET_USE_FANCY_MATH_387
15025 && flag_unsafe_math_optimizations"
15027 [(set_attr "type" "fistp")
15028 (set_attr "i387_cw" "ceil")
15029 (set_attr "mode" "<MODE>")])
15032 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15033 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15035 (use (match_operand:HI 2 "memory_operand" ""))
15036 (use (match_operand:HI 3 "memory_operand" ""))
15037 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15039 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15041 (use (match_dup 2))
15042 (use (match_dup 3))])
15043 (set (match_dup 0) (match_dup 4))])
15046 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15047 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15049 (use (match_operand:HI 2 "memory_operand" ""))
15050 (use (match_operand:HI 3 "memory_operand" ""))
15051 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15053 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15055 (use (match_dup 2))
15056 (use (match_dup 3))])])
15058 (define_expand "lceilxf<mode>2"
15059 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15060 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15062 (clobber (reg:CC FLAGS_REG))])]
15063 "TARGET_USE_FANCY_MATH_387
15064 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15065 && flag_unsafe_math_optimizations")
15067 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15068 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15069 (match_operand:MODEF 1 "register_operand" "")]
15070 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15071 && !flag_trapping_math"
15073 ix86_expand_lfloorceil (operand0, operand1, false);
15077 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15078 (define_insn_and_split "frndintxf2_trunc"
15079 [(set (match_operand:XF 0 "register_operand" "")
15080 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15081 UNSPEC_FRNDINT_TRUNC))
15082 (clobber (reg:CC FLAGS_REG))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && flag_unsafe_math_optimizations
15085 && can_create_pseudo_p ()"
15090 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15095 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15096 operands[2], operands[3]));
15099 [(set_attr "type" "frndint")
15100 (set_attr "i387_cw" "trunc")
15101 (set_attr "mode" "XF")])
15103 (define_insn "frndintxf2_trunc_i387"
15104 [(set (match_operand:XF 0 "register_operand" "=f")
15105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15106 UNSPEC_FRNDINT_TRUNC))
15107 (use (match_operand:HI 2 "memory_operand" "m"))
15108 (use (match_operand:HI 3 "memory_operand" "m"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15111 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15112 [(set_attr "type" "frndint")
15113 (set_attr "i387_cw" "trunc")
15114 (set_attr "mode" "XF")])
15116 (define_expand "btruncxf2"
15117 [(use (match_operand:XF 0 "register_operand" ""))
15118 (use (match_operand:XF 1 "register_operand" ""))]
15119 "TARGET_USE_FANCY_MATH_387
15120 && flag_unsafe_math_optimizations"
15122 if (optimize_insn_for_size_p ())
15124 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15128 (define_expand "btrunc<mode>2"
15129 [(use (match_operand:MODEF 0 "register_operand" ""))
15130 (use (match_operand:MODEF 1 "register_operand" ""))]
15131 "(TARGET_USE_FANCY_MATH_387
15132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15133 || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations)
15135 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15136 && !flag_trapping_math)"
15138 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15139 && !flag_trapping_math
15140 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15143 emit_insn (gen_sse4_1_round<mode>2
15144 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15145 else if (optimize_insn_for_size_p ())
15147 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15148 ix86_expand_trunc (operand0, operand1);
15150 ix86_expand_truncdf_32 (operand0, operand1);
15156 if (optimize_insn_for_size_p ())
15159 op0 = gen_reg_rtx (XFmode);
15160 op1 = gen_reg_rtx (XFmode);
15161 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15162 emit_insn (gen_frndintxf2_trunc (op0, op1));
15164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15169 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15170 (define_insn_and_split "frndintxf2_mask_pm"
15171 [(set (match_operand:XF 0 "register_operand" "")
15172 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15173 UNSPEC_FRNDINT_MASK_PM))
15174 (clobber (reg:CC FLAGS_REG))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations
15177 && can_create_pseudo_p ()"
15182 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15184 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15185 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15187 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15188 operands[2], operands[3]));
15191 [(set_attr "type" "frndint")
15192 (set_attr "i387_cw" "mask_pm")
15193 (set_attr "mode" "XF")])
15195 (define_insn "frndintxf2_mask_pm_i387"
15196 [(set (match_operand:XF 0 "register_operand" "=f")
15197 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15198 UNSPEC_FRNDINT_MASK_PM))
15199 (use (match_operand:HI 2 "memory_operand" "m"))
15200 (use (match_operand:HI 3 "memory_operand" "m"))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && flag_unsafe_math_optimizations"
15203 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15204 [(set_attr "type" "frndint")
15205 (set_attr "i387_cw" "mask_pm")
15206 (set_attr "mode" "XF")])
15208 (define_expand "nearbyintxf2"
15209 [(use (match_operand:XF 0 "register_operand" ""))
15210 (use (match_operand:XF 1 "register_operand" ""))]
15211 "TARGET_USE_FANCY_MATH_387
15212 && flag_unsafe_math_optimizations"
15214 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15218 (define_expand "nearbyint<mode>2"
15219 [(use (match_operand:MODEF 0 "register_operand" ""))
15220 (use (match_operand:MODEF 1 "register_operand" ""))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15223 || TARGET_MIX_SSE_I387)
15224 && flag_unsafe_math_optimizations"
15226 rtx op0 = gen_reg_rtx (XFmode);
15227 rtx op1 = gen_reg_rtx (XFmode);
15229 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15230 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15236 (define_insn "fxam<mode>2_i387"
15237 [(set (match_operand:HI 0 "register_operand" "=a")
15239 [(match_operand:X87MODEF 1 "register_operand" "f")]
15241 "TARGET_USE_FANCY_MATH_387"
15242 "fxam\n\tfnstsw\t%0"
15243 [(set_attr "type" "multi")
15244 (set_attr "length" "4")
15245 (set_attr "unit" "i387")
15246 (set_attr "mode" "<MODE>")])
15248 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15249 [(set (match_operand:HI 0 "register_operand" "")
15251 [(match_operand:MODEF 1 "memory_operand" "")]
15253 "TARGET_USE_FANCY_MATH_387
15254 && can_create_pseudo_p ()"
15257 [(set (match_dup 2)(match_dup 1))
15259 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15261 operands[2] = gen_reg_rtx (<MODE>mode);
15263 MEM_VOLATILE_P (operands[1]) = 1;
15265 [(set_attr "type" "multi")
15266 (set_attr "unit" "i387")
15267 (set_attr "mode" "<MODE>")])
15269 (define_expand "isinfxf2"
15270 [(use (match_operand:SI 0 "register_operand" ""))
15271 (use (match_operand:XF 1 "register_operand" ""))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && TARGET_C99_FUNCTIONS"
15275 rtx mask = GEN_INT (0x45);
15276 rtx val = GEN_INT (0x05);
15280 rtx scratch = gen_reg_rtx (HImode);
15281 rtx res = gen_reg_rtx (QImode);
15283 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15285 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15286 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15287 cond = gen_rtx_fmt_ee (EQ, QImode,
15288 gen_rtx_REG (CCmode, FLAGS_REG),
15290 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15291 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15295 (define_expand "isinf<mode>2"
15296 [(use (match_operand:SI 0 "register_operand" ""))
15297 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15298 "TARGET_USE_FANCY_MATH_387
15299 && TARGET_C99_FUNCTIONS
15300 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15302 rtx mask = GEN_INT (0x45);
15303 rtx val = GEN_INT (0x05);
15307 rtx scratch = gen_reg_rtx (HImode);
15308 rtx res = gen_reg_rtx (QImode);
15310 /* Remove excess precision by forcing value through memory. */
15311 if (memory_operand (operands[1], VOIDmode))
15312 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15315 enum ix86_stack_slot slot = (virtuals_instantiated
15318 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15320 emit_move_insn (temp, operands[1]);
15321 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15324 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15325 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15326 cond = gen_rtx_fmt_ee (EQ, QImode,
15327 gen_rtx_REG (CCmode, FLAGS_REG),
15329 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15330 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15334 (define_expand "signbitxf2"
15335 [(use (match_operand:SI 0 "register_operand" ""))
15336 (use (match_operand:XF 1 "register_operand" ""))]
15337 "TARGET_USE_FANCY_MATH_387"
15339 rtx scratch = gen_reg_rtx (HImode);
15341 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15342 emit_insn (gen_andsi3 (operands[0],
15343 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15347 (define_insn "movmsk_df"
15348 [(set (match_operand:SI 0 "register_operand" "=r")
15350 [(match_operand:DF 1 "register_operand" "x")]
15352 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15353 "%vmovmskpd\t{%1, %0|%0, %1}"
15354 [(set_attr "type" "ssemov")
15355 (set_attr "prefix" "maybe_vex")
15356 (set_attr "mode" "DF")])
15358 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15359 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15360 (define_expand "signbitdf2"
15361 [(use (match_operand:SI 0 "register_operand" ""))
15362 (use (match_operand:DF 1 "register_operand" ""))]
15363 "TARGET_USE_FANCY_MATH_387
15364 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15366 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15368 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15369 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15373 rtx scratch = gen_reg_rtx (HImode);
15375 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15376 emit_insn (gen_andsi3 (operands[0],
15377 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15382 (define_expand "signbitsf2"
15383 [(use (match_operand:SI 0 "register_operand" ""))
15384 (use (match_operand:SF 1 "register_operand" ""))]
15385 "TARGET_USE_FANCY_MATH_387
15386 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15388 rtx scratch = gen_reg_rtx (HImode);
15390 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15391 emit_insn (gen_andsi3 (operands[0],
15392 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15396 ;; Block operation instructions
15399 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15402 [(set_attr "length" "1")
15403 (set_attr "length_immediate" "0")
15404 (set_attr "modrm" "0")])
15406 (define_expand "movmem<mode>"
15407 [(use (match_operand:BLK 0 "memory_operand" ""))
15408 (use (match_operand:BLK 1 "memory_operand" ""))
15409 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15410 (use (match_operand:SWI48 3 "const_int_operand" ""))
15411 (use (match_operand:SI 4 "const_int_operand" ""))
15412 (use (match_operand:SI 5 "const_int_operand" ""))]
15415 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15416 operands[4], operands[5]))
15422 ;; Most CPUs don't like single string operations
15423 ;; Handle this case here to simplify previous expander.
15425 (define_expand "strmov"
15426 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15427 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15428 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15429 (clobber (reg:CC FLAGS_REG))])
15430 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15431 (clobber (reg:CC FLAGS_REG))])]
15434 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15436 /* If .md ever supports :P for Pmode, these can be directly
15437 in the pattern above. */
15438 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15439 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15441 /* Can't use this if the user has appropriated esi or edi. */
15442 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15443 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15445 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15446 operands[2], operands[3],
15447 operands[5], operands[6]));
15451 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15454 (define_expand "strmov_singleop"
15455 [(parallel [(set (match_operand 1 "memory_operand" "")
15456 (match_operand 3 "memory_operand" ""))
15457 (set (match_operand 0 "register_operand" "")
15458 (match_operand 4 "" ""))
15459 (set (match_operand 2 "register_operand" "")
15460 (match_operand 5 "" ""))])]
15462 "ix86_current_function_needs_cld = 1;")
15464 (define_insn "*strmovdi_rex_1"
15465 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15466 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15467 (set (match_operand:DI 0 "register_operand" "=D")
15468 (plus:DI (match_dup 2)
15470 (set (match_operand:DI 1 "register_operand" "=S")
15471 (plus:DI (match_dup 3)
15475 [(set_attr "type" "str")
15476 (set_attr "memory" "both")
15477 (set_attr "mode" "DI")])
15479 (define_insn "*strmovsi_1"
15480 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15481 (mem:SI (match_operand:P 3 "register_operand" "1")))
15482 (set (match_operand:P 0 "register_operand" "=D")
15483 (plus:P (match_dup 2)
15485 (set (match_operand:P 1 "register_operand" "=S")
15486 (plus:P (match_dup 3)
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "both")
15492 (set_attr "mode" "SI")])
15494 (define_insn "*strmovhi_1"
15495 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15496 (mem:HI (match_operand:P 3 "register_operand" "1")))
15497 (set (match_operand:P 0 "register_operand" "=D")
15498 (plus:P (match_dup 2)
15500 (set (match_operand:P 1 "register_operand" "=S")
15501 (plus:P (match_dup 3)
15505 [(set_attr "type" "str")
15506 (set_attr "memory" "both")
15507 (set_attr "mode" "HI")])
15509 (define_insn "*strmovqi_1"
15510 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15511 (mem:QI (match_operand:P 3 "register_operand" "1")))
15512 (set (match_operand:P 0 "register_operand" "=D")
15513 (plus:P (match_dup 2)
15515 (set (match_operand:P 1 "register_operand" "=S")
15516 (plus:P (match_dup 3)
15520 [(set_attr "type" "str")
15521 (set_attr "memory" "both")
15522 (set (attr "prefix_rex")
15524 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15526 (const_string "*")))
15527 (set_attr "mode" "QI")])
15529 (define_expand "rep_mov"
15530 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15531 (set (match_operand 0 "register_operand" "")
15532 (match_operand 5 "" ""))
15533 (set (match_operand 2 "register_operand" "")
15534 (match_operand 6 "" ""))
15535 (set (match_operand 1 "memory_operand" "")
15536 (match_operand 3 "memory_operand" ""))
15537 (use (match_dup 4))])]
15539 "ix86_current_function_needs_cld = 1;")
15541 (define_insn "*rep_movdi_rex64"
15542 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15543 (set (match_operand:DI 0 "register_operand" "=D")
15544 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15546 (match_operand:DI 3 "register_operand" "0")))
15547 (set (match_operand:DI 1 "register_operand" "=S")
15548 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15549 (match_operand:DI 4 "register_operand" "1")))
15550 (set (mem:BLK (match_dup 3))
15551 (mem:BLK (match_dup 4)))
15552 (use (match_dup 5))]
15555 [(set_attr "type" "str")
15556 (set_attr "prefix_rep" "1")
15557 (set_attr "memory" "both")
15558 (set_attr "mode" "DI")])
15560 (define_insn "*rep_movsi"
15561 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15562 (set (match_operand:P 0 "register_operand" "=D")
15563 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15565 (match_operand:P 3 "register_operand" "0")))
15566 (set (match_operand:P 1 "register_operand" "=S")
15567 (plus:P (ashift:P (match_dup 5) (const_int 2))
15568 (match_operand:P 4 "register_operand" "1")))
15569 (set (mem:BLK (match_dup 3))
15570 (mem:BLK (match_dup 4)))
15571 (use (match_dup 5))]
15573 "rep{%;} movs{l|d}"
15574 [(set_attr "type" "str")
15575 (set_attr "prefix_rep" "1")
15576 (set_attr "memory" "both")
15577 (set_attr "mode" "SI")])
15579 (define_insn "*rep_movqi"
15580 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15581 (set (match_operand:P 0 "register_operand" "=D")
15582 (plus:P (match_operand:P 3 "register_operand" "0")
15583 (match_operand:P 5 "register_operand" "2")))
15584 (set (match_operand:P 1 "register_operand" "=S")
15585 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15586 (set (mem:BLK (match_dup 3))
15587 (mem:BLK (match_dup 4)))
15588 (use (match_dup 5))]
15591 [(set_attr "type" "str")
15592 (set_attr "prefix_rep" "1")
15593 (set_attr "memory" "both")
15594 (set_attr "mode" "QI")])
15596 (define_expand "setmem<mode>"
15597 [(use (match_operand:BLK 0 "memory_operand" ""))
15598 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15599 (use (match_operand:QI 2 "nonmemory_operand" ""))
15600 (use (match_operand 3 "const_int_operand" ""))
15601 (use (match_operand:SI 4 "const_int_operand" ""))
15602 (use (match_operand:SI 5 "const_int_operand" ""))]
15605 if (ix86_expand_setmem (operands[0], operands[1],
15606 operands[2], operands[3],
15607 operands[4], operands[5]))
15613 ;; Most CPUs don't like single string operations
15614 ;; Handle this case here to simplify previous expander.
15616 (define_expand "strset"
15617 [(set (match_operand 1 "memory_operand" "")
15618 (match_operand 2 "register_operand" ""))
15619 (parallel [(set (match_operand 0 "register_operand" "")
15621 (clobber (reg:CC FLAGS_REG))])]
15624 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15625 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15627 /* If .md ever supports :P for Pmode, this can be directly
15628 in the pattern above. */
15629 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15630 GEN_INT (GET_MODE_SIZE (GET_MODE
15632 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15634 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15640 (define_expand "strset_singleop"
15641 [(parallel [(set (match_operand 1 "memory_operand" "")
15642 (match_operand 2 "register_operand" ""))
15643 (set (match_operand 0 "register_operand" "")
15644 (match_operand 3 "" ""))])]
15646 "ix86_current_function_needs_cld = 1;")
15648 (define_insn "*strsetdi_rex_1"
15649 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15650 (match_operand:DI 2 "register_operand" "a"))
15651 (set (match_operand:DI 0 "register_operand" "=D")
15652 (plus:DI (match_dup 1)
15656 [(set_attr "type" "str")
15657 (set_attr "memory" "store")
15658 (set_attr "mode" "DI")])
15660 (define_insn "*strsetsi_1"
15661 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15662 (match_operand:SI 2 "register_operand" "a"))
15663 (set (match_operand:P 0 "register_operand" "=D")
15664 (plus:P (match_dup 1)
15668 [(set_attr "type" "str")
15669 (set_attr "memory" "store")
15670 (set_attr "mode" "SI")])
15672 (define_insn "*strsethi_1"
15673 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15674 (match_operand:HI 2 "register_operand" "a"))
15675 (set (match_operand:P 0 "register_operand" "=D")
15676 (plus:P (match_dup 1)
15680 [(set_attr "type" "str")
15681 (set_attr "memory" "store")
15682 (set_attr "mode" "HI")])
15684 (define_insn "*strsetqi_1"
15685 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15686 (match_operand:QI 2 "register_operand" "a"))
15687 (set (match_operand:P 0 "register_operand" "=D")
15688 (plus:P (match_dup 1)
15692 [(set_attr "type" "str")
15693 (set_attr "memory" "store")
15694 (set (attr "prefix_rex")
15696 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15698 (const_string "*")))
15699 (set_attr "mode" "QI")])
15701 (define_expand "rep_stos"
15702 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15703 (set (match_operand 0 "register_operand" "")
15704 (match_operand 4 "" ""))
15705 (set (match_operand 2 "memory_operand" "") (const_int 0))
15706 (use (match_operand 3 "register_operand" ""))
15707 (use (match_dup 1))])]
15709 "ix86_current_function_needs_cld = 1;")
15711 (define_insn "*rep_stosdi_rex64"
15712 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15713 (set (match_operand:DI 0 "register_operand" "=D")
15714 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15716 (match_operand:DI 3 "register_operand" "0")))
15717 (set (mem:BLK (match_dup 3))
15719 (use (match_operand:DI 2 "register_operand" "a"))
15720 (use (match_dup 4))]
15723 [(set_attr "type" "str")
15724 (set_attr "prefix_rep" "1")
15725 (set_attr "memory" "store")
15726 (set_attr "mode" "DI")])
15728 (define_insn "*rep_stossi"
15729 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15730 (set (match_operand:P 0 "register_operand" "=D")
15731 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15733 (match_operand:P 3 "register_operand" "0")))
15734 (set (mem:BLK (match_dup 3))
15736 (use (match_operand:SI 2 "register_operand" "a"))
15737 (use (match_dup 4))]
15739 "rep{%;} stos{l|d}"
15740 [(set_attr "type" "str")
15741 (set_attr "prefix_rep" "1")
15742 (set_attr "memory" "store")
15743 (set_attr "mode" "SI")])
15745 (define_insn "*rep_stosqi"
15746 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15747 (set (match_operand:P 0 "register_operand" "=D")
15748 (plus:P (match_operand:P 3 "register_operand" "0")
15749 (match_operand:P 4 "register_operand" "1")))
15750 (set (mem:BLK (match_dup 3))
15752 (use (match_operand:QI 2 "register_operand" "a"))
15753 (use (match_dup 4))]
15756 [(set_attr "type" "str")
15757 (set_attr "prefix_rep" "1")
15758 (set_attr "memory" "store")
15759 (set (attr "prefix_rex")
15761 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15763 (const_string "*")))
15764 (set_attr "mode" "QI")])
15766 (define_expand "cmpstrnsi"
15767 [(set (match_operand:SI 0 "register_operand" "")
15768 (compare:SI (match_operand:BLK 1 "general_operand" "")
15769 (match_operand:BLK 2 "general_operand" "")))
15770 (use (match_operand 3 "general_operand" ""))
15771 (use (match_operand 4 "immediate_operand" ""))]
15774 rtx addr1, addr2, out, outlow, count, countreg, align;
15776 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15779 /* Can't use this if the user has appropriated esi or edi. */
15780 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15785 out = gen_reg_rtx (SImode);
15787 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15788 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15789 if (addr1 != XEXP (operands[1], 0))
15790 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15791 if (addr2 != XEXP (operands[2], 0))
15792 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15794 count = operands[3];
15795 countreg = ix86_zero_extend_to_Pmode (count);
15797 /* %%% Iff we are testing strict equality, we can use known alignment
15798 to good advantage. This may be possible with combine, particularly
15799 once cc0 is dead. */
15800 align = operands[4];
15802 if (CONST_INT_P (count))
15804 if (INTVAL (count) == 0)
15806 emit_move_insn (operands[0], const0_rtx);
15809 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15810 operands[1], operands[2]));
15814 rtx (*gen_cmp) (rtx, rtx);
15816 gen_cmp = (TARGET_64BIT
15817 ? gen_cmpdi_1 : gen_cmpsi_1);
15819 emit_insn (gen_cmp (countreg, countreg));
15820 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15821 operands[1], operands[2]));
15824 outlow = gen_lowpart (QImode, out);
15825 emit_insn (gen_cmpintqi (outlow));
15826 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15828 if (operands[0] != out)
15829 emit_move_insn (operands[0], out);
15834 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15836 (define_expand "cmpintqi"
15837 [(set (match_dup 1)
15838 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15840 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15841 (parallel [(set (match_operand:QI 0 "register_operand" "")
15842 (minus:QI (match_dup 1)
15844 (clobber (reg:CC FLAGS_REG))])]
15847 operands[1] = gen_reg_rtx (QImode);
15848 operands[2] = gen_reg_rtx (QImode);
15851 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15852 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15854 (define_expand "cmpstrnqi_nz_1"
15855 [(parallel [(set (reg:CC FLAGS_REG)
15856 (compare:CC (match_operand 4 "memory_operand" "")
15857 (match_operand 5 "memory_operand" "")))
15858 (use (match_operand 2 "register_operand" ""))
15859 (use (match_operand:SI 3 "immediate_operand" ""))
15860 (clobber (match_operand 0 "register_operand" ""))
15861 (clobber (match_operand 1 "register_operand" ""))
15862 (clobber (match_dup 2))])]
15864 "ix86_current_function_needs_cld = 1;")
15866 (define_insn "*cmpstrnqi_nz_1"
15867 [(set (reg:CC FLAGS_REG)
15868 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15869 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15870 (use (match_operand:P 6 "register_operand" "2"))
15871 (use (match_operand:SI 3 "immediate_operand" "i"))
15872 (clobber (match_operand:P 0 "register_operand" "=S"))
15873 (clobber (match_operand:P 1 "register_operand" "=D"))
15874 (clobber (match_operand:P 2 "register_operand" "=c"))]
15877 [(set_attr "type" "str")
15878 (set_attr "mode" "QI")
15879 (set (attr "prefix_rex")
15881 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15883 (const_string "*")))
15884 (set_attr "prefix_rep" "1")])
15886 ;; The same, but the count is not known to not be zero.
15888 (define_expand "cmpstrnqi_1"
15889 [(parallel [(set (reg:CC FLAGS_REG)
15890 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15892 (compare:CC (match_operand 4 "memory_operand" "")
15893 (match_operand 5 "memory_operand" ""))
15895 (use (match_operand:SI 3 "immediate_operand" ""))
15896 (use (reg:CC FLAGS_REG))
15897 (clobber (match_operand 0 "register_operand" ""))
15898 (clobber (match_operand 1 "register_operand" ""))
15899 (clobber (match_dup 2))])]
15901 "ix86_current_function_needs_cld = 1;")
15903 (define_insn "*cmpstrnqi_1"
15904 [(set (reg:CC FLAGS_REG)
15905 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15907 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15908 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15910 (use (match_operand:SI 3 "immediate_operand" "i"))
15911 (use (reg:CC FLAGS_REG))
15912 (clobber (match_operand:P 0 "register_operand" "=S"))
15913 (clobber (match_operand:P 1 "register_operand" "=D"))
15914 (clobber (match_operand:P 2 "register_operand" "=c"))]
15917 [(set_attr "type" "str")
15918 (set_attr "mode" "QI")
15919 (set (attr "prefix_rex")
15921 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15923 (const_string "*")))
15924 (set_attr "prefix_rep" "1")])
15926 (define_expand "strlen<mode>"
15927 [(set (match_operand:SWI48x 0 "register_operand" "")
15928 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15929 (match_operand:QI 2 "immediate_operand" "")
15930 (match_operand 3 "immediate_operand" "")]
15934 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15940 (define_expand "strlenqi_1"
15941 [(parallel [(set (match_operand 0 "register_operand" "")
15942 (match_operand 2 "" ""))
15943 (clobber (match_operand 1 "register_operand" ""))
15944 (clobber (reg:CC FLAGS_REG))])]
15946 "ix86_current_function_needs_cld = 1;")
15948 (define_insn "*strlenqi_1"
15949 [(set (match_operand:P 0 "register_operand" "=&c")
15950 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15951 (match_operand:QI 2 "register_operand" "a")
15952 (match_operand:P 3 "immediate_operand" "i")
15953 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15954 (clobber (match_operand:P 1 "register_operand" "=D"))
15955 (clobber (reg:CC FLAGS_REG))]
15958 [(set_attr "type" "str")
15959 (set_attr "mode" "QI")
15960 (set (attr "prefix_rex")
15962 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15964 (const_string "*")))
15965 (set_attr "prefix_rep" "1")])
15967 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15968 ;; handled in combine, but it is not currently up to the task.
15969 ;; When used for their truth value, the cmpstrn* expanders generate
15978 ;; The intermediate three instructions are unnecessary.
15980 ;; This one handles cmpstrn*_nz_1...
15983 (set (reg:CC FLAGS_REG)
15984 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15985 (mem:BLK (match_operand 5 "register_operand" ""))))
15986 (use (match_operand 6 "register_operand" ""))
15987 (use (match_operand:SI 3 "immediate_operand" ""))
15988 (clobber (match_operand 0 "register_operand" ""))
15989 (clobber (match_operand 1 "register_operand" ""))
15990 (clobber (match_operand 2 "register_operand" ""))])
15991 (set (match_operand:QI 7 "register_operand" "")
15992 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15993 (set (match_operand:QI 8 "register_operand" "")
15994 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15995 (set (reg FLAGS_REG)
15996 (compare (match_dup 7) (match_dup 8)))
15998 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16000 (set (reg:CC FLAGS_REG)
16001 (compare:CC (mem:BLK (match_dup 4))
16002 (mem:BLK (match_dup 5))))
16003 (use (match_dup 6))
16004 (use (match_dup 3))
16005 (clobber (match_dup 0))
16006 (clobber (match_dup 1))
16007 (clobber (match_dup 2))])])
16009 ;; ...and this one handles cmpstrn*_1.
16012 (set (reg:CC FLAGS_REG)
16013 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16015 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16016 (mem:BLK (match_operand 5 "register_operand" "")))
16018 (use (match_operand:SI 3 "immediate_operand" ""))
16019 (use (reg:CC FLAGS_REG))
16020 (clobber (match_operand 0 "register_operand" ""))
16021 (clobber (match_operand 1 "register_operand" ""))
16022 (clobber (match_operand 2 "register_operand" ""))])
16023 (set (match_operand:QI 7 "register_operand" "")
16024 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16025 (set (match_operand:QI 8 "register_operand" "")
16026 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16027 (set (reg FLAGS_REG)
16028 (compare (match_dup 7) (match_dup 8)))
16030 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16032 (set (reg:CC FLAGS_REG)
16033 (if_then_else:CC (ne (match_dup 6)
16035 (compare:CC (mem:BLK (match_dup 4))
16036 (mem:BLK (match_dup 5)))
16038 (use (match_dup 3))
16039 (use (reg:CC FLAGS_REG))
16040 (clobber (match_dup 0))
16041 (clobber (match_dup 1))
16042 (clobber (match_dup 2))])])
16044 ;; Conditional move instructions.
16046 (define_expand "mov<mode>cc"
16047 [(set (match_operand:SWIM 0 "register_operand" "")
16048 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16049 (match_operand:SWIM 2 "general_operand" "")
16050 (match_operand:SWIM 3 "general_operand" "")))]
16052 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16054 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16055 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16056 ;; So just document what we're doing explicitly.
16058 (define_expand "x86_mov<mode>cc_0_m1"
16060 [(set (match_operand:SWI48 0 "register_operand" "")
16061 (if_then_else:SWI48
16062 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16063 [(match_operand 1 "flags_reg_operand" "")
16067 (clobber (reg:CC FLAGS_REG))])])
16069 (define_insn "*x86_mov<mode>cc_0_m1"
16070 [(set (match_operand:SWI48 0 "register_operand" "=r")
16071 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16072 [(reg FLAGS_REG) (const_int 0)])
16075 (clobber (reg:CC FLAGS_REG))]
16077 "sbb{<imodesuffix>}\t%0, %0"
16078 ; Since we don't have the proper number of operands for an alu insn,
16079 ; fill in all the blanks.
16080 [(set_attr "type" "alu")
16081 (set_attr "use_carry" "1")
16082 (set_attr "pent_pair" "pu")
16083 (set_attr "memory" "none")
16084 (set_attr "imm_disp" "false")
16085 (set_attr "mode" "<MODE>")
16086 (set_attr "length_immediate" "0")])
16088 (define_insn "*x86_mov<mode>cc_0_m1_se"
16089 [(set (match_operand:SWI48 0 "register_operand" "=r")
16090 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16091 [(reg FLAGS_REG) (const_int 0)])
16094 (clobber (reg:CC FLAGS_REG))]
16096 "sbb{<imodesuffix>}\t%0, %0"
16097 [(set_attr "type" "alu")
16098 (set_attr "use_carry" "1")
16099 (set_attr "pent_pair" "pu")
16100 (set_attr "memory" "none")
16101 (set_attr "imm_disp" "false")
16102 (set_attr "mode" "<MODE>")
16103 (set_attr "length_immediate" "0")])
16105 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16106 [(set (match_operand:SWI48 0 "register_operand" "=r")
16107 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16108 [(reg FLAGS_REG) (const_int 0)])))]
16110 "sbb{<imodesuffix>}\t%0, %0"
16111 [(set_attr "type" "alu")
16112 (set_attr "use_carry" "1")
16113 (set_attr "pent_pair" "pu")
16114 (set_attr "memory" "none")
16115 (set_attr "imm_disp" "false")
16116 (set_attr "mode" "<MODE>")
16117 (set_attr "length_immediate" "0")])
16119 (define_insn "*mov<mode>cc_noc"
16120 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16121 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16122 [(reg FLAGS_REG) (const_int 0)])
16123 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16124 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16125 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16127 cmov%O2%C1\t{%2, %0|%0, %2}
16128 cmov%O2%c1\t{%3, %0|%0, %3}"
16129 [(set_attr "type" "icmov")
16130 (set_attr "mode" "<MODE>")])
16132 (define_insn_and_split "*movqicc_noc"
16133 [(set (match_operand:QI 0 "register_operand" "=r,r")
16134 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16135 [(match_operand 4 "flags_reg_operand" "")
16137 (match_operand:QI 2 "register_operand" "r,0")
16138 (match_operand:QI 3 "register_operand" "0,r")))]
16139 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16141 "&& reload_completed"
16142 [(set (match_dup 0)
16143 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16146 "operands[0] = gen_lowpart (SImode, operands[0]);
16147 operands[2] = gen_lowpart (SImode, operands[2]);
16148 operands[3] = gen_lowpart (SImode, operands[3]);"
16149 [(set_attr "type" "icmov")
16150 (set_attr "mode" "SI")])
16152 (define_expand "mov<mode>cc"
16153 [(set (match_operand:X87MODEF 0 "register_operand" "")
16154 (if_then_else:X87MODEF
16155 (match_operand 1 "ix86_fp_comparison_operator" "")
16156 (match_operand:X87MODEF 2 "register_operand" "")
16157 (match_operand:X87MODEF 3 "register_operand" "")))]
16158 "(TARGET_80387 && TARGET_CMOVE)
16159 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16160 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16162 (define_insn "*movxfcc_1"
16163 [(set (match_operand:XF 0 "register_operand" "=f,f")
16164 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16165 [(reg FLAGS_REG) (const_int 0)])
16166 (match_operand:XF 2 "register_operand" "f,0")
16167 (match_operand:XF 3 "register_operand" "0,f")))]
16168 "TARGET_80387 && TARGET_CMOVE"
16170 fcmov%F1\t{%2, %0|%0, %2}
16171 fcmov%f1\t{%3, %0|%0, %3}"
16172 [(set_attr "type" "fcmov")
16173 (set_attr "mode" "XF")])
16175 (define_insn "*movdfcc_1_rex64"
16176 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16177 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16178 [(reg FLAGS_REG) (const_int 0)])
16179 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16180 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16181 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16182 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16184 fcmov%F1\t{%2, %0|%0, %2}
16185 fcmov%f1\t{%3, %0|%0, %3}
16186 cmov%O2%C1\t{%2, %0|%0, %2}
16187 cmov%O2%c1\t{%3, %0|%0, %3}"
16188 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16189 (set_attr "mode" "DF,DF,DI,DI")])
16191 (define_insn "*movdfcc_1"
16192 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16193 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16194 [(reg FLAGS_REG) (const_int 0)])
16195 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16196 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16197 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16198 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16200 fcmov%F1\t{%2, %0|%0, %2}
16201 fcmov%f1\t{%3, %0|%0, %3}
16204 [(set_attr "type" "fcmov,fcmov,multi,multi")
16205 (set_attr "mode" "DF,DF,DI,DI")])
16208 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16209 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16210 [(match_operand 4 "flags_reg_operand" "")
16212 (match_operand:DF 2 "nonimmediate_operand" "")
16213 (match_operand:DF 3 "nonimmediate_operand" "")))]
16214 "!TARGET_64BIT && reload_completed"
16215 [(set (match_dup 2)
16216 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16220 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16224 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16225 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16228 (define_insn "*movsfcc_1_387"
16229 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16230 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16231 [(reg FLAGS_REG) (const_int 0)])
16232 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16233 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16234 "TARGET_80387 && TARGET_CMOVE
16235 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16237 fcmov%F1\t{%2, %0|%0, %2}
16238 fcmov%f1\t{%3, %0|%0, %3}
16239 cmov%O2%C1\t{%2, %0|%0, %2}
16240 cmov%O2%c1\t{%3, %0|%0, %3}"
16241 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16242 (set_attr "mode" "SF,SF,SI,SI")])
16244 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16245 ;; the scalar versions to have only XMM registers as operands.
16247 ;; XOP conditional move
16248 (define_insn "*xop_pcmov_<mode>"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 (if_then_else:MODEF
16251 (match_operand:MODEF 1 "register_operand" "x")
16252 (match_operand:MODEF 2 "register_operand" "x")
16253 (match_operand:MODEF 3 "register_operand" "x")))]
16255 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16256 [(set_attr "type" "sse4arg")])
16258 ;; These versions of the min/max patterns are intentionally ignorant of
16259 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16260 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16261 ;; are undefined in this condition, we're certain this is correct.
16263 (define_insn "<code><mode>3"
16264 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16266 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16268 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16270 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16271 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16272 [(set_attr "isa" "noavx,avx")
16273 (set_attr "prefix" "orig,vex")
16274 (set_attr "type" "sseadd")
16275 (set_attr "mode" "<MODE>")])
16277 ;; These versions of the min/max patterns implement exactly the operations
16278 ;; min = (op1 < op2 ? op1 : op2)
16279 ;; max = (!(op1 < op2) ? op1 : op2)
16280 ;; Their operands are not commutative, and thus they may be used in the
16281 ;; presence of -0.0 and NaN.
16283 (define_insn "*ieee_smin<mode>3"
16284 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16286 [(match_operand:MODEF 1 "register_operand" "0,x")
16287 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16291 min<ssemodesuffix>\t{%2, %0|%0, %2}
16292 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16293 [(set_attr "isa" "noavx,avx")
16294 (set_attr "prefix" "orig,vex")
16295 (set_attr "type" "sseadd")
16296 (set_attr "mode" "<MODE>")])
16298 (define_insn "*ieee_smax<mode>3"
16299 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16301 [(match_operand:MODEF 1 "register_operand" "0,x")
16302 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16304 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16306 max<ssemodesuffix>\t{%2, %0|%0, %2}
16307 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16308 [(set_attr "isa" "noavx,avx")
16309 (set_attr "prefix" "orig,vex")
16310 (set_attr "type" "sseadd")
16311 (set_attr "mode" "<MODE>")])
16313 ;; Make two stack loads independent:
16315 ;; fld %st(0) -> fld bb
16316 ;; fmul bb fmul %st(1), %st
16318 ;; Actually we only match the last two instructions for simplicity.
16320 [(set (match_operand 0 "fp_register_operand" "")
16321 (match_operand 1 "fp_register_operand" ""))
16323 (match_operator 2 "binary_fp_operator"
16325 (match_operand 3 "memory_operand" "")]))]
16326 "REGNO (operands[0]) != REGNO (operands[1])"
16327 [(set (match_dup 0) (match_dup 3))
16328 (set (match_dup 0) (match_dup 4))]
16330 ;; The % modifier is not operational anymore in peephole2's, so we have to
16331 ;; swap the operands manually in the case of addition and multiplication.
16332 "if (COMMUTATIVE_ARITH_P (operands[2]))
16333 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16334 GET_MODE (operands[2]),
16335 operands[0], operands[1]);
16337 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16338 GET_MODE (operands[2]),
16339 operands[1], operands[0]);")
16341 ;; Conditional addition patterns
16342 (define_expand "add<mode>cc"
16343 [(match_operand:SWI 0 "register_operand" "")
16344 (match_operand 1 "ordered_comparison_operator" "")
16345 (match_operand:SWI 2 "register_operand" "")
16346 (match_operand:SWI 3 "const_int_operand" "")]
16348 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16350 ;; Misc patterns (?)
16352 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16353 ;; Otherwise there will be nothing to keep
16355 ;; [(set (reg ebp) (reg esp))]
16356 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16357 ;; (clobber (eflags)]
16358 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16360 ;; in proper program order.
16362 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16363 [(set (match_operand:P 0 "register_operand" "=r,r")
16364 (plus:P (match_operand:P 1 "register_operand" "0,r")
16365 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16366 (clobber (reg:CC FLAGS_REG))
16367 (clobber (mem:BLK (scratch)))]
16370 switch (get_attr_type (insn))
16373 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16376 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16377 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16378 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16380 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16383 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16384 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16387 [(set (attr "type")
16388 (cond [(and (eq_attr "alternative" "0")
16389 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16390 (const_string "alu")
16391 (match_operand:<MODE> 2 "const0_operand" "")
16392 (const_string "imov")
16394 (const_string "lea")))
16395 (set (attr "length_immediate")
16396 (cond [(eq_attr "type" "imov")
16398 (and (eq_attr "type" "alu")
16399 (match_operand 2 "const128_operand" ""))
16402 (const_string "*")))
16403 (set_attr "mode" "<MODE>")])
16405 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16406 [(set (match_operand:P 0 "register_operand" "=r")
16407 (minus:P (match_operand:P 1 "register_operand" "0")
16408 (match_operand:P 2 "register_operand" "r")))
16409 (clobber (reg:CC FLAGS_REG))
16410 (clobber (mem:BLK (scratch)))]
16412 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16413 [(set_attr "type" "alu")
16414 (set_attr "mode" "<MODE>")])
16416 (define_insn "allocate_stack_worker_probe_<mode>"
16417 [(set (match_operand:P 0 "register_operand" "=a")
16418 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16419 UNSPECV_STACK_PROBE))
16420 (clobber (reg:CC FLAGS_REG))]
16421 "ix86_target_stack_probe ()"
16422 "call\t___chkstk_ms"
16423 [(set_attr "type" "multi")
16424 (set_attr "length" "5")])
16426 (define_expand "allocate_stack"
16427 [(match_operand 0 "register_operand" "")
16428 (match_operand 1 "general_operand" "")]
16429 "ix86_target_stack_probe ()"
16433 #ifndef CHECK_STACK_LIMIT
16434 #define CHECK_STACK_LIMIT 0
16437 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16438 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16440 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16441 stack_pointer_rtx, 0, OPTAB_DIRECT);
16442 if (x != stack_pointer_rtx)
16443 emit_move_insn (stack_pointer_rtx, x);
16447 x = copy_to_mode_reg (Pmode, operands[1]);
16449 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16451 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16452 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16453 stack_pointer_rtx, 0, OPTAB_DIRECT);
16454 if (x != stack_pointer_rtx)
16455 emit_move_insn (stack_pointer_rtx, x);
16458 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16462 ;; Use IOR for stack probes, this is shorter.
16463 (define_expand "probe_stack"
16464 [(match_operand 0 "memory_operand" "")]
16467 rtx (*gen_ior3) (rtx, rtx, rtx);
16469 gen_ior3 = (GET_MODE (operands[0]) == DImode
16470 ? gen_iordi3 : gen_iorsi3);
16472 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16476 (define_insn "adjust_stack_and_probe<mode>"
16477 [(set (match_operand:P 0 "register_operand" "=r")
16478 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16479 UNSPECV_PROBE_STACK_RANGE))
16480 (set (reg:P SP_REG)
16481 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16482 (clobber (reg:CC FLAGS_REG))
16483 (clobber (mem:BLK (scratch)))]
16485 "* return output_adjust_stack_and_probe (operands[0]);"
16486 [(set_attr "type" "multi")])
16488 (define_insn "probe_stack_range<mode>"
16489 [(set (match_operand:P 0 "register_operand" "=r")
16490 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16491 (match_operand:P 2 "const_int_operand" "n")]
16492 UNSPECV_PROBE_STACK_RANGE))
16493 (clobber (reg:CC FLAGS_REG))]
16495 "* return output_probe_stack_range (operands[0], operands[2]);"
16496 [(set_attr "type" "multi")])
16498 (define_expand "builtin_setjmp_receiver"
16499 [(label_ref (match_operand 0 "" ""))]
16500 "!TARGET_64BIT && flag_pic"
16506 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16507 rtx label_rtx = gen_label_rtx ();
16508 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16509 xops[0] = xops[1] = picreg;
16510 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16511 ix86_expand_binary_operator (MINUS, SImode, xops);
16515 emit_insn (gen_set_got (pic_offset_table_rtx));
16519 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16522 [(set (match_operand 0 "register_operand" "")
16523 (match_operator 3 "promotable_binary_operator"
16524 [(match_operand 1 "register_operand" "")
16525 (match_operand 2 "aligned_operand" "")]))
16526 (clobber (reg:CC FLAGS_REG))]
16527 "! TARGET_PARTIAL_REG_STALL && reload_completed
16528 && ((GET_MODE (operands[0]) == HImode
16529 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16530 /* ??? next two lines just !satisfies_constraint_K (...) */
16531 || !CONST_INT_P (operands[2])
16532 || satisfies_constraint_K (operands[2])))
16533 || (GET_MODE (operands[0]) == QImode
16534 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16535 [(parallel [(set (match_dup 0)
16536 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16537 (clobber (reg:CC FLAGS_REG))])]
16538 "operands[0] = gen_lowpart (SImode, operands[0]);
16539 operands[1] = gen_lowpart (SImode, operands[1]);
16540 if (GET_CODE (operands[3]) != ASHIFT)
16541 operands[2] = gen_lowpart (SImode, operands[2]);
16542 PUT_MODE (operands[3], SImode);")
16544 ; Promote the QImode tests, as i386 has encoding of the AND
16545 ; instruction with 32-bit sign-extended immediate and thus the
16546 ; instruction size is unchanged, except in the %eax case for
16547 ; which it is increased by one byte, hence the ! optimize_size.
16549 [(set (match_operand 0 "flags_reg_operand" "")
16550 (match_operator 2 "compare_operator"
16551 [(and (match_operand 3 "aligned_operand" "")
16552 (match_operand 4 "const_int_operand" ""))
16554 (set (match_operand 1 "register_operand" "")
16555 (and (match_dup 3) (match_dup 4)))]
16556 "! TARGET_PARTIAL_REG_STALL && reload_completed
16557 && optimize_insn_for_speed_p ()
16558 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16559 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16560 /* Ensure that the operand will remain sign-extended immediate. */
16561 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16562 [(parallel [(set (match_dup 0)
16563 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16566 (and:SI (match_dup 3) (match_dup 4)))])]
16569 = gen_int_mode (INTVAL (operands[4])
16570 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16571 operands[1] = gen_lowpart (SImode, operands[1]);
16572 operands[3] = gen_lowpart (SImode, operands[3]);
16575 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16576 ; the TEST instruction with 32-bit sign-extended immediate and thus
16577 ; the instruction size would at least double, which is not what we
16578 ; want even with ! optimize_size.
16580 [(set (match_operand 0 "flags_reg_operand" "")
16581 (match_operator 1 "compare_operator"
16582 [(and (match_operand:HI 2 "aligned_operand" "")
16583 (match_operand:HI 3 "const_int_operand" ""))
16585 "! TARGET_PARTIAL_REG_STALL && reload_completed
16586 && ! TARGET_FAST_PREFIX
16587 && optimize_insn_for_speed_p ()
16588 /* Ensure that the operand will remain sign-extended immediate. */
16589 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16590 [(set (match_dup 0)
16591 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16595 = gen_int_mode (INTVAL (operands[3])
16596 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16597 operands[2] = gen_lowpart (SImode, operands[2]);
16601 [(set (match_operand 0 "register_operand" "")
16602 (neg (match_operand 1 "register_operand" "")))
16603 (clobber (reg:CC FLAGS_REG))]
16604 "! TARGET_PARTIAL_REG_STALL && reload_completed
16605 && (GET_MODE (operands[0]) == HImode
16606 || (GET_MODE (operands[0]) == QImode
16607 && (TARGET_PROMOTE_QImode
16608 || optimize_insn_for_size_p ())))"
16609 [(parallel [(set (match_dup 0)
16610 (neg:SI (match_dup 1)))
16611 (clobber (reg:CC FLAGS_REG))])]
16612 "operands[0] = gen_lowpart (SImode, operands[0]);
16613 operands[1] = gen_lowpart (SImode, operands[1]);")
16616 [(set (match_operand 0 "register_operand" "")
16617 (not (match_operand 1 "register_operand" "")))]
16618 "! TARGET_PARTIAL_REG_STALL && reload_completed
16619 && (GET_MODE (operands[0]) == HImode
16620 || (GET_MODE (operands[0]) == QImode
16621 && (TARGET_PROMOTE_QImode
16622 || optimize_insn_for_size_p ())))"
16623 [(set (match_dup 0)
16624 (not:SI (match_dup 1)))]
16625 "operands[0] = gen_lowpart (SImode, operands[0]);
16626 operands[1] = gen_lowpart (SImode, operands[1]);")
16629 [(set (match_operand 0 "register_operand" "")
16630 (if_then_else (match_operator 1 "ordered_comparison_operator"
16631 [(reg FLAGS_REG) (const_int 0)])
16632 (match_operand 2 "register_operand" "")
16633 (match_operand 3 "register_operand" "")))]
16634 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16635 && (GET_MODE (operands[0]) == HImode
16636 || (GET_MODE (operands[0]) == QImode
16637 && (TARGET_PROMOTE_QImode
16638 || optimize_insn_for_size_p ())))"
16639 [(set (match_dup 0)
16640 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16641 "operands[0] = gen_lowpart (SImode, operands[0]);
16642 operands[2] = gen_lowpart (SImode, operands[2]);
16643 operands[3] = gen_lowpart (SImode, operands[3]);")
16645 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16646 ;; transform a complex memory operation into two memory to register operations.
16648 ;; Don't push memory operands
16650 [(set (match_operand:SWI 0 "push_operand" "")
16651 (match_operand:SWI 1 "memory_operand" ""))
16652 (match_scratch:SWI 2 "<r>")]
16653 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16654 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16655 [(set (match_dup 2) (match_dup 1))
16656 (set (match_dup 0) (match_dup 2))])
16658 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16661 [(set (match_operand:SF 0 "push_operand" "")
16662 (match_operand:SF 1 "memory_operand" ""))
16663 (match_scratch:SF 2 "r")]
16664 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16665 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16666 [(set (match_dup 2) (match_dup 1))
16667 (set (match_dup 0) (match_dup 2))])
16669 ;; Don't move an immediate directly to memory when the instruction
16672 [(match_scratch:SWI124 1 "<r>")
16673 (set (match_operand:SWI124 0 "memory_operand" "")
16675 "optimize_insn_for_speed_p ()
16676 && !TARGET_USE_MOV0
16677 && TARGET_SPLIT_LONG_MOVES
16678 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16679 && peep2_regno_dead_p (0, FLAGS_REG)"
16680 [(parallel [(set (match_dup 2) (const_int 0))
16681 (clobber (reg:CC FLAGS_REG))])
16682 (set (match_dup 0) (match_dup 1))]
16683 "operands[2] = gen_lowpart (SImode, operands[1]);")
16686 [(match_scratch:SWI124 2 "<r>")
16687 (set (match_operand:SWI124 0 "memory_operand" "")
16688 (match_operand:SWI124 1 "immediate_operand" ""))]
16689 "optimize_insn_for_speed_p ()
16690 && TARGET_SPLIT_LONG_MOVES
16691 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16692 [(set (match_dup 2) (match_dup 1))
16693 (set (match_dup 0) (match_dup 2))])
16695 ;; Don't compare memory with zero, load and use a test instead.
16697 [(set (match_operand 0 "flags_reg_operand" "")
16698 (match_operator 1 "compare_operator"
16699 [(match_operand:SI 2 "memory_operand" "")
16701 (match_scratch:SI 3 "r")]
16702 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16703 [(set (match_dup 3) (match_dup 2))
16704 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16706 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16707 ;; Don't split NOTs with a displacement operand, because resulting XOR
16708 ;; will not be pairable anyway.
16710 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16711 ;; represented using a modRM byte. The XOR replacement is long decoded,
16712 ;; so this split helps here as well.
16714 ;; Note: Can't do this as a regular split because we can't get proper
16715 ;; lifetime information then.
16718 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16719 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16720 "optimize_insn_for_speed_p ()
16721 && ((TARGET_NOT_UNPAIRABLE
16722 && (!MEM_P (operands[0])
16723 || !memory_displacement_operand (operands[0], <MODE>mode)))
16724 || (TARGET_NOT_VECTORMODE
16725 && long_memory_operand (operands[0], <MODE>mode)))
16726 && peep2_regno_dead_p (0, FLAGS_REG)"
16727 [(parallel [(set (match_dup 0)
16728 (xor:SWI124 (match_dup 1) (const_int -1)))
16729 (clobber (reg:CC FLAGS_REG))])])
16731 ;; Non pairable "test imm, reg" instructions can be translated to
16732 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16733 ;; byte opcode instead of two, have a short form for byte operands),
16734 ;; so do it for other CPUs as well. Given that the value was dead,
16735 ;; this should not create any new dependencies. Pass on the sub-word
16736 ;; versions if we're concerned about partial register stalls.
16739 [(set (match_operand 0 "flags_reg_operand" "")
16740 (match_operator 1 "compare_operator"
16741 [(and:SI (match_operand:SI 2 "register_operand" "")
16742 (match_operand:SI 3 "immediate_operand" ""))
16744 "ix86_match_ccmode (insn, CCNOmode)
16745 && (true_regnum (operands[2]) != AX_REG
16746 || satisfies_constraint_K (operands[3]))
16747 && peep2_reg_dead_p (1, operands[2])"
16749 [(set (match_dup 0)
16750 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16753 (and:SI (match_dup 2) (match_dup 3)))])])
16755 ;; We don't need to handle HImode case, because it will be promoted to SImode
16756 ;; on ! TARGET_PARTIAL_REG_STALL
16759 [(set (match_operand 0 "flags_reg_operand" "")
16760 (match_operator 1 "compare_operator"
16761 [(and:QI (match_operand:QI 2 "register_operand" "")
16762 (match_operand:QI 3 "immediate_operand" ""))
16764 "! TARGET_PARTIAL_REG_STALL
16765 && ix86_match_ccmode (insn, CCNOmode)
16766 && true_regnum (operands[2]) != AX_REG
16767 && peep2_reg_dead_p (1, operands[2])"
16769 [(set (match_dup 0)
16770 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16773 (and:QI (match_dup 2) (match_dup 3)))])])
16776 [(set (match_operand 0 "flags_reg_operand" "")
16777 (match_operator 1 "compare_operator"
16780 (match_operand 2 "ext_register_operand" "")
16783 (match_operand 3 "const_int_operand" ""))
16785 "! TARGET_PARTIAL_REG_STALL
16786 && ix86_match_ccmode (insn, CCNOmode)
16787 && true_regnum (operands[2]) != AX_REG
16788 && peep2_reg_dead_p (1, operands[2])"
16789 [(parallel [(set (match_dup 0)
16798 (set (zero_extract:SI (match_dup 2)
16806 (match_dup 3)))])])
16808 ;; Don't do logical operations with memory inputs.
16810 [(match_scratch:SI 2 "r")
16811 (parallel [(set (match_operand:SI 0 "register_operand" "")
16812 (match_operator:SI 3 "arith_or_logical_operator"
16814 (match_operand:SI 1 "memory_operand" "")]))
16815 (clobber (reg:CC FLAGS_REG))])]
16816 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16817 [(set (match_dup 2) (match_dup 1))
16818 (parallel [(set (match_dup 0)
16819 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16820 (clobber (reg:CC FLAGS_REG))])])
16823 [(match_scratch:SI 2 "r")
16824 (parallel [(set (match_operand:SI 0 "register_operand" "")
16825 (match_operator:SI 3 "arith_or_logical_operator"
16826 [(match_operand:SI 1 "memory_operand" "")
16828 (clobber (reg:CC FLAGS_REG))])]
16829 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16830 [(set (match_dup 2) (match_dup 1))
16831 (parallel [(set (match_dup 0)
16832 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16833 (clobber (reg:CC FLAGS_REG))])])
16835 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16836 ;; refers to the destination of the load!
16839 [(set (match_operand:SI 0 "register_operand" "")
16840 (match_operand:SI 1 "register_operand" ""))
16841 (parallel [(set (match_dup 0)
16842 (match_operator:SI 3 "commutative_operator"
16844 (match_operand:SI 2 "memory_operand" "")]))
16845 (clobber (reg:CC FLAGS_REG))])]
16846 "REGNO (operands[0]) != REGNO (operands[1])
16847 && GENERAL_REGNO_P (REGNO (operands[0]))
16848 && GENERAL_REGNO_P (REGNO (operands[1]))"
16849 [(set (match_dup 0) (match_dup 4))
16850 (parallel [(set (match_dup 0)
16851 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16852 (clobber (reg:CC FLAGS_REG))])]
16853 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16856 [(set (match_operand 0 "register_operand" "")
16857 (match_operand 1 "register_operand" ""))
16859 (match_operator 3 "commutative_operator"
16861 (match_operand 2 "memory_operand" "")]))]
16862 "REGNO (operands[0]) != REGNO (operands[1])
16863 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16864 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16865 [(set (match_dup 0) (match_dup 2))
16867 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16869 ; Don't do logical operations with memory outputs
16871 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16872 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16873 ; the same decoder scheduling characteristics as the original.
16876 [(match_scratch:SI 2 "r")
16877 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16878 (match_operator:SI 3 "arith_or_logical_operator"
16880 (match_operand:SI 1 "nonmemory_operand" "")]))
16881 (clobber (reg:CC FLAGS_REG))])]
16882 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16883 /* Do not split stack checking probes. */
16884 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16885 [(set (match_dup 2) (match_dup 0))
16886 (parallel [(set (match_dup 2)
16887 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16888 (clobber (reg:CC FLAGS_REG))])
16889 (set (match_dup 0) (match_dup 2))])
16892 [(match_scratch:SI 2 "r")
16893 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16894 (match_operator:SI 3 "arith_or_logical_operator"
16895 [(match_operand:SI 1 "nonmemory_operand" "")
16897 (clobber (reg:CC FLAGS_REG))])]
16898 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16899 /* Do not split stack checking probes. */
16900 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16901 [(set (match_dup 2) (match_dup 0))
16902 (parallel [(set (match_dup 2)
16903 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16904 (clobber (reg:CC FLAGS_REG))])
16905 (set (match_dup 0) (match_dup 2))])
16907 ;; Attempt to use arith or logical operations with memory outputs with
16908 ;; setting of flags.
16910 [(set (match_operand:SWI 0 "register_operand" "")
16911 (match_operand:SWI 1 "memory_operand" ""))
16912 (parallel [(set (match_dup 0)
16913 (match_operator:SWI 3 "plusminuslogic_operator"
16915 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16916 (clobber (reg:CC FLAGS_REG))])
16917 (set (match_dup 1) (match_dup 0))
16918 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16919 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16920 && peep2_reg_dead_p (4, operands[0])
16921 && !reg_overlap_mentioned_p (operands[0], operands[1])
16922 && ix86_match_ccmode (peep2_next_insn (3),
16923 (GET_CODE (operands[3]) == PLUS
16924 || GET_CODE (operands[3]) == MINUS)
16925 ? CCGOCmode : CCNOmode)"
16926 [(parallel [(set (match_dup 4) (match_dup 5))
16927 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16928 (match_dup 2)]))])]
16929 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16930 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16931 copy_rtx (operands[1]),
16932 copy_rtx (operands[2]));
16933 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16934 operands[5], const0_rtx);")
16937 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16938 (match_operator:SWI 2 "plusminuslogic_operator"
16940 (match_operand:SWI 1 "memory_operand" "")]))
16941 (clobber (reg:CC FLAGS_REG))])
16942 (set (match_dup 1) (match_dup 0))
16943 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16944 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16945 && GET_CODE (operands[2]) != MINUS
16946 && peep2_reg_dead_p (3, operands[0])
16947 && !reg_overlap_mentioned_p (operands[0], operands[1])
16948 && ix86_match_ccmode (peep2_next_insn (2),
16949 GET_CODE (operands[2]) == PLUS
16950 ? CCGOCmode : CCNOmode)"
16951 [(parallel [(set (match_dup 3) (match_dup 4))
16952 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16953 (match_dup 0)]))])]
16954 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16955 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16956 copy_rtx (operands[1]),
16957 copy_rtx (operands[0]));
16958 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16959 operands[4], const0_rtx);")
16962 [(set (match_operand:SWI12 0 "register_operand" "")
16963 (match_operand:SWI12 1 "memory_operand" ""))
16964 (parallel [(set (match_operand:SI 4 "register_operand" "")
16965 (match_operator:SI 3 "plusminuslogic_operator"
16967 (match_operand:SI 2 "nonmemory_operand" "")]))
16968 (clobber (reg:CC FLAGS_REG))])
16969 (set (match_dup 1) (match_dup 0))
16970 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16971 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16972 && REG_P (operands[0]) && REG_P (operands[4])
16973 && REGNO (operands[0]) == REGNO (operands[4])
16974 && peep2_reg_dead_p (4, operands[0])
16975 && !reg_overlap_mentioned_p (operands[0], operands[1])
16976 && ix86_match_ccmode (peep2_next_insn (3),
16977 (GET_CODE (operands[3]) == PLUS
16978 || GET_CODE (operands[3]) == MINUS)
16979 ? CCGOCmode : CCNOmode)"
16980 [(parallel [(set (match_dup 4) (match_dup 5))
16981 (set (match_dup 1) (match_dup 6))])]
16982 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16983 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16984 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16985 copy_rtx (operands[1]), operands[2]);
16986 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16987 operands[5], const0_rtx);
16988 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16989 copy_rtx (operands[1]),
16990 copy_rtx (operands[2]));")
16992 ;; Attempt to always use XOR for zeroing registers.
16994 [(set (match_operand 0 "register_operand" "")
16995 (match_operand 1 "const0_operand" ""))]
16996 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16997 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16998 && GENERAL_REG_P (operands[0])
16999 && peep2_regno_dead_p (0, FLAGS_REG)"
17000 [(parallel [(set (match_dup 0) (const_int 0))
17001 (clobber (reg:CC FLAGS_REG))])]
17002 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17005 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17007 "(GET_MODE (operands[0]) == QImode
17008 || GET_MODE (operands[0]) == HImode)
17009 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17010 && peep2_regno_dead_p (0, FLAGS_REG)"
17011 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17012 (clobber (reg:CC FLAGS_REG))])])
17014 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17016 [(set (match_operand:SWI248 0 "register_operand" "")
17018 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17019 && peep2_regno_dead_p (0, FLAGS_REG)"
17020 [(parallel [(set (match_dup 0) (const_int -1))
17021 (clobber (reg:CC FLAGS_REG))])]
17023 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17024 operands[0] = gen_lowpart (SImode, operands[0]);
17027 ;; Attempt to convert simple lea to add/shift.
17028 ;; These can be created by move expanders.
17031 [(set (match_operand:SWI48 0 "register_operand" "")
17032 (plus:SWI48 (match_dup 0)
17033 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17034 "peep2_regno_dead_p (0, FLAGS_REG)"
17035 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17036 (clobber (reg:CC FLAGS_REG))])])
17039 [(set (match_operand:SI 0 "register_operand" "")
17040 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17041 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17043 && peep2_regno_dead_p (0, FLAGS_REG)
17044 && REGNO (operands[0]) == REGNO (operands[1])"
17045 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17046 (clobber (reg:CC FLAGS_REG))])]
17047 "operands[2] = gen_lowpart (SImode, operands[2]);")
17050 [(set (match_operand:SWI48 0 "register_operand" "")
17051 (mult:SWI48 (match_dup 0)
17052 (match_operand:SWI48 1 "const_int_operand" "")))]
17053 "exact_log2 (INTVAL (operands[1])) >= 0
17054 && peep2_regno_dead_p (0, FLAGS_REG)"
17055 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17060 [(set (match_operand:SI 0 "register_operand" "")
17061 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17062 (match_operand:DI 2 "const_int_operand" "")) 0))]
17064 && exact_log2 (INTVAL (operands[2])) >= 0
17065 && REGNO (operands[0]) == REGNO (operands[1])
17066 && peep2_regno_dead_p (0, FLAGS_REG)"
17067 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17068 (clobber (reg:CC FLAGS_REG))])]
17069 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17071 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17072 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17073 ;; On many CPUs it is also faster, since special hardware to avoid esp
17074 ;; dependencies is present.
17076 ;; While some of these conversions may be done using splitters, we use
17077 ;; peepholes in order to allow combine_stack_adjustments pass to see
17078 ;; nonobfuscated RTL.
17080 ;; Convert prologue esp subtractions to push.
17081 ;; We need register to push. In order to keep verify_flow_info happy we have
17083 ;; - use scratch and clobber it in order to avoid dependencies
17084 ;; - use already live register
17085 ;; We can't use the second way right now, since there is no reliable way how to
17086 ;; verify that given register is live. First choice will also most likely in
17087 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17088 ;; call clobbered registers are dead. We may want to use base pointer as an
17089 ;; alternative when no register is available later.
17092 [(match_scratch:P 1 "r")
17093 (parallel [(set (reg:P SP_REG)
17094 (plus:P (reg:P SP_REG)
17095 (match_operand:P 0 "const_int_operand" "")))
17096 (clobber (reg:CC FLAGS_REG))
17097 (clobber (mem:BLK (scratch)))])]
17098 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17099 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17100 [(clobber (match_dup 1))
17101 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17102 (clobber (mem:BLK (scratch)))])])
17105 [(match_scratch:P 1 "r")
17106 (parallel [(set (reg:P SP_REG)
17107 (plus:P (reg:P SP_REG)
17108 (match_operand:P 0 "const_int_operand" "")))
17109 (clobber (reg:CC FLAGS_REG))
17110 (clobber (mem:BLK (scratch)))])]
17111 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17112 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17113 [(clobber (match_dup 1))
17114 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17115 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17116 (clobber (mem:BLK (scratch)))])])
17118 ;; Convert esp subtractions to push.
17120 [(match_scratch:P 1 "r")
17121 (parallel [(set (reg:P SP_REG)
17122 (plus:P (reg:P SP_REG)
17123 (match_operand:P 0 "const_int_operand" "")))
17124 (clobber (reg:CC FLAGS_REG))])]
17125 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17126 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17127 [(clobber (match_dup 1))
17128 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17131 [(match_scratch:P 1 "r")
17132 (parallel [(set (reg:P SP_REG)
17133 (plus:P (reg:P SP_REG)
17134 (match_operand:P 0 "const_int_operand" "")))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17137 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17138 [(clobber (match_dup 1))
17139 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17140 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17142 ;; Convert epilogue deallocator to pop.
17144 [(match_scratch:P 1 "r")
17145 (parallel [(set (reg:P SP_REG)
17146 (plus:P (reg:P SP_REG)
17147 (match_operand:P 0 "const_int_operand" "")))
17148 (clobber (reg:CC FLAGS_REG))
17149 (clobber (mem:BLK (scratch)))])]
17150 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17151 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17152 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17153 (clobber (mem:BLK (scratch)))])])
17155 ;; Two pops case is tricky, since pop causes dependency
17156 ;; on destination register. We use two registers if available.
17158 [(match_scratch:P 1 "r")
17159 (match_scratch:P 2 "r")
17160 (parallel [(set (reg:P SP_REG)
17161 (plus:P (reg:P SP_REG)
17162 (match_operand:P 0 "const_int_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))
17164 (clobber (mem:BLK (scratch)))])]
17165 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17166 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17167 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17168 (clobber (mem:BLK (scratch)))])
17169 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17172 [(match_scratch:P 1 "r")
17173 (parallel [(set (reg:P SP_REG)
17174 (plus:P (reg:P SP_REG)
17175 (match_operand:P 0 "const_int_operand" "")))
17176 (clobber (reg:CC FLAGS_REG))
17177 (clobber (mem:BLK (scratch)))])]
17178 "optimize_insn_for_size_p ()
17179 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17180 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17181 (clobber (mem:BLK (scratch)))])
17182 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17184 ;; Convert esp additions to pop.
17186 [(match_scratch:P 1 "r")
17187 (parallel [(set (reg:P SP_REG)
17188 (plus:P (reg:P SP_REG)
17189 (match_operand:P 0 "const_int_operand" "")))
17190 (clobber (reg:CC FLAGS_REG))])]
17191 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17192 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17194 ;; Two pops case is tricky, since pop causes dependency
17195 ;; on destination register. We use two registers if available.
17197 [(match_scratch:P 1 "r")
17198 (match_scratch:P 2 "r")
17199 (parallel [(set (reg:P SP_REG)
17200 (plus:P (reg:P SP_REG)
17201 (match_operand:P 0 "const_int_operand" "")))
17202 (clobber (reg:CC FLAGS_REG))])]
17203 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17204 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17205 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17208 [(match_scratch:P 1 "r")
17209 (parallel [(set (reg:P SP_REG)
17210 (plus:P (reg:P SP_REG)
17211 (match_operand:P 0 "const_int_operand" "")))
17212 (clobber (reg:CC FLAGS_REG))])]
17213 "optimize_insn_for_size_p ()
17214 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17215 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17216 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17218 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17219 ;; required and register dies. Similarly for 128 to -128.
17221 [(set (match_operand 0 "flags_reg_operand" "")
17222 (match_operator 1 "compare_operator"
17223 [(match_operand 2 "register_operand" "")
17224 (match_operand 3 "const_int_operand" "")]))]
17225 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17226 && incdec_operand (operands[3], GET_MODE (operands[3])))
17227 || (!TARGET_FUSE_CMP_AND_BRANCH
17228 && INTVAL (operands[3]) == 128))
17229 && ix86_match_ccmode (insn, CCGCmode)
17230 && peep2_reg_dead_p (1, operands[2])"
17231 [(parallel [(set (match_dup 0)
17232 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17233 (clobber (match_dup 2))])])
17235 ;; Convert imul by three, five and nine into lea
17238 [(set (match_operand:SWI48 0 "register_operand" "")
17239 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17240 (match_operand:SWI48 2 "const_int_operand" "")))
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "INTVAL (operands[2]) == 3
17243 || INTVAL (operands[2]) == 5
17244 || INTVAL (operands[2]) == 9"
17245 [(set (match_dup 0)
17246 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17248 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17252 [(set (match_operand:SWI48 0 "register_operand" "")
17253 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17254 (match_operand:SWI48 2 "const_int_operand" "")))
17255 (clobber (reg:CC FLAGS_REG))])]
17256 "optimize_insn_for_speed_p ()
17257 && (INTVAL (operands[2]) == 3
17258 || INTVAL (operands[2]) == 5
17259 || INTVAL (operands[2]) == 9)"
17260 [(set (match_dup 0) (match_dup 1))
17262 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17264 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17266 ;; imul $32bit_imm, mem, reg is vector decoded, while
17267 ;; imul $32bit_imm, reg, reg is direct decoded.
17269 [(match_scratch:SWI48 3 "r")
17270 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17271 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17272 (match_operand:SWI48 2 "immediate_operand" "")))
17273 (clobber (reg:CC FLAGS_REG))])]
17274 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17275 && !satisfies_constraint_K (operands[2])"
17276 [(set (match_dup 3) (match_dup 1))
17277 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17278 (clobber (reg:CC FLAGS_REG))])])
17281 [(match_scratch:SI 3 "r")
17282 (parallel [(set (match_operand:DI 0 "register_operand" "")
17284 (mult:SI (match_operand:SI 1 "memory_operand" "")
17285 (match_operand:SI 2 "immediate_operand" ""))))
17286 (clobber (reg:CC FLAGS_REG))])]
17288 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17289 && !satisfies_constraint_K (operands[2])"
17290 [(set (match_dup 3) (match_dup 1))
17291 (parallel [(set (match_dup 0)
17292 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17293 (clobber (reg:CC FLAGS_REG))])])
17295 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17296 ;; Convert it into imul reg, reg
17297 ;; It would be better to force assembler to encode instruction using long
17298 ;; immediate, but there is apparently no way to do so.
17300 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17302 (match_operand:SWI248 1 "nonimmediate_operand" "")
17303 (match_operand:SWI248 2 "const_int_operand" "")))
17304 (clobber (reg:CC FLAGS_REG))])
17305 (match_scratch:SWI248 3 "r")]
17306 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17307 && satisfies_constraint_K (operands[2])"
17308 [(set (match_dup 3) (match_dup 2))
17309 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17310 (clobber (reg:CC FLAGS_REG))])]
17312 if (!rtx_equal_p (operands[0], operands[1]))
17313 emit_move_insn (operands[0], operands[1]);
17316 ;; After splitting up read-modify operations, array accesses with memory
17317 ;; operands might end up in form:
17319 ;; movl 4(%esp), %edx
17321 ;; instead of pre-splitting:
17323 ;; addl 4(%esp), %eax
17325 ;; movl 4(%esp), %edx
17326 ;; leal (%edx,%eax,4), %eax
17329 [(match_scratch:P 5 "r")
17330 (parallel [(set (match_operand 0 "register_operand" "")
17331 (ashift (match_operand 1 "register_operand" "")
17332 (match_operand 2 "const_int_operand" "")))
17333 (clobber (reg:CC FLAGS_REG))])
17334 (parallel [(set (match_operand 3 "register_operand" "")
17335 (plus (match_dup 0)
17336 (match_operand 4 "x86_64_general_operand" "")))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17339 /* Validate MODE for lea. */
17340 && ((!TARGET_PARTIAL_REG_STALL
17341 && (GET_MODE (operands[0]) == QImode
17342 || GET_MODE (operands[0]) == HImode))
17343 || GET_MODE (operands[0]) == SImode
17344 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17345 && (rtx_equal_p (operands[0], operands[3])
17346 || peep2_reg_dead_p (2, operands[0]))
17347 /* We reorder load and the shift. */
17348 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17349 [(set (match_dup 5) (match_dup 4))
17350 (set (match_dup 0) (match_dup 1))]
17352 enum machine_mode op1mode = GET_MODE (operands[1]);
17353 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17354 int scale = 1 << INTVAL (operands[2]);
17355 rtx index = gen_lowpart (Pmode, operands[1]);
17356 rtx base = gen_lowpart (Pmode, operands[5]);
17357 rtx dest = gen_lowpart (mode, operands[3]);
17359 operands[1] = gen_rtx_PLUS (Pmode, base,
17360 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17361 operands[5] = base;
17363 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17364 if (op1mode != Pmode)
17365 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17366 operands[0] = dest;
17369 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17370 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17371 ;; caught for use by garbage collectors and the like. Using an insn that
17372 ;; maps to SIGILL makes it more likely the program will rightfully die.
17373 ;; Keeping with tradition, "6" is in honor of #UD.
17374 (define_insn "trap"
17375 [(trap_if (const_int 1) (const_int 6))]
17377 { return ASM_SHORT "0x0b0f"; }
17378 [(set_attr "length" "2")])
17380 (define_expand "prefetch"
17381 [(prefetch (match_operand 0 "address_operand" "")
17382 (match_operand:SI 1 "const_int_operand" "")
17383 (match_operand:SI 2 "const_int_operand" ""))]
17384 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17386 int rw = INTVAL (operands[1]);
17387 int locality = INTVAL (operands[2]);
17389 gcc_assert (rw == 0 || rw == 1);
17390 gcc_assert (locality >= 0 && locality <= 3);
17391 gcc_assert (GET_MODE (operands[0]) == Pmode
17392 || GET_MODE (operands[0]) == VOIDmode);
17394 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17395 supported by SSE counterpart or the SSE prefetch is not available
17396 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17398 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17399 operands[2] = GEN_INT (3);
17401 operands[1] = const0_rtx;
17404 (define_insn "*prefetch_sse_<mode>"
17405 [(prefetch (match_operand:P 0 "address_operand" "p")
17407 (match_operand:SI 1 "const_int_operand" ""))]
17408 "TARGET_PREFETCH_SSE"
17410 static const char * const patterns[4] = {
17411 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17414 int locality = INTVAL (operands[1]);
17415 gcc_assert (locality >= 0 && locality <= 3);
17417 return patterns[locality];
17419 [(set_attr "type" "sse")
17420 (set_attr "atom_sse_attr" "prefetch")
17421 (set (attr "length_address")
17422 (symbol_ref "memory_address_length (operands[0])"))
17423 (set_attr "memory" "none")])
17425 (define_insn "*prefetch_3dnow_<mode>"
17426 [(prefetch (match_operand:P 0 "address_operand" "p")
17427 (match_operand:SI 1 "const_int_operand" "n")
17431 if (INTVAL (operands[1]) == 0)
17432 return "prefetch\t%a0";
17434 return "prefetchw\t%a0";
17436 [(set_attr "type" "mmx")
17437 (set (attr "length_address")
17438 (symbol_ref "memory_address_length (operands[0])"))
17439 (set_attr "memory" "none")])
17441 (define_expand "stack_protect_set"
17442 [(match_operand 0 "memory_operand" "")
17443 (match_operand 1 "memory_operand" "")]
17446 rtx (*insn)(rtx, rtx);
17448 #ifdef TARGET_THREAD_SSP_OFFSET
17449 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17450 insn = (TARGET_64BIT
17451 ? gen_stack_tls_protect_set_di
17452 : gen_stack_tls_protect_set_si);
17454 insn = (TARGET_64BIT
17455 ? gen_stack_protect_set_di
17456 : gen_stack_protect_set_si);
17459 emit_insn (insn (operands[0], operands[1]));
17463 (define_insn "stack_protect_set_<mode>"
17464 [(set (match_operand:P 0 "memory_operand" "=m")
17465 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17466 (set (match_scratch:P 2 "=&r") (const_int 0))
17467 (clobber (reg:CC FLAGS_REG))]
17469 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17470 [(set_attr "type" "multi")])
17472 (define_insn "stack_tls_protect_set_<mode>"
17473 [(set (match_operand:P 0 "memory_operand" "=m")
17474 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17475 UNSPEC_SP_TLS_SET))
17476 (set (match_scratch:P 2 "=&r") (const_int 0))
17477 (clobber (reg:CC FLAGS_REG))]
17479 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17480 [(set_attr "type" "multi")])
17482 (define_expand "stack_protect_test"
17483 [(match_operand 0 "memory_operand" "")
17484 (match_operand 1 "memory_operand" "")
17485 (match_operand 2 "" "")]
17488 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17490 rtx (*insn)(rtx, rtx, rtx);
17492 #ifdef TARGET_THREAD_SSP_OFFSET
17493 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17494 insn = (TARGET_64BIT
17495 ? gen_stack_tls_protect_test_di
17496 : gen_stack_tls_protect_test_si);
17498 insn = (TARGET_64BIT
17499 ? gen_stack_protect_test_di
17500 : gen_stack_protect_test_si);
17503 emit_insn (insn (flags, operands[0], operands[1]));
17505 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17506 flags, const0_rtx, operands[2]));
17510 (define_insn "stack_protect_test_<mode>"
17511 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17512 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17513 (match_operand:P 2 "memory_operand" "m")]
17515 (clobber (match_scratch:P 3 "=&r"))]
17517 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17518 [(set_attr "type" "multi")])
17520 (define_insn "stack_tls_protect_test_<mode>"
17521 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17522 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17523 (match_operand:P 2 "const_int_operand" "i")]
17524 UNSPEC_SP_TLS_TEST))
17525 (clobber (match_scratch:P 3 "=r"))]
17527 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17528 [(set_attr "type" "multi")])
17530 (define_insn "sse4_2_crc32<mode>"
17531 [(set (match_operand:SI 0 "register_operand" "=r")
17533 [(match_operand:SI 1 "register_operand" "0")
17534 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17536 "TARGET_SSE4_2 || TARGET_CRC32"
17537 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17538 [(set_attr "type" "sselog1")
17539 (set_attr "prefix_rep" "1")
17540 (set_attr "prefix_extra" "1")
17541 (set (attr "prefix_data16")
17542 (if_then_else (match_operand:HI 2 "" "")
17544 (const_string "*")))
17545 (set (attr "prefix_rex")
17546 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17548 (const_string "*")))
17549 (set_attr "mode" "SI")])
17551 (define_insn "sse4_2_crc32di"
17552 [(set (match_operand:DI 0 "register_operand" "=r")
17554 [(match_operand:DI 1 "register_operand" "0")
17555 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17557 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17558 "crc32{q}\t{%2, %0|%0, %2}"
17559 [(set_attr "type" "sselog1")
17560 (set_attr "prefix_rep" "1")
17561 (set_attr "prefix_extra" "1")
17562 (set_attr "mode" "DI")])
17564 (define_expand "rdpmc"
17565 [(match_operand:DI 0 "register_operand" "")
17566 (match_operand:SI 1 "register_operand" "")]
17569 rtx reg = gen_reg_rtx (DImode);
17572 /* Force operand 1 into ECX. */
17573 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17574 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17575 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17580 rtvec vec = rtvec_alloc (2);
17581 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17582 rtx upper = gen_reg_rtx (DImode);
17583 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17584 gen_rtvec (1, const0_rtx),
17586 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17587 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17589 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17590 NULL, 1, OPTAB_DIRECT);
17591 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17595 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17596 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17600 (define_insn "*rdpmc"
17601 [(set (match_operand:DI 0 "register_operand" "=A")
17602 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17606 [(set_attr "type" "other")
17607 (set_attr "length" "2")])
17609 (define_insn "*rdpmc_rex64"
17610 [(set (match_operand:DI 0 "register_operand" "=a")
17611 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17613 (set (match_operand:DI 1 "register_operand" "=d")
17614 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17617 [(set_attr "type" "other")
17618 (set_attr "length" "2")])
17620 (define_expand "rdtsc"
17621 [(set (match_operand:DI 0 "register_operand" "")
17622 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17627 rtvec vec = rtvec_alloc (2);
17628 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17629 rtx upper = gen_reg_rtx (DImode);
17630 rtx lower = gen_reg_rtx (DImode);
17631 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17632 gen_rtvec (1, const0_rtx),
17634 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17635 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17637 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17638 NULL, 1, OPTAB_DIRECT);
17639 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17641 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17646 (define_insn "*rdtsc"
17647 [(set (match_operand:DI 0 "register_operand" "=A")
17648 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17651 [(set_attr "type" "other")
17652 (set_attr "length" "2")])
17654 (define_insn "*rdtsc_rex64"
17655 [(set (match_operand:DI 0 "register_operand" "=a")
17656 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17657 (set (match_operand:DI 1 "register_operand" "=d")
17658 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17661 [(set_attr "type" "other")
17662 (set_attr "length" "2")])
17664 (define_expand "rdtscp"
17665 [(match_operand:DI 0 "register_operand" "")
17666 (match_operand:SI 1 "memory_operand" "")]
17669 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17670 gen_rtvec (1, const0_rtx),
17672 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17673 gen_rtvec (1, const0_rtx),
17675 rtx reg = gen_reg_rtx (DImode);
17676 rtx tmp = gen_reg_rtx (SImode);
17680 rtvec vec = rtvec_alloc (3);
17681 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17682 rtx upper = gen_reg_rtx (DImode);
17683 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17684 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17685 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17687 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17688 NULL, 1, OPTAB_DIRECT);
17689 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17694 rtvec vec = rtvec_alloc (2);
17695 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17696 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17697 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17700 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17701 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17705 (define_insn "*rdtscp"
17706 [(set (match_operand:DI 0 "register_operand" "=A")
17707 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17708 (set (match_operand:SI 1 "register_operand" "=c")
17709 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17712 [(set_attr "type" "other")
17713 (set_attr "length" "3")])
17715 (define_insn "*rdtscp_rex64"
17716 [(set (match_operand:DI 0 "register_operand" "=a")
17717 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17718 (set (match_operand:DI 1 "register_operand" "=d")
17719 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17720 (set (match_operand:SI 2 "register_operand" "=c")
17721 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17724 [(set_attr "type" "other")
17725 (set_attr "length" "3")])
17727 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17729 ;; LWP instructions
17731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17733 (define_expand "lwp_llwpcb"
17734 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17735 UNSPECV_LLWP_INTRINSIC)]
17738 (define_insn "*lwp_llwpcb<mode>1"
17739 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17740 UNSPECV_LLWP_INTRINSIC)]
17743 [(set_attr "type" "lwp")
17744 (set_attr "mode" "<MODE>")
17745 (set_attr "length" "5")])
17747 (define_expand "lwp_slwpcb"
17748 [(set (match_operand 0 "register_operand" "=r")
17749 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17754 insn = (TARGET_64BIT
17756 : gen_lwp_slwpcbsi);
17758 emit_insn (insn (operands[0]));
17762 (define_insn "lwp_slwpcb<mode>"
17763 [(set (match_operand:P 0 "register_operand" "=r")
17764 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17767 [(set_attr "type" "lwp")
17768 (set_attr "mode" "<MODE>")
17769 (set_attr "length" "5")])
17771 (define_expand "lwp_lwpval<mode>3"
17772 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17773 (match_operand:SI 2 "nonimmediate_operand" "rm")
17774 (match_operand:SI 3 "const_int_operand" "i")]
17775 UNSPECV_LWPVAL_INTRINSIC)]
17777 "/* Avoid unused variable warning. */
17780 (define_insn "*lwp_lwpval<mode>3_1"
17781 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17782 (match_operand:SI 1 "nonimmediate_operand" "rm")
17783 (match_operand:SI 2 "const_int_operand" "i")]
17784 UNSPECV_LWPVAL_INTRINSIC)]
17786 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17787 [(set_attr "type" "lwp")
17788 (set_attr "mode" "<MODE>")
17789 (set (attr "length")
17790 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17792 (define_expand "lwp_lwpins<mode>3"
17793 [(set (reg:CCC FLAGS_REG)
17794 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17795 (match_operand:SI 2 "nonimmediate_operand" "rm")
17796 (match_operand:SI 3 "const_int_operand" "i")]
17797 UNSPECV_LWPINS_INTRINSIC))
17798 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17799 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17802 (define_insn "*lwp_lwpins<mode>3_1"
17803 [(set (reg:CCC FLAGS_REG)
17804 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17805 (match_operand:SI 1 "nonimmediate_operand" "rm")
17806 (match_operand:SI 2 "const_int_operand" "i")]
17807 UNSPECV_LWPINS_INTRINSIC))]
17809 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17810 [(set_attr "type" "lwp")
17811 (set_attr "mode" "<MODE>")
17812 (set (attr "length")
17813 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17815 (define_insn "rdfsbase<mode>"
17816 [(set (match_operand:SWI48 0 "register_operand" "=r")
17817 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17818 "TARGET_64BIT && TARGET_FSGSBASE"
17820 [(set_attr "type" "other")
17821 (set_attr "prefix_extra" "2")])
17823 (define_insn "rdgsbase<mode>"
17824 [(set (match_operand:SWI48 0 "register_operand" "=r")
17825 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17826 "TARGET_64BIT && TARGET_FSGSBASE"
17828 [(set_attr "type" "other")
17829 (set_attr "prefix_extra" "2")])
17831 (define_insn "wrfsbase<mode>"
17832 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17834 "TARGET_64BIT && TARGET_FSGSBASE"
17836 [(set_attr "type" "other")
17837 (set_attr "prefix_extra" "2")])
17839 (define_insn "wrgsbase<mode>"
17840 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17842 "TARGET_64BIT && TARGET_FSGSBASE"
17844 [(set_attr "type" "other")
17845 (set_attr "prefix_extra" "2")])
17847 (define_insn "rdrand<mode>_1"
17848 [(set (match_operand:SWI248 0 "register_operand" "=r")
17849 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17850 (set (reg:CCC FLAGS_REG)
17851 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17854 [(set_attr "type" "other")
17855 (set_attr "prefix_extra" "1")])
17857 (define_expand "pause"
17858 [(set (match_dup 0)
17859 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17862 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17863 MEM_VOLATILE_P (operands[0]) = 1;
17866 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17867 ;; They have the same encoding.
17868 (define_insn "*pause"
17869 [(set (match_operand:BLK 0 "" "")
17870 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17873 [(set_attr "length" "2")
17874 (set_attr "memory" "unknown")])
17878 (include "sync.md")