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,bdver2,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 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "x86_64_general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "x86_64_szext_general_operand")
888 (DI "x86_64_szext_general_operand")])
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "x86_64_immediate_operand")
895 (DI "x86_64_immediate_operand")])
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "x86_64_nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
940 ;; SSE vector suffix for floating point modes
941 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943 ;; SSE vector mode corresponding to a scalar mode
944 (define_mode_attr ssevecmode
945 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947 ;; Instruction suffix for REX 64bit operators.
948 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950 ;; This mode iterator allows :P to be used for patterns that operate on
951 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
952 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954 ;; This mode iterator allows :PTR to be used for patterns that operate on
955 ;; ptr_mode sized quantities.
956 (define_mode_iterator PTR
957 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
959 ;; Scheduling descriptions
961 (include "pentium.md")
964 (include "athlon.md")
965 (include "bdver1.md")
971 ;; Operand and operator predicates and constraints
973 (include "predicates.md")
974 (include "constraints.md")
977 ;; Compare and branch/compare and store instructions.
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1053 (match_operand:QI 0 "general_operand" "Qm")
1056 (match_operand 1 "ext_register_operand" "Q")
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1067 (match_operand:QI 0 "register_operand" "Q")
1070 (match_operand 1 "ext_register_operand" "Q")
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "")
1101 (match_operand:QI 1 "immediate_operand" "")))])
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1108 (match_operand 0 "ext_register_operand" "Q")
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1123 (match_operand 0 "ext_register_operand" "Q")
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1138 (match_operand 0 "ext_register_operand" "Q")
1143 (match_operand 1 "ext_register_operand" "Q")
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1196 (label_ref (match_operand 3 "" ""))
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, false, false);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286 "&& reload_completed"
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1312 "* return output_fp_compare (insn, operands, false, false);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1346 "* return output_fp_compare (insn, operands, false, false);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 && TARGET_SAHF && !TARGET_CMOVE"
1360 "&& reload_completed"
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, false, true);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1 "" "")
1387 (match_operand:DF 1 "" "")
1390 (const_string "XF")))])
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1402 "&& reload_completed"
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1413 (cond [(match_operand:SF 1 "" "")
1415 (match_operand:DF 1 "" "")
1418 (const_string "XF")))])
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, false, false);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:SWI24 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "&& reload_completed"
1454 (match_op_dup 3 [(match_dup 2)]))]
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1485 #ifndef HAVE_AS_IX86_SAHF
1487 return ASM_BYTE "0x9e";
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, true, false);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1511 (if_then_else (match_operand:SF 1 "" "")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1521 (eq_attr "mode" "DF")
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, true, false);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1540 (if_then_else (match_operand:SF 1 "" "")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, true, false);"
1561 [(set_attr "type" "fcmp")
1563 (cond [(match_operand:SF 1 "" "")
1565 (match_operand:DF 1 "" "")
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, true);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1584 (if_then_else (match_operand:SF 1 "" "")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1594 (eq_attr "mode" "DF")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, true, true);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1613 (if_then_else (match_operand:SF 1 "" "")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, true, true);"
1634 [(set_attr "type" "fcmp")
1636 (cond [(match_operand:SF 1 "" "")
1638 (match_operand:DF 1 "" "")
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1646 ;; Push/pop instructions.
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1653 [(set_attr "type" "multi")
1654 (set_attr "mode" "<MODE>")])
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 ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1985 (match_operand:DI 1 "general_operand"
1986 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*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" "4")
2037 (const_string "multi")
2038 (eq_attr "alternative" "5")
2039 (const_string "mmx")
2040 (eq_attr "alternative" "6,7,8,9")
2041 (const_string "mmxmov")
2042 (eq_attr "alternative" "10")
2043 (const_string "sselog1")
2044 (eq_attr "alternative" "11,12,13,14,15")
2045 (const_string "ssemov")
2046 (eq_attr "alternative" "16,17")
2047 (const_string "ssecvt")
2048 (match_operand 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" "8,9")
2065 (const_string "*")))
2066 (set (attr "prefix_data16")
2067 (if_then_else (eq_attr "alternative" "11")
2069 (const_string "*")))
2070 (set (attr "prefix")
2071 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2072 (const_string "maybe_vex")
2073 (const_string "orig")))
2074 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2076 ;; Reload patterns to support multi-word load/store
2077 ;; with non-offsetable address.
2078 (define_expand "reload_noff_store"
2079 [(parallel [(match_operand 0 "memory_operand" "=m")
2080 (match_operand 1 "register_operand" "r")
2081 (match_operand:DI 2 "register_operand" "=&r")])]
2084 rtx mem = operands[0];
2085 rtx addr = XEXP (mem, 0);
2087 emit_move_insn (operands[2], addr);
2088 mem = replace_equiv_address_nv (mem, operands[2]);
2090 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2094 (define_expand "reload_noff_load"
2095 [(parallel [(match_operand 0 "register_operand" "=r")
2096 (match_operand 1 "memory_operand" "m")
2097 (match_operand:DI 2 "register_operand" "=r")])]
2100 rtx mem = operands[1];
2101 rtx addr = XEXP (mem, 0);
2103 emit_move_insn (operands[2], addr);
2104 mem = replace_equiv_address_nv (mem, operands[2]);
2106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, move by 32bit parts.
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "memory_operand" "")
2116 (match_operand:DI 1 "immediate_operand" ""))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))])
2122 ;; We need to define this as both peepholer and splitter for case
2123 ;; peephole2 pass is not run.
2124 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 [(set (match_operand:DI 0 "memory_operand" "")
2127 (match_operand:DI 1 "immediate_operand" ""))]
2128 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2130 [(set (match_dup 2) (match_dup 3))
2131 (set (match_dup 4) (match_dup 5))]
2132 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2135 [(set (match_operand:DI 0 "memory_operand" "")
2136 (match_operand:DI 1 "immediate_operand" ""))]
2137 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2138 ? epilogue_completed : reload_completed)
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2145 (define_insn "*movdi_internal"
2146 [(set (match_operand:DI 0 "nonimmediate_operand"
2147 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2148 (match_operand:DI 1 "general_operand"
2149 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2150 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2152 switch (get_attr_type (insn))
2155 if (SSE_REG_P (operands[0]))
2156 return "movq2dq\t{%1, %0|%0, %1}";
2158 return "movdq2q\t{%1, %0|%0, %1}";
2161 switch (get_attr_mode (insn))
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2166 return "%vmovq\t{%1, %0|%0, %1}";
2168 return "movaps\t{%1, %0|%0, %1}";
2170 return "movlps\t{%1, %0|%0, %1}";
2176 return "movq\t{%1, %0|%0, %1}";
2179 return standard_sse_constant_opcode (insn, operands[1]);
2182 return "pxor\t%0, %0";
2192 (if_then_else (eq_attr "alternative" "9,10,11,12")
2193 (const_string "noavx")
2194 (const_string "*")))
2196 (cond [(eq_attr "alternative" "0,1")
2197 (const_string "multi")
2198 (eq_attr "alternative" "2")
2199 (const_string "mmx")
2200 (eq_attr "alternative" "3,4")
2201 (const_string "mmxmov")
2202 (eq_attr "alternative" "5,9")
2203 (const_string "sselog1")
2204 (eq_attr "alternative" "13,14")
2205 (const_string "ssecvt")
2207 (const_string "ssemov")))
2208 (set (attr "prefix")
2209 (if_then_else (eq_attr "alternative" "5,6,7,8")
2210 (const_string "maybe_vex")
2211 (const_string "orig")))
2212 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2216 (match_operand:DI 1 "general_operand" ""))]
2217 "!TARGET_64BIT && reload_completed
2218 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2219 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2221 "ix86_split_long_move (operands); DONE;")
2223 (define_insn "*movsi_internal"
2224 [(set (match_operand:SI 0 "nonimmediate_operand"
2225 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2226 (match_operand:SI 1 "general_operand"
2227 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2228 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 switch (get_attr_type (insn))
2233 return standard_sse_constant_opcode (insn, operands[1]);
2236 switch (get_attr_mode (insn))
2239 return "%vmovdqa\t{%1, %0|%0, %1}";
2241 return "%vmovaps\t{%1, %0|%0, %1}";
2243 return "%vmovd\t{%1, %0|%0, %1}";
2245 return "%vmovss\t{%1, %0|%0, %1}";
2251 return "pxor\t%0, %0";
2254 if (get_attr_mode (insn) == MODE_DI)
2255 return "movq\t{%1, %0|%0, %1}";
2256 return "movd\t{%1, %0|%0, %1}";
2259 return "lea{l}\t{%a1, %0|%0, %a1}";
2262 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2263 return "mov{l}\t{%1, %0|%0, %1}";
2267 (cond [(eq_attr "alternative" "2")
2268 (const_string "mmx")
2269 (eq_attr "alternative" "3,4,5")
2270 (const_string "mmxmov")
2271 (eq_attr "alternative" "6")
2272 (const_string "sselog1")
2273 (eq_attr "alternative" "7,8,9,10,11")
2274 (const_string "ssemov")
2275 (match_operand 1 "pic_32bit_operand" "")
2276 (const_string "lea")
2278 (const_string "imov")))
2279 (set (attr "prefix")
2280 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2281 (const_string "orig")
2282 (const_string "maybe_vex")))
2283 (set (attr "prefix_data16")
2284 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2286 (const_string "*")))
2288 (cond [(eq_attr "alternative" "2,3")
2290 (eq_attr "alternative" "6,7")
2292 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2293 (const_string "V4SF")
2294 (const_string "TI"))
2295 (and (eq_attr "alternative" "8,9,10,11")
2296 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2299 (const_string "SI")))])
2301 (define_insn "*movhi_internal"
2302 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2303 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2304 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2306 switch (get_attr_type (insn))
2309 /* movzwl is faster than movw on p2 due to partial word stalls,
2310 though not as fast as an aligned movl. */
2311 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2313 if (get_attr_mode (insn) == MODE_SI)
2314 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2316 return "mov{w}\t{%1, %0|%0, %1}";
2320 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2322 (const_string "imov")
2323 (and (eq_attr "alternative" "0")
2324 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2326 (eq (symbol_ref "TARGET_HIMODE_MATH")
2328 (const_string "imov")
2329 (and (eq_attr "alternative" "1,2")
2330 (match_operand:HI 1 "aligned_operand" ""))
2331 (const_string "imov")
2332 (and (ne (symbol_ref "TARGET_MOVX")
2334 (eq_attr "alternative" "0,2"))
2335 (const_string "imovx")
2337 (const_string "imov")))
2339 (cond [(eq_attr "type" "imovx")
2341 (and (eq_attr "alternative" "1,2")
2342 (match_operand:HI 1 "aligned_operand" ""))
2344 (and (eq_attr "alternative" "0")
2345 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2347 (eq (symbol_ref "TARGET_HIMODE_MATH")
2351 (const_string "HI")))])
2353 ;; Situation is quite tricky about when to choose full sized (SImode) move
2354 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2355 ;; partial register dependency machines (such as AMD Athlon), where QImode
2356 ;; moves issue extra dependency and for partial register stalls machines
2357 ;; that don't use QImode patterns (and QImode move cause stall on the next
2360 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2361 ;; register stall machines with, where we use QImode instructions, since
2362 ;; partial register stall can be caused there. Then we use movzx.
2363 (define_insn "*movqi_internal"
2364 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2365 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2366 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2368 switch (get_attr_type (insn))
2371 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2372 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2374 if (get_attr_mode (insn) == MODE_SI)
2375 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2377 return "mov{b}\t{%1, %0|%0, %1}";
2381 (cond [(and (eq_attr "alternative" "5")
2382 (not (match_operand:QI 1 "aligned_operand" "")))
2383 (const_string "imovx")
2384 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2386 (const_string "imov")
2387 (and (eq_attr "alternative" "3")
2388 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2390 (eq (symbol_ref "TARGET_QIMODE_MATH")
2392 (const_string "imov")
2393 (eq_attr "alternative" "3,5")
2394 (const_string "imovx")
2395 (and (ne (symbol_ref "TARGET_MOVX")
2397 (eq_attr "alternative" "2"))
2398 (const_string "imovx")
2400 (const_string "imov")))
2402 (cond [(eq_attr "alternative" "3,4,5")
2404 (eq_attr "alternative" "6")
2406 (eq_attr "type" "imovx")
2408 (and (eq_attr "type" "imov")
2409 (and (eq_attr "alternative" "0,1")
2410 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2412 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2414 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2417 ;; Avoid partial register stalls when not using QImode arithmetic
2418 (and (eq_attr "type" "imov")
2419 (and (eq_attr "alternative" "0,1")
2420 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2422 (eq (symbol_ref "TARGET_QIMODE_MATH")
2426 (const_string "QI")))])
2428 ;; Stores and loads of ax to arbitrary constant address.
2429 ;; We fake an second form of instruction to force reload to load address
2430 ;; into register when rax is not available
2431 (define_insn "*movabs<mode>_1"
2432 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2433 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2434 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2436 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2437 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2438 [(set_attr "type" "imov")
2439 (set_attr "modrm" "0,*")
2440 (set_attr "length_address" "8,0")
2441 (set_attr "length_immediate" "0,*")
2442 (set_attr "memory" "store")
2443 (set_attr "mode" "<MODE>")])
2445 (define_insn "*movabs<mode>_2"
2446 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2447 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2448 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2450 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2451 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2452 [(set_attr "type" "imov")
2453 (set_attr "modrm" "0,*")
2454 (set_attr "length_address" "8,0")
2455 (set_attr "length_immediate" "0")
2456 (set_attr "memory" "load")
2457 (set_attr "mode" "<MODE>")])
2459 (define_insn "*swap<mode>"
2460 [(set (match_operand:SWI48 0 "register_operand" "+r")
2461 (match_operand:SWI48 1 "register_operand" "+r"))
2465 "xchg{<imodesuffix>}\t%1, %0"
2466 [(set_attr "type" "imov")
2467 (set_attr "mode" "<MODE>")
2468 (set_attr "pent_pair" "np")
2469 (set_attr "athlon_decode" "vector")
2470 (set_attr "amdfam10_decode" "double")
2471 (set_attr "bdver1_decode" "double")])
2473 (define_insn "*swap<mode>_1"
2474 [(set (match_operand:SWI12 0 "register_operand" "+r")
2475 (match_operand:SWI12 1 "register_operand" "+r"))
2478 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2480 [(set_attr "type" "imov")
2481 (set_attr "mode" "SI")
2482 (set_attr "pent_pair" "np")
2483 (set_attr "athlon_decode" "vector")
2484 (set_attr "amdfam10_decode" "double")
2485 (set_attr "bdver1_decode" "double")])
2487 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2488 ;; is disabled for AMDFAM10
2489 (define_insn "*swap<mode>_2"
2490 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2491 (match_operand:SWI12 1 "register_operand" "+<r>"))
2494 "TARGET_PARTIAL_REG_STALL"
2495 "xchg{<imodesuffix>}\t%1, %0"
2496 [(set_attr "type" "imov")
2497 (set_attr "mode" "<MODE>")
2498 (set_attr "pent_pair" "np")
2499 (set_attr "athlon_decode" "vector")])
2501 (define_expand "movstrict<mode>"
2502 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2503 (match_operand:SWI12 1 "general_operand" ""))]
2506 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2508 if (GET_CODE (operands[0]) == SUBREG
2509 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2511 /* Don't generate memory->memory moves, go through a register */
2512 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2513 operands[1] = force_reg (<MODE>mode, operands[1]);
2516 (define_insn "*movstrict<mode>_1"
2517 [(set (strict_low_part
2518 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2519 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2520 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2521 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2522 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2523 [(set_attr "type" "imov")
2524 (set_attr "mode" "<MODE>")])
2526 (define_insn "*movstrict<mode>_xor"
2527 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2528 (match_operand:SWI12 1 "const0_operand" ""))
2529 (clobber (reg:CC FLAGS_REG))]
2531 "xor{<imodesuffix>}\t%0, %0"
2532 [(set_attr "type" "alu1")
2533 (set_attr "mode" "<MODE>")
2534 (set_attr "length_immediate" "0")])
2536 (define_insn "*mov<mode>_extv_1"
2537 [(set (match_operand:SWI24 0 "register_operand" "=R")
2538 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2542 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2543 [(set_attr "type" "imovx")
2544 (set_attr "mode" "SI")])
2546 (define_insn "*movqi_extv_1_rex64"
2547 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2548 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2553 switch (get_attr_type (insn))
2556 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2558 return "mov{b}\t{%h1, %0|%0, %h1}";
2562 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2563 (ne (symbol_ref "TARGET_MOVX")
2565 (const_string "imovx")
2566 (const_string "imov")))
2568 (if_then_else (eq_attr "type" "imovx")
2570 (const_string "QI")))])
2572 (define_insn "*movqi_extv_1"
2573 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2574 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2579 switch (get_attr_type (insn))
2582 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2584 return "mov{b}\t{%h1, %0|%0, %h1}";
2588 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2589 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2590 (ne (symbol_ref "TARGET_MOVX")
2592 (const_string "imovx")
2593 (const_string "imov")))
2595 (if_then_else (eq_attr "type" "imovx")
2597 (const_string "QI")))])
2599 (define_insn "*mov<mode>_extzv_1"
2600 [(set (match_operand:SWI48 0 "register_operand" "=R")
2601 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2605 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2606 [(set_attr "type" "imovx")
2607 (set_attr "mode" "SI")])
2609 (define_insn "*movqi_extzv_2_rex64"
2610 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2612 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2617 switch (get_attr_type (insn))
2620 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2622 return "mov{b}\t{%h1, %0|%0, %h1}";
2626 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2627 (ne (symbol_ref "TARGET_MOVX")
2629 (const_string "imovx")
2630 (const_string "imov")))
2632 (if_then_else (eq_attr "type" "imovx")
2634 (const_string "QI")))])
2636 (define_insn "*movqi_extzv_2"
2637 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2639 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2644 switch (get_attr_type (insn))
2647 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2649 return "mov{b}\t{%h1, %0|%0, %h1}";
2653 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2654 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2655 (ne (symbol_ref "TARGET_MOVX")
2657 (const_string "imovx")
2658 (const_string "imov")))
2660 (if_then_else (eq_attr "type" "imovx")
2662 (const_string "QI")))])
2664 (define_expand "mov<mode>_insv_1"
2665 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2668 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2670 (define_insn "*mov<mode>_insv_1_rex64"
2671 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2674 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2676 "mov{b}\t{%b1, %h0|%h0, %b1}"
2677 [(set_attr "type" "imov")
2678 (set_attr "mode" "QI")])
2680 (define_insn "*movsi_insv_1"
2681 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2684 (match_operand:SI 1 "general_operand" "Qmn"))]
2686 "mov{b}\t{%b1, %h0|%h0, %b1}"
2687 [(set_attr "type" "imov")
2688 (set_attr "mode" "QI")])
2690 (define_insn "*movqi_insv_2"
2691 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2694 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2697 "mov{b}\t{%h1, %h0|%h0, %h1}"
2698 [(set_attr "type" "imov")
2699 (set_attr "mode" "QI")])
2701 ;; Floating point push instructions.
2703 (define_insn "*pushtf"
2704 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2705 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2708 /* This insn should be already split before reg-stack. */
2711 [(set_attr "type" "multi")
2712 (set_attr "unit" "sse,*,*")
2713 (set_attr "mode" "TF,SI,SI")])
2715 ;; %%% Kill this when call knows how to work this out.
2717 [(set (match_operand:TF 0 "push_operand" "")
2718 (match_operand:TF 1 "sse_reg_operand" ""))]
2719 "TARGET_SSE2 && reload_completed"
2720 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2721 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2723 (define_insn "*pushxf"
2724 [(set (match_operand:XF 0 "push_operand" "=<,<")
2725 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2726 "optimize_function_for_speed_p (cfun)"
2728 /* This insn should be already split before reg-stack. */
2731 [(set_attr "type" "multi")
2732 (set_attr "unit" "i387,*")
2733 (set_attr "mode" "XF,SI")])
2735 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2736 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2737 ;; Pushing using integer instructions is longer except for constants
2738 ;; and direct memory references (assuming that any given constant is pushed
2739 ;; only once, but this ought to be handled elsewhere).
2741 (define_insn "*pushxf_nointeger"
2742 [(set (match_operand:XF 0 "push_operand" "=<,<")
2743 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2744 "optimize_function_for_size_p (cfun)"
2746 /* This insn should be already split before reg-stack. */
2749 [(set_attr "type" "multi")
2750 (set_attr "unit" "i387,*")
2751 (set_attr "mode" "XF,SI")])
2753 ;; %%% Kill this when call knows how to work this out.
2755 [(set (match_operand:XF 0 "push_operand" "")
2756 (match_operand:XF 1 "fp_register_operand" ""))]
2758 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2759 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2760 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2762 (define_insn "*pushdf_rex64"
2763 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2764 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
2767 /* This insn should be already split before reg-stack. */
2770 [(set_attr "type" "multi")
2771 (set_attr "unit" "i387,*,*")
2772 (set_attr "mode" "DF,DI,DF")])
2774 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2775 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2776 ;; On the average, pushdf using integers can be still shorter.
2778 (define_insn "*pushdf"
2779 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2780 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2783 /* This insn should be already split before reg-stack. */
2786 [(set_attr "type" "multi")
2787 (set_attr "unit" "i387,*,*")
2788 (set_attr "mode" "DF,DI,DF")])
2790 ;; %%% Kill this when call knows how to work this out.
2792 [(set (match_operand:DF 0 "push_operand" "")
2793 (match_operand:DF 1 "any_fp_register_operand" ""))]
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2796 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2798 (define_insn "*pushsf_rex64"
2799 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2800 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2803 /* Anything else should be already split before reg-stack. */
2804 gcc_assert (which_alternative == 1);
2805 return "push{q}\t%q1";
2807 [(set_attr "type" "multi,push,multi")
2808 (set_attr "unit" "i387,*,*")
2809 (set_attr "mode" "SF,DI,SF")])
2811 (define_insn "*pushsf"
2812 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2813 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2816 /* Anything else should be already split before reg-stack. */
2817 gcc_assert (which_alternative == 1);
2818 return "push{l}\t%1";
2820 [(set_attr "type" "multi,push,multi")
2821 (set_attr "unit" "i387,*,*")
2822 (set_attr "mode" "SF,SI,SF")])
2824 ;; %%% Kill this when call knows how to work this out.
2826 [(set (match_operand:SF 0 "push_operand" "")
2827 (match_operand:SF 1 "any_fp_register_operand" ""))]
2829 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2830 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2831 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2834 [(set (match_operand:SF 0 "push_operand" "")
2835 (match_operand:SF 1 "memory_operand" ""))]
2837 && (operands[2] = find_constant_src (insn))"
2838 [(set (match_dup 0) (match_dup 2))])
2841 [(set (match_operand 0 "push_operand" "")
2842 (match_operand 1 "general_operand" ""))]
2844 && (GET_MODE (operands[0]) == TFmode
2845 || GET_MODE (operands[0]) == XFmode
2846 || GET_MODE (operands[0]) == DFmode)
2847 && !ANY_FP_REG_P (operands[1])"
2849 "ix86_split_long_move (operands); DONE;")
2851 ;; Floating point move instructions.
2853 (define_expand "movtf"
2854 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2855 (match_operand:TF 1 "nonimmediate_operand" ""))]
2858 ix86_expand_move (TFmode, operands);
2862 (define_expand "mov<mode>"
2863 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2864 (match_operand:X87MODEF 1 "general_operand" ""))]
2866 "ix86_expand_move (<MODE>mode, operands); DONE;")
2868 (define_insn "*movtf_internal"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2870 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (!can_create_pseudo_p ()
2874 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || (optimize_function_for_size_p (cfun)
2877 && standard_sse_constant_p (operands[1])
2878 && !memory_operand (operands[0], TFmode))
2879 || (!TARGET_MEMORY_MISMATCH_STALL
2880 && memory_operand (operands[0], TFmode)))"
2882 switch (which_alternative)
2886 /* Handle misaligned load/store since we
2887 don't have movmisaligntf pattern. */
2888 if (misaligned_operand (operands[0], TFmode)
2889 || misaligned_operand (operands[1], TFmode))
2891 if (get_attr_mode (insn) == MODE_V4SF)
2892 return "%vmovups\t{%1, %0|%0, %1}";
2894 return "%vmovdqu\t{%1, %0|%0, %1}";
2898 if (get_attr_mode (insn) == MODE_V4SF)
2899 return "%vmovaps\t{%1, %0|%0, %1}";
2901 return "%vmovdqa\t{%1, %0|%0, %1}";
2905 return standard_sse_constant_opcode (insn, operands[1]);
2915 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2916 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2918 (cond [(eq_attr "alternative" "0,2")
2920 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2922 (const_string "V4SF")
2923 (const_string "TI"))
2924 (eq_attr "alternative" "1")
2926 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2928 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2930 (const_string "V4SF")
2931 (const_string "TI"))]
2932 (const_string "DI")))])
2934 ;; Possible store forwarding (partial memory) stall in alternative 4.
2935 (define_insn "*movxf_internal"
2936 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2937 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2938 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2939 && (!can_create_pseudo_p ()
2940 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2941 || GET_CODE (operands[1]) != CONST_DOUBLE
2942 || (optimize_function_for_size_p (cfun)
2943 && standard_80387_constant_p (operands[1]) > 0
2944 && !memory_operand (operands[0], XFmode))
2945 || (!TARGET_MEMORY_MISMATCH_STALL
2946 && memory_operand (operands[0], XFmode)))"
2948 switch (which_alternative)
2952 return output_387_reg_move (insn, operands);
2955 return standard_80387_constant_opcode (operands[1]);
2965 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2966 (set_attr "mode" "XF,XF,XF,SI,SI")])
2968 (define_insn "*movdf_internal_rex64"
2969 [(set (match_operand:DF 0 "nonimmediate_operand"
2970 "=f,m,f,?r,?m,?r,!o,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2971 (match_operand:DF 1 "general_operand"
2972 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2973 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2974 && (!can_create_pseudo_p ()
2975 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2976 || GET_CODE (operands[1]) != CONST_DOUBLE
2977 || (optimize_function_for_size_p (cfun)
2978 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2979 && standard_80387_constant_p (operands[1]) > 0)
2980 || (TARGET_SSE2 && TARGET_SSE_MATH
2981 && standard_sse_constant_p (operands[1]))))
2982 || memory_operand (operands[0], DFmode))"
2984 switch (which_alternative)
2988 return output_387_reg_move (insn, operands);
2991 return standard_80387_constant_opcode (operands[1]);
2995 return "mov{q}\t{%1, %0|%0, %1}";
2998 return "movabs{q}\t{%1, %0|%0, %1}";
3004 return standard_sse_constant_opcode (insn, operands[1]);
3009 switch (get_attr_mode (insn))
3012 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3013 return "%vmovapd\t{%1, %0|%0, %1}";
3015 return "%vmovaps\t{%1, %0|%0, %1}";
3018 return "%vmovq\t{%1, %0|%0, %1}";
3020 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3021 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3022 return "%vmovsd\t{%1, %0|%0, %1}";
3024 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3026 return "%vmovlps\t{%1, %d0|%d0, %1}";
3033 /* Handle broken assemblers that require movd instead of movq. */
3034 return "%vmovd\t{%1, %0|%0, %1}";
3040 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3043 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3045 (const_string "*")))
3046 (set (attr "length_immediate")
3048 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3050 (const_string "*")))
3051 (set (attr "prefix")
3052 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3053 (const_string "orig")
3054 (const_string "maybe_vex")))
3055 (set (attr "prefix_data16")
3056 (if_then_else (eq_attr "mode" "V1DF")
3058 (const_string "*")))
3060 (cond [(eq_attr "alternative" "0,1,2")
3062 (eq_attr "alternative" "3,4,5,6,11,12")
3065 /* xorps is one byte shorter. */
3066 (eq_attr "alternative" "7")
3067 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3069 (const_string "V4SF")
3070 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3074 (const_string "V2DF"))
3076 /* For architectures resolving dependencies on
3077 whole SSE registers use APD move to break dependency
3078 chains, otherwise use short move to avoid extra work.
3080 movaps encodes one byte shorter. */
3081 (eq_attr "alternative" "8")
3083 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3085 (const_string "V4SF")
3086 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3088 (const_string "V2DF")
3090 (const_string "DF"))
3091 /* For architectures resolving dependencies on register
3092 parts we may avoid extra work to zero out upper part
3094 (eq_attr "alternative" "9")
3096 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3098 (const_string "V1DF")
3099 (const_string "DF"))
3101 (const_string "DF")))])
3103 ;; Possible store forwarding (partial memory) stall in alternative 4.
3104 (define_insn "*movdf_internal"
3105 [(set (match_operand:DF 0 "nonimmediate_operand"
3106 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3107 (match_operand:DF 1 "general_operand"
3108 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3109 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3110 && (!can_create_pseudo_p ()
3111 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3112 || GET_CODE (operands[1]) != CONST_DOUBLE
3113 || (optimize_function_for_size_p (cfun)
3114 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3115 && standard_80387_constant_p (operands[1]) > 0)
3116 || (TARGET_SSE2 && TARGET_SSE_MATH
3117 && standard_sse_constant_p (operands[1])))
3118 && !memory_operand (operands[0], DFmode))
3119 || (!TARGET_MEMORY_MISMATCH_STALL
3120 && memory_operand (operands[0], DFmode)))"
3122 switch (which_alternative)
3126 return output_387_reg_move (insn, operands);
3129 return standard_80387_constant_opcode (operands[1]);
3136 return standard_sse_constant_opcode (insn, operands[1]);
3141 switch (get_attr_mode (insn))
3144 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3145 return "%vmovapd\t{%1, %0|%0, %1}";
3147 return "%vmovaps\t{%1, %0|%0, %1}";
3150 return "%vmovq\t{%1, %0|%0, %1}";
3152 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3153 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3154 return "%vmovsd\t{%1, %0|%0, %1}";
3156 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3158 return "%vmovlps\t{%1, %d0|%d0, %1}";
3167 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3168 (set (attr "prefix")
3169 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3170 (const_string "orig")
3171 (const_string "maybe_vex")))
3172 (set (attr "prefix_data16")
3173 (if_then_else (eq_attr "mode" "V1DF")
3175 (const_string "*")))
3177 (cond [(eq_attr "alternative" "0,1,2")
3179 (eq_attr "alternative" "3,4")
3182 /* For SSE1, we have many fewer alternatives. */
3183 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3185 (eq_attr "alternative" "5,6")
3186 (const_string "V4SF")
3187 (const_string "V2SF"))
3189 /* xorps is one byte shorter. */
3190 (eq_attr "alternative" "5")
3191 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3193 (const_string "V4SF")
3194 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3198 (const_string "V2DF"))
3200 /* For architectures resolving dependencies on
3201 whole SSE registers use APD move to break dependency
3202 chains, otherwise use short move to avoid extra work.
3204 movaps encodes one byte shorter. */
3205 (eq_attr "alternative" "6")
3207 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3209 (const_string "V4SF")
3210 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3212 (const_string "V2DF")
3214 (const_string "DF"))
3215 /* For architectures resolving dependencies on register
3216 parts we may avoid extra work to zero out upper part
3218 (eq_attr "alternative" "7")
3220 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3222 (const_string "V1DF")
3223 (const_string "DF"))
3225 (const_string "DF")))])
3227 (define_insn "*movsf_internal"
3228 [(set (match_operand:SF 0 "nonimmediate_operand"
3229 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3230 (match_operand:SF 1 "general_operand"
3231 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3232 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3233 && (!can_create_pseudo_p ()
3234 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3235 || GET_CODE (operands[1]) != CONST_DOUBLE
3236 || (optimize_function_for_size_p (cfun)
3237 && ((!TARGET_SSE_MATH
3238 && standard_80387_constant_p (operands[1]) > 0)
3240 && standard_sse_constant_p (operands[1]))))
3241 || memory_operand (operands[0], SFmode))"
3243 switch (which_alternative)
3247 return output_387_reg_move (insn, operands);
3250 return standard_80387_constant_opcode (operands[1]);
3254 return "mov{l}\t{%1, %0|%0, %1}";
3257 return standard_sse_constant_opcode (insn, operands[1]);
3260 if (get_attr_mode (insn) == MODE_V4SF)
3261 return "%vmovaps\t{%1, %0|%0, %1}";
3263 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3267 return "%vmovss\t{%1, %0|%0, %1}";
3273 return "movd\t{%1, %0|%0, %1}";
3276 return "movq\t{%1, %0|%0, %1}";
3280 return "%vmovd\t{%1, %0|%0, %1}";
3286 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3287 (set (attr "prefix")
3288 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3289 (const_string "maybe_vex")
3290 (const_string "orig")))
3292 (cond [(eq_attr "alternative" "3,4,9,10")
3294 (eq_attr "alternative" "5")
3296 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3298 (ne (symbol_ref "TARGET_SSE2")
3300 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3303 (const_string "V4SF"))
3304 /* For architectures resolving dependencies on
3305 whole SSE registers use APS move to break dependency
3306 chains, otherwise use short move to avoid extra work.
3308 Do the same for architectures resolving dependencies on
3309 the parts. While in DF mode it is better to always handle
3310 just register parts, the SF mode is different due to lack
3311 of instructions to load just part of the register. It is
3312 better to maintain the whole registers in single format
3313 to avoid problems on using packed logical operations. */
3314 (eq_attr "alternative" "6")
3316 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3318 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3320 (const_string "V4SF")
3321 (const_string "SF"))
3322 (eq_attr "alternative" "11")
3323 (const_string "DI")]
3324 (const_string "SF")))])
3327 [(set (match_operand 0 "any_fp_register_operand" "")
3328 (match_operand 1 "memory_operand" ""))]
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode
3333 || GET_MODE (operands[0]) == SFmode)
3334 && (operands[2] = find_constant_src (insn))"
3335 [(set (match_dup 0) (match_dup 2))]
3337 rtx c = operands[2];
3338 int r = REGNO (operands[0]);
3340 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3341 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3346 [(set (match_operand 0 "any_fp_register_operand" "")
3347 (float_extend (match_operand 1 "memory_operand" "")))]
3349 && (GET_MODE (operands[0]) == TFmode
3350 || GET_MODE (operands[0]) == XFmode
3351 || GET_MODE (operands[0]) == DFmode)
3352 && (operands[2] = find_constant_src (insn))"
3353 [(set (match_dup 0) (match_dup 2))]
3355 rtx c = operands[2];
3356 int r = REGNO (operands[0]);
3358 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3359 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3363 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3365 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3366 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3368 && (standard_80387_constant_p (operands[1]) == 8
3369 || standard_80387_constant_p (operands[1]) == 9)"
3370 [(set (match_dup 0)(match_dup 1))
3372 (neg:X87MODEF (match_dup 0)))]
3376 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3377 if (real_isnegzero (&r))
3378 operands[1] = CONST0_RTX (<MODE>mode);
3380 operands[1] = CONST1_RTX (<MODE>mode);
3384 [(set (match_operand 0 "nonimmediate_operand" "")
3385 (match_operand 1 "general_operand" ""))]
3387 && (GET_MODE (operands[0]) == TFmode
3388 || GET_MODE (operands[0]) == XFmode
3389 || GET_MODE (operands[0]) == DFmode)
3390 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3392 "ix86_split_long_move (operands); DONE;")
3394 (define_insn "swapxf"
3395 [(set (match_operand:XF 0 "register_operand" "+f")
3396 (match_operand:XF 1 "register_operand" "+f"))
3401 if (STACK_TOP_P (operands[0]))
3406 [(set_attr "type" "fxch")
3407 (set_attr "mode" "XF")])
3409 (define_insn "*swap<mode>"
3410 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3411 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3414 "TARGET_80387 || reload_completed"
3416 if (STACK_TOP_P (operands[0]))
3421 [(set_attr "type" "fxch")
3422 (set_attr "mode" "<MODE>")])
3424 ;; Zero extension instructions
3426 (define_expand "zero_extendsidi2"
3427 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3428 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3433 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3438 (define_insn "*zero_extendsidi2_rex64"
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3441 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3444 mov\t{%k1, %k0|%k0, %k1}
3446 movd\t{%1, %0|%0, %1}
3447 movd\t{%1, %0|%0, %1}
3448 %vmovd\t{%1, %0|%0, %1}
3449 %vmovd\t{%1, %0|%0, %1}"
3450 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3451 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3452 (set_attr "prefix_0f" "0,*,*,*,*,*")
3453 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3456 [(set (match_operand:DI 0 "memory_operand" "")
3457 (zero_extend:DI (match_dup 0)))]
3459 [(set (match_dup 4) (const_int 0))]
3460 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3462 ;; %%% Kill me once multi-word ops are sane.
3463 (define_insn "zero_extendsidi2_1"
3464 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3466 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3467 (clobber (reg:CC FLAGS_REG))]
3473 movd\t{%1, %0|%0, %1}
3474 movd\t{%1, %0|%0, %1}
3475 %vmovd\t{%1, %0|%0, %1}
3476 %vmovd\t{%1, %0|%0, %1}"
3477 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3478 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3479 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3482 [(set (match_operand:DI 0 "register_operand" "")
3483 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3484 (clobber (reg:CC FLAGS_REG))]
3485 "!TARGET_64BIT && reload_completed
3486 && true_regnum (operands[0]) == true_regnum (operands[1])"
3487 [(set (match_dup 4) (const_int 0))]
3488 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3491 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3492 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "!TARGET_64BIT && reload_completed
3495 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3496 [(set (match_dup 3) (match_dup 1))
3497 (set (match_dup 4) (const_int 0))]
3498 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3500 (define_insn "zero_extend<mode>di2"
3501 [(set (match_operand:DI 0 "register_operand" "=r")
3503 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3505 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3506 [(set_attr "type" "imovx")
3507 (set_attr "mode" "SI")])
3509 (define_expand "zero_extendhisi2"
3510 [(set (match_operand:SI 0 "register_operand" "")
3511 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3514 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3516 operands[1] = force_reg (HImode, operands[1]);
3517 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3522 (define_insn_and_split "zero_extendhisi2_and"
3523 [(set (match_operand:SI 0 "register_operand" "=r")
3524 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3525 (clobber (reg:CC FLAGS_REG))]
3526 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3528 "&& reload_completed"
3529 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3530 (clobber (reg:CC FLAGS_REG))])]
3532 [(set_attr "type" "alu1")
3533 (set_attr "mode" "SI")])
3535 (define_insn "*zero_extendhisi2_movzwl"
3536 [(set (match_operand:SI 0 "register_operand" "=r")
3537 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3538 "!TARGET_ZERO_EXTEND_WITH_AND
3539 || optimize_function_for_size_p (cfun)"
3540 "movz{wl|x}\t{%1, %0|%0, %1}"
3541 [(set_attr "type" "imovx")
3542 (set_attr "mode" "SI")])
3544 (define_expand "zero_extendqi<mode>2"
3546 [(set (match_operand:SWI24 0 "register_operand" "")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))])])
3550 (define_insn "*zero_extendqi<mode>2_and"
3551 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3552 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3553 (clobber (reg:CC FLAGS_REG))]
3554 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3556 [(set_attr "type" "alu1")
3557 (set_attr "mode" "<MODE>")])
3559 ;; When source and destination does not overlap, clear destination
3560 ;; first and then do the movb
3562 [(set (match_operand:SWI24 0 "register_operand" "")
3563 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3564 (clobber (reg:CC FLAGS_REG))]
3566 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3567 && ANY_QI_REG_P (operands[0])
3568 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3569 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3570 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3572 operands[2] = gen_lowpart (QImode, operands[0]);
3573 ix86_expand_clear (operands[0]);
3576 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3577 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3578 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3579 (clobber (reg:CC FLAGS_REG))]
3580 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3582 [(set_attr "type" "imovx,alu1")
3583 (set_attr "mode" "<MODE>")])
3585 ;; For the movzbl case strip only the clobber
3587 [(set (match_operand:SWI24 0 "register_operand" "")
3588 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3589 (clobber (reg:CC FLAGS_REG))]
3591 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3592 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3594 (zero_extend:SWI24 (match_dup 1)))])
3596 ; zero extend to SImode to avoid partial register stalls
3597 (define_insn "*zero_extendqi<mode>2_movzbl"
3598 [(set (match_operand:SWI24 0 "register_operand" "=r")
3599 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3601 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3602 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3603 [(set_attr "type" "imovx")
3604 (set_attr "mode" "SI")])
3606 ;; Rest is handled by single and.
3608 [(set (match_operand:SWI24 0 "register_operand" "")
3609 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3610 (clobber (reg:CC FLAGS_REG))]
3612 && true_regnum (operands[0]) == true_regnum (operands[1])"
3613 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3614 (clobber (reg:CC FLAGS_REG))])])
3616 ;; Sign extension instructions
3618 (define_expand "extendsidi2"
3619 [(set (match_operand:DI 0 "register_operand" "")
3620 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3625 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3630 (define_insn "*extendsidi2_rex64"
3631 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3632 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3636 movs{lq|x}\t{%1, %0|%0, %1}"
3637 [(set_attr "type" "imovx")
3638 (set_attr "mode" "DI")
3639 (set_attr "prefix_0f" "0")
3640 (set_attr "modrm" "0,1")])
3642 (define_insn "extendsidi2_1"
3643 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3644 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3645 (clobber (reg:CC FLAGS_REG))
3646 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3650 ;; Extend to memory case when source register does die.
3652 [(set (match_operand:DI 0 "memory_operand" "")
3653 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3654 (clobber (reg:CC FLAGS_REG))
3655 (clobber (match_operand:SI 2 "register_operand" ""))]
3657 && dead_or_set_p (insn, operands[1])
3658 && !reg_mentioned_p (operands[1], operands[0]))"
3659 [(set (match_dup 3) (match_dup 1))
3660 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3661 (clobber (reg:CC FLAGS_REG))])
3662 (set (match_dup 4) (match_dup 1))]
3663 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3665 ;; Extend to memory case when source register does not die.
3667 [(set (match_operand:DI 0 "memory_operand" "")
3668 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3669 (clobber (reg:CC FLAGS_REG))
3670 (clobber (match_operand:SI 2 "register_operand" ""))]
3674 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3676 emit_move_insn (operands[3], operands[1]);
3678 /* Generate a cltd if possible and doing so it profitable. */
3679 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3680 && true_regnum (operands[1]) == AX_REG
3681 && true_regnum (operands[2]) == DX_REG)
3683 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3687 emit_move_insn (operands[2], operands[1]);
3688 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3690 emit_move_insn (operands[4], operands[2]);
3694 ;; Extend to register case. Optimize case where source and destination
3695 ;; registers match and cases where we can use cltd.
3697 [(set (match_operand:DI 0 "register_operand" "")
3698 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3699 (clobber (reg:CC FLAGS_REG))
3700 (clobber (match_scratch:SI 2 ""))]
3704 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3706 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3707 emit_move_insn (operands[3], operands[1]);
3709 /* Generate a cltd if possible and doing so it profitable. */
3710 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3711 && true_regnum (operands[3]) == AX_REG
3712 && true_regnum (operands[4]) == DX_REG)
3714 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3718 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3719 emit_move_insn (operands[4], operands[1]);
3721 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3725 (define_insn "extend<mode>di2"
3726 [(set (match_operand:DI 0 "register_operand" "=r")
3728 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3730 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3731 [(set_attr "type" "imovx")
3732 (set_attr "mode" "DI")])
3734 (define_insn "extendhisi2"
3735 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3736 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3739 switch (get_attr_prefix_0f (insn))
3742 return "{cwtl|cwde}";
3744 return "movs{wl|x}\t{%1, %0|%0, %1}";
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "SI")
3749 (set (attr "prefix_0f")
3750 ;; movsx is short decodable while cwtl is vector decoded.
3751 (if_then_else (and (eq_attr "cpu" "!k6")
3752 (eq_attr "alternative" "0"))
3754 (const_string "1")))
3756 (if_then_else (eq_attr "prefix_0f" "0")
3758 (const_string "1")))])
3760 (define_insn "*extendhisi2_zext"
3761 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3764 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3767 switch (get_attr_prefix_0f (insn))
3770 return "{cwtl|cwde}";
3772 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3775 [(set_attr "type" "imovx")
3776 (set_attr "mode" "SI")
3777 (set (attr "prefix_0f")
3778 ;; movsx is short decodable while cwtl is vector decoded.
3779 (if_then_else (and (eq_attr "cpu" "!k6")
3780 (eq_attr "alternative" "0"))
3782 (const_string "1")))
3784 (if_then_else (eq_attr "prefix_0f" "0")
3786 (const_string "1")))])
3788 (define_insn "extendqisi2"
3789 [(set (match_operand:SI 0 "register_operand" "=r")
3790 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3792 "movs{bl|x}\t{%1, %0|%0, %1}"
3793 [(set_attr "type" "imovx")
3794 (set_attr "mode" "SI")])
3796 (define_insn "*extendqisi2_zext"
3797 [(set (match_operand:DI 0 "register_operand" "=r")
3799 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3801 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3802 [(set_attr "type" "imovx")
3803 (set_attr "mode" "SI")])
3805 (define_insn "extendqihi2"
3806 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3807 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3810 switch (get_attr_prefix_0f (insn))
3813 return "{cbtw|cbw}";
3815 return "movs{bw|x}\t{%1, %0|%0, %1}";
3818 [(set_attr "type" "imovx")
3819 (set_attr "mode" "HI")
3820 (set (attr "prefix_0f")
3821 ;; movsx is short decodable while cwtl is vector decoded.
3822 (if_then_else (and (eq_attr "cpu" "!k6")
3823 (eq_attr "alternative" "0"))
3825 (const_string "1")))
3827 (if_then_else (eq_attr "prefix_0f" "0")
3829 (const_string "1")))])
3831 ;; Conversions between float and double.
3833 ;; These are all no-ops in the model used for the 80387.
3834 ;; So just emit moves.
3836 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3838 [(set (match_operand:DF 0 "push_operand" "")
3839 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3841 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3842 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3845 [(set (match_operand:XF 0 "push_operand" "")
3846 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3848 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3849 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3850 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3852 (define_expand "extendsfdf2"
3853 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3854 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3855 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3857 /* ??? Needed for compress_float_constant since all fp constants
3858 are TARGET_LEGITIMATE_CONSTANT_P. */
3859 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3861 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3862 && standard_80387_constant_p (operands[1]) > 0)
3864 operands[1] = simplify_const_unary_operation
3865 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3866 emit_move_insn_1 (operands[0], operands[1]);
3869 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3873 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3875 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3877 We do the conversion post reload to avoid producing of 128bit spills
3878 that might lead to ICE on 32bit target. The sequence unlikely combine
3881 [(set (match_operand:DF 0 "register_operand" "")
3883 (match_operand:SF 1 "nonimmediate_operand" "")))]
3884 "TARGET_USE_VECTOR_FP_CONVERTS
3885 && optimize_insn_for_speed_p ()
3886 && reload_completed && SSE_REG_P (operands[0])"
3891 (parallel [(const_int 0) (const_int 1)]))))]
3893 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3894 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3895 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3896 Try to avoid move when unpacking can be done in source. */
3897 if (REG_P (operands[1]))
3899 /* If it is unsafe to overwrite upper half of source, we need
3900 to move to destination and unpack there. */
3901 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3902 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3903 && true_regnum (operands[0]) != true_regnum (operands[1]))
3905 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3906 emit_move_insn (tmp, operands[1]);
3909 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3910 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3914 emit_insn (gen_vec_setv4sf_0 (operands[3],
3915 CONST0_RTX (V4SFmode), operands[1]));
3918 (define_insn "*extendsfdf2_mixed"
3919 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3921 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3922 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3924 switch (which_alternative)
3928 return output_387_reg_move (insn, operands);
3931 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3937 [(set_attr "type" "fmov,fmov,ssecvt")
3938 (set_attr "prefix" "orig,orig,maybe_vex")
3939 (set_attr "mode" "SF,XF,DF")])
3941 (define_insn "*extendsfdf2_sse"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3943 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3944 "TARGET_SSE2 && TARGET_SSE_MATH"
3945 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3946 [(set_attr "type" "ssecvt")
3947 (set_attr "prefix" "maybe_vex")
3948 (set_attr "mode" "DF")])
3950 (define_insn "*extendsfdf2_i387"
3951 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3952 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3954 "* return output_387_reg_move (insn, operands);"
3955 [(set_attr "type" "fmov")
3956 (set_attr "mode" "SF,XF")])
3958 (define_expand "extend<mode>xf2"
3959 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3960 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3963 /* ??? Needed for compress_float_constant since all fp constants
3964 are TARGET_LEGITIMATE_CONSTANT_P. */
3965 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3967 if (standard_80387_constant_p (operands[1]) > 0)
3969 operands[1] = simplify_const_unary_operation
3970 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3971 emit_move_insn_1 (operands[0], operands[1]);
3974 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3978 (define_insn "*extend<mode>xf2_i387"
3979 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3981 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3983 "* return output_387_reg_move (insn, operands);"
3984 [(set_attr "type" "fmov")
3985 (set_attr "mode" "<MODE>,XF")])
3987 ;; %%% This seems bad bad news.
3988 ;; This cannot output into an f-reg because there is no way to be sure
3989 ;; of truncating in that case. Otherwise this is just like a simple move
3990 ;; insn. So we pretend we can output to a reg in order to get better
3991 ;; register preferencing, but we really use a stack slot.
3993 ;; Conversion from DFmode to SFmode.
3995 (define_expand "truncdfsf2"
3996 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3998 (match_operand:DF 1 "nonimmediate_operand" "")))]
3999 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4001 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4003 else if (flag_unsafe_math_optimizations)
4007 enum ix86_stack_slot slot = (virtuals_instantiated
4010 rtx temp = assign_386_stack_local (SFmode, slot);
4011 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4016 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4018 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4020 We do the conversion post reload to avoid producing of 128bit spills
4021 that might lead to ICE on 32bit target. The sequence unlikely combine
4024 [(set (match_operand:SF 0 "register_operand" "")
4026 (match_operand:DF 1 "nonimmediate_operand" "")))]
4027 "TARGET_USE_VECTOR_FP_CONVERTS
4028 && optimize_insn_for_speed_p ()
4029 && reload_completed && SSE_REG_P (operands[0])"
4032 (float_truncate:V2SF
4036 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4037 operands[3] = CONST0_RTX (V2SFmode);
4038 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4039 /* Use movsd for loading from memory, unpcklpd for registers.
4040 Try to avoid move when unpacking can be done in source, or SSE3
4041 movddup is available. */
4042 if (REG_P (operands[1]))
4045 && true_regnum (operands[0]) != true_regnum (operands[1])
4046 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4047 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4049 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4050 emit_move_insn (tmp, operands[1]);
4053 else if (!TARGET_SSE3)
4054 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4055 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4058 emit_insn (gen_sse2_loadlpd (operands[4],
4059 CONST0_RTX (V2DFmode), operands[1]));
4062 (define_expand "truncdfsf2_with_temp"
4063 [(parallel [(set (match_operand:SF 0 "" "")
4064 (float_truncate:SF (match_operand:DF 1 "" "")))
4065 (clobber (match_operand:SF 2 "" ""))])])
4067 (define_insn "*truncdfsf_fast_mixed"
4068 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4070 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4071 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4073 switch (which_alternative)
4076 return output_387_reg_move (insn, operands);
4078 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4083 [(set_attr "type" "fmov,ssecvt")
4084 (set_attr "prefix" "orig,maybe_vex")
4085 (set_attr "mode" "SF")])
4087 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4088 ;; because nothing we do here is unsafe.
4089 (define_insn "*truncdfsf_fast_sse"
4090 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4092 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4093 "TARGET_SSE2 && TARGET_SSE_MATH"
4094 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4095 [(set_attr "type" "ssecvt")
4096 (set_attr "prefix" "maybe_vex")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf_fast_i387"
4100 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4102 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4103 "TARGET_80387 && flag_unsafe_math_optimizations"
4104 "* return output_387_reg_move (insn, operands);"
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "SF")])
4108 (define_insn "*truncdfsf_mixed"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4111 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4112 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4113 "TARGET_MIX_SSE_I387"
4115 switch (which_alternative)
4118 return output_387_reg_move (insn, operands);
4120 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4126 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4127 (set_attr "unit" "*,*,i387,i387,i387")
4128 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4129 (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf_i387"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4135 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4138 switch (which_alternative)
4141 return output_387_reg_move (insn, operands);
4147 [(set_attr "type" "fmov,multi,multi,multi")
4148 (set_attr "unit" "*,i387,i387,i387")
4149 (set_attr "mode" "SF")])
4151 (define_insn "*truncdfsf2_i387_1"
4152 [(set (match_operand:SF 0 "memory_operand" "=m")
4154 (match_operand:DF 1 "register_operand" "f")))]
4156 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4157 && !TARGET_MIX_SSE_I387"
4158 "* return output_387_reg_move (insn, operands);"
4159 [(set_attr "type" "fmov")
4160 (set_attr "mode" "SF")])
4163 [(set (match_operand:SF 0 "register_operand" "")
4165 (match_operand:DF 1 "fp_register_operand" "")))
4166 (clobber (match_operand 2 "" ""))]
4168 [(set (match_dup 2) (match_dup 1))
4169 (set (match_dup 0) (match_dup 2))]
4170 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4172 ;; Conversion from XFmode to {SF,DF}mode
4174 (define_expand "truncxf<mode>2"
4175 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "")))
4178 (clobber (match_dup 2))])]
4181 if (flag_unsafe_math_optimizations)
4183 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4184 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4185 if (reg != operands[0])
4186 emit_move_insn (operands[0], reg);
4191 enum ix86_stack_slot slot = (virtuals_instantiated
4194 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4198 (define_insn "*truncxfsf2_mixed"
4199 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4201 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4202 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4205 gcc_assert (!which_alternative);
4206 return output_387_reg_move (insn, operands);
4208 [(set_attr "type" "fmov,multi,multi,multi")
4209 (set_attr "unit" "*,i387,i387,i387")
4210 (set_attr "mode" "SF")])
4212 (define_insn "*truncxfdf2_mixed"
4213 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4215 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4216 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4219 gcc_assert (!which_alternative);
4220 return output_387_reg_move (insn, operands);
4222 [(set_attr "type" "fmov,multi,multi,multi")
4223 (set_attr "unit" "*,i387,i387,i387")
4224 (set_attr "mode" "DF")])
4226 (define_insn "truncxf<mode>2_i387_noop"
4227 [(set (match_operand:MODEF 0 "register_operand" "=f")
4228 (float_truncate:MODEF
4229 (match_operand:XF 1 "register_operand" "f")))]
4230 "TARGET_80387 && flag_unsafe_math_optimizations"
4231 "* return output_387_reg_move (insn, operands);"
4232 [(set_attr "type" "fmov")
4233 (set_attr "mode" "<MODE>")])
4235 (define_insn "*truncxf<mode>2_i387"
4236 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4237 (float_truncate:MODEF
4238 (match_operand:XF 1 "register_operand" "f")))]
4240 "* return output_387_reg_move (insn, operands);"
4241 [(set_attr "type" "fmov")
4242 (set_attr "mode" "<MODE>")])
4245 [(set (match_operand:MODEF 0 "register_operand" "")
4246 (float_truncate:MODEF
4247 (match_operand:XF 1 "register_operand" "")))
4248 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4249 "TARGET_80387 && reload_completed"
4250 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4251 (set (match_dup 0) (match_dup 2))])
4254 [(set (match_operand:MODEF 0 "memory_operand" "")
4255 (float_truncate:MODEF
4256 (match_operand:XF 1 "register_operand" "")))
4257 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4259 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4261 ;; Signed conversion to DImode.
4263 (define_expand "fix_truncxfdi2"
4264 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4265 (fix:DI (match_operand:XF 1 "register_operand" "")))
4266 (clobber (reg:CC FLAGS_REG))])]
4271 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4276 (define_expand "fix_trunc<mode>di2"
4277 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4278 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4279 (clobber (reg:CC FLAGS_REG))])]
4280 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4283 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4285 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4288 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4290 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4291 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4292 if (out != operands[0])
4293 emit_move_insn (operands[0], out);
4298 ;; Signed conversion to SImode.
4300 (define_expand "fix_truncxfsi2"
4301 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4302 (fix:SI (match_operand:XF 1 "register_operand" "")))
4303 (clobber (reg:CC FLAGS_REG))])]
4308 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4313 (define_expand "fix_trunc<mode>si2"
4314 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4315 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4316 (clobber (reg:CC FLAGS_REG))])]
4317 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4320 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4322 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4325 if (SSE_FLOAT_MODE_P (<MODE>mode))
4327 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4328 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4329 if (out != operands[0])
4330 emit_move_insn (operands[0], out);
4335 ;; Signed conversion to HImode.
4337 (define_expand "fix_trunc<mode>hi2"
4338 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4339 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4340 (clobber (reg:CC FLAGS_REG))])]
4342 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4346 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4351 ;; Unsigned conversion to SImode.
4353 (define_expand "fixuns_trunc<mode>si2"
4355 [(set (match_operand:SI 0 "register_operand" "")
4357 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4359 (clobber (match_scratch:<ssevecmode> 3 ""))
4360 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4361 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4363 enum machine_mode mode = <MODE>mode;
4364 enum machine_mode vecmode = <ssevecmode>mode;
4365 REAL_VALUE_TYPE TWO31r;
4368 if (optimize_insn_for_size_p ())
4371 real_ldexp (&TWO31r, &dconst1, 31);
4372 two31 = const_double_from_real_value (TWO31r, mode);
4373 two31 = ix86_build_const_vector (vecmode, true, two31);
4374 operands[2] = force_reg (vecmode, two31);
4377 (define_insn_and_split "*fixuns_trunc<mode>_1"
4378 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4380 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4381 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4382 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4383 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4384 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4385 && optimize_function_for_speed_p (cfun)"
4387 "&& reload_completed"
4390 ix86_split_convert_uns_si_sse (operands);
4394 ;; Unsigned conversion to HImode.
4395 ;; Without these patterns, we'll try the unsigned SI conversion which
4396 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4398 (define_expand "fixuns_trunc<mode>hi2"
4400 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4401 (set (match_operand:HI 0 "nonimmediate_operand" "")
4402 (subreg:HI (match_dup 2) 0))]
4403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4404 "operands[2] = gen_reg_rtx (SImode);")
4406 ;; When SSE is available, it is always faster to use it!
4407 (define_insn "fix_trunc<mode>di_sse"
4408 [(set (match_operand:DI 0 "register_operand" "=r,r")
4409 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4410 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4411 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4412 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4413 [(set_attr "type" "sseicvt")
4414 (set_attr "prefix" "maybe_vex")
4415 (set_attr "prefix_rex" "1")
4416 (set_attr "mode" "<MODE>")
4417 (set_attr "athlon_decode" "double,vector")
4418 (set_attr "amdfam10_decode" "double,double")
4419 (set_attr "bdver1_decode" "double,double")])
4421 (define_insn "fix_trunc<mode>si_sse"
4422 [(set (match_operand:SI 0 "register_operand" "=r,r")
4423 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4424 "SSE_FLOAT_MODE_P (<MODE>mode)
4425 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4426 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4427 [(set_attr "type" "sseicvt")
4428 (set_attr "prefix" "maybe_vex")
4429 (set_attr "mode" "<MODE>")
4430 (set_attr "athlon_decode" "double,vector")
4431 (set_attr "amdfam10_decode" "double,double")
4432 (set_attr "bdver1_decode" "double,double")])
4434 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4436 [(set (match_operand:MODEF 0 "register_operand" "")
4437 (match_operand:MODEF 1 "memory_operand" ""))
4438 (set (match_operand:SWI48x 2 "register_operand" "")
4439 (fix:SWI48x (match_dup 0)))]
4440 "TARGET_SHORTEN_X87_SSE
4441 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4442 && peep2_reg_dead_p (2, operands[0])"
4443 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4445 ;; Avoid vector decoded forms of the instruction.
4447 [(match_scratch:DF 2 "Y2")
4448 (set (match_operand:SWI48x 0 "register_operand" "")
4449 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4450 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4451 [(set (match_dup 2) (match_dup 1))
4452 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4455 [(match_scratch:SF 2 "x")
4456 (set (match_operand:SWI48x 0 "register_operand" "")
4457 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4458 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4459 [(set (match_dup 2) (match_dup 1))
4460 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4462 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4463 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4464 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4465 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4467 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4468 && (TARGET_64BIT || <MODE>mode != DImode))
4470 && can_create_pseudo_p ()"
4475 if (memory_operand (operands[0], VOIDmode))
4476 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4479 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4480 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4486 [(set_attr "type" "fisttp")
4487 (set_attr "mode" "<MODE>")])
4489 (define_insn "fix_trunc<mode>_i387_fisttp"
4490 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4491 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4492 (clobber (match_scratch:XF 2 "=&1f"))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && TARGET_SSE_MATH)"
4498 "* return output_fix_trunc (insn, operands, true);"
4499 [(set_attr "type" "fisttp")
4500 (set_attr "mode" "<MODE>")])
4502 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4503 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4504 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4505 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4506 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4507 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4509 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4510 && (TARGET_64BIT || <MODE>mode != DImode))
4511 && TARGET_SSE_MATH)"
4513 [(set_attr "type" "fisttp")
4514 (set_attr "mode" "<MODE>")])
4517 [(set (match_operand:SWI248x 0 "register_operand" "")
4518 (fix:SWI248x (match_operand 1 "register_operand" "")))
4519 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4520 (clobber (match_scratch 3 ""))]
4522 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4523 (clobber (match_dup 3))])
4524 (set (match_dup 0) (match_dup 2))])
4527 [(set (match_operand:SWI248x 0 "memory_operand" "")
4528 (fix:SWI248x (match_operand 1 "register_operand" "")))
4529 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4530 (clobber (match_scratch 3 ""))]
4532 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4533 (clobber (match_dup 3))])])
4535 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4536 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4537 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4538 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4539 ;; function in i386.c.
4540 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4541 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4542 (fix:SWI248x (match_operand 1 "register_operand" "")))
4543 (clobber (reg:CC FLAGS_REG))]
4544 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4547 && (TARGET_64BIT || <MODE>mode != DImode))
4548 && can_create_pseudo_p ()"
4553 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4555 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4556 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4557 if (memory_operand (operands[0], VOIDmode))
4558 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4559 operands[2], operands[3]));
4562 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4563 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4564 operands[2], operands[3],
4569 [(set_attr "type" "fistp")
4570 (set_attr "i387_cw" "trunc")
4571 (set_attr "mode" "<MODE>")])
4573 (define_insn "fix_truncdi_i387"
4574 [(set (match_operand:DI 0 "memory_operand" "=m")
4575 (fix:DI (match_operand 1 "register_operand" "f")))
4576 (use (match_operand:HI 2 "memory_operand" "m"))
4577 (use (match_operand:HI 3 "memory_operand" "m"))
4578 (clobber (match_scratch:XF 4 "=&1f"))]
4579 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4581 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4582 "* return output_fix_trunc (insn, operands, false);"
4583 [(set_attr "type" "fistp")
4584 (set_attr "i387_cw" "trunc")
4585 (set_attr "mode" "DI")])
4587 (define_insn "fix_truncdi_i387_with_temp"
4588 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4589 (fix:DI (match_operand 1 "register_operand" "f,f")))
4590 (use (match_operand:HI 2 "memory_operand" "m,m"))
4591 (use (match_operand:HI 3 "memory_operand" "m,m"))
4592 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4593 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4594 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4596 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4598 [(set_attr "type" "fistp")
4599 (set_attr "i387_cw" "trunc")
4600 (set_attr "mode" "DI")])
4603 [(set (match_operand:DI 0 "register_operand" "")
4604 (fix:DI (match_operand 1 "register_operand" "")))
4605 (use (match_operand:HI 2 "memory_operand" ""))
4606 (use (match_operand:HI 3 "memory_operand" ""))
4607 (clobber (match_operand:DI 4 "memory_operand" ""))
4608 (clobber (match_scratch 5 ""))]
4610 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4613 (clobber (match_dup 5))])
4614 (set (match_dup 0) (match_dup 4))])
4617 [(set (match_operand:DI 0 "memory_operand" "")
4618 (fix:DI (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:DI 4 "memory_operand" ""))
4622 (clobber (match_scratch 5 ""))]
4624 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4627 (clobber (match_dup 5))])])
4629 (define_insn "fix_trunc<mode>_i387"
4630 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4631 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4632 (use (match_operand:HI 2 "memory_operand" "m"))
4633 (use (match_operand:HI 3 "memory_operand" "m"))]
4634 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4637 "* return output_fix_trunc (insn, operands, false);"
4638 [(set_attr "type" "fistp")
4639 (set_attr "i387_cw" "trunc")
4640 (set_attr "mode" "<MODE>")])
4642 (define_insn "fix_trunc<mode>_i387_with_temp"
4643 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4644 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4645 (use (match_operand:HI 2 "memory_operand" "m,m"))
4646 (use (match_operand:HI 3 "memory_operand" "m,m"))
4647 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4648 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4652 [(set_attr "type" "fistp")
4653 (set_attr "i387_cw" "trunc")
4654 (set_attr "mode" "<MODE>")])
4657 [(set (match_operand:SWI24 0 "register_operand" "")
4658 (fix:SWI24 (match_operand 1 "register_operand" "")))
4659 (use (match_operand:HI 2 "memory_operand" ""))
4660 (use (match_operand:HI 3 "memory_operand" ""))
4661 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4663 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4665 (use (match_dup 3))])
4666 (set (match_dup 0) (match_dup 4))])
4669 [(set (match_operand:SWI24 0 "memory_operand" "")
4670 (fix:SWI24 (match_operand 1 "register_operand" "")))
4671 (use (match_operand:HI 2 "memory_operand" ""))
4672 (use (match_operand:HI 3 "memory_operand" ""))
4673 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4675 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4677 (use (match_dup 3))])])
4679 (define_insn "x86_fnstcw_1"
4680 [(set (match_operand:HI 0 "memory_operand" "=m")
4681 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4684 [(set (attr "length")
4685 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4686 (set_attr "mode" "HI")
4687 (set_attr "unit" "i387")
4688 (set_attr "bdver1_decode" "vector")])
4690 (define_insn "x86_fldcw_1"
4691 [(set (reg:HI FPCR_REG)
4692 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4695 [(set (attr "length")
4696 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4697 (set_attr "mode" "HI")
4698 (set_attr "unit" "i387")
4699 (set_attr "athlon_decode" "vector")
4700 (set_attr "amdfam10_decode" "vector")
4701 (set_attr "bdver1_decode" "vector")])
4703 ;; Conversion between fixed point and floating point.
4705 ;; Even though we only accept memory inputs, the backend _really_
4706 ;; wants to be able to do this between registers.
4708 (define_expand "floathi<mode>2"
4709 [(set (match_operand:X87MODEF 0 "register_operand" "")
4710 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4713 || TARGET_MIX_SSE_I387)")
4715 ;; Pre-reload splitter to add memory clobber to the pattern.
4716 (define_insn_and_split "*floathi<mode>2_1"
4717 [(set (match_operand:X87MODEF 0 "register_operand" "")
4718 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4721 || TARGET_MIX_SSE_I387)
4722 && can_create_pseudo_p ()"
4725 [(parallel [(set (match_dup 0)
4726 (float:X87MODEF (match_dup 1)))
4727 (clobber (match_dup 2))])]
4728 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4730 (define_insn "*floathi<mode>2_i387_with_temp"
4731 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4732 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4733 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4736 || TARGET_MIX_SSE_I387)"
4738 [(set_attr "type" "fmov,multi")
4739 (set_attr "mode" "<MODE>")
4740 (set_attr "unit" "*,i387")
4741 (set_attr "fp_int_src" "true")])
4743 (define_insn "*floathi<mode>2_i387"
4744 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4745 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4748 || TARGET_MIX_SSE_I387)"
4750 [(set_attr "type" "fmov")
4751 (set_attr "mode" "<MODE>")
4752 (set_attr "fp_int_src" "true")])
4755 [(set (match_operand:X87MODEF 0 "register_operand" "")
4756 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4757 (clobber (match_operand:HI 2 "memory_operand" ""))]
4759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387)
4761 && reload_completed"
4762 [(set (match_dup 2) (match_dup 1))
4763 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4766 [(set (match_operand:X87MODEF 0 "register_operand" "")
4767 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4768 (clobber (match_operand:HI 2 "memory_operand" ""))]
4770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4771 || TARGET_MIX_SSE_I387)
4772 && reload_completed"
4773 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4775 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4776 [(set (match_operand:X87MODEF 0 "register_operand" "")
4778 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4780 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4781 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4783 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4784 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4785 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4787 rtx reg = gen_reg_rtx (XFmode);
4788 rtx (*insn)(rtx, rtx);
4790 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4792 if (<X87MODEF:MODE>mode == SFmode)
4793 insn = gen_truncxfsf2;
4794 else if (<X87MODEF:MODE>mode == DFmode)
4795 insn = gen_truncxfdf2;
4799 emit_insn (insn (operands[0], reg));
4804 ;; Pre-reload splitter to add memory clobber to the pattern.
4805 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4806 [(set (match_operand:X87MODEF 0 "register_operand" "")
4807 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4809 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4810 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4811 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4812 || TARGET_MIX_SSE_I387))
4813 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4814 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4815 && ((<SWI48x:MODE>mode == SImode
4816 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4817 && optimize_function_for_speed_p (cfun)
4818 && flag_trapping_math)
4819 || !(TARGET_INTER_UNIT_CONVERSIONS
4820 || optimize_function_for_size_p (cfun)))))
4821 && can_create_pseudo_p ()"
4824 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4825 (clobber (match_dup 2))])]
4827 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4829 /* Avoid store forwarding (partial memory) stall penalty
4830 by passing DImode value through XMM registers. */
4831 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4832 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4833 && optimize_function_for_speed_p (cfun))
4835 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4842 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4843 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4845 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4846 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4847 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4848 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4851 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4852 (set_attr "unit" "*,i387,*,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct,double")
4854 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4855 (set_attr "bdver1_decode" "*,*,double,direct,double")
4856 (set_attr "fp_int_src" "true")])
4858 (define_insn "*floatsi<mode>2_vector_mixed"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4860 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4861 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4862 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4866 [(set_attr "type" "fmov,sseicvt")
4867 (set_attr "mode" "<MODE>,<ssevecmode>")
4868 (set_attr "unit" "i387,*")
4869 (set_attr "athlon_decode" "*,direct")
4870 (set_attr "amdfam10_decode" "*,double")
4871 (set_attr "bdver1_decode" "*,direct")
4872 (set_attr "fp_int_src" "true")])
4874 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4875 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4877 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4878 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4879 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4880 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4882 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4883 (set_attr "mode" "<MODEF:MODE>")
4884 (set_attr "unit" "*,i387,*,*")
4885 (set_attr "athlon_decode" "*,*,double,direct")
4886 (set_attr "amdfam10_decode" "*,*,vector,double")
4887 (set_attr "bdver1_decode" "*,*,double,direct")
4888 (set_attr "fp_int_src" "true")])
4891 [(set (match_operand:MODEF 0 "register_operand" "")
4892 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4893 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4894 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4895 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4896 && TARGET_INTER_UNIT_CONVERSIONS
4898 && (SSE_REG_P (operands[0])
4899 || (GET_CODE (operands[0]) == SUBREG
4900 && SSE_REG_P (operands[0])))"
4901 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4904 [(set (match_operand:MODEF 0 "register_operand" "")
4905 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4906 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4907 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4908 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4909 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4911 && (SSE_REG_P (operands[0])
4912 || (GET_CODE (operands[0]) == SUBREG
4913 && SSE_REG_P (operands[0])))"
4914 [(set (match_dup 2) (match_dup 1))
4915 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4917 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4918 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4920 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4921 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4923 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4926 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4927 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4928 [(set_attr "type" "fmov,sseicvt,sseicvt")
4929 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4930 (set_attr "mode" "<MODEF:MODE>")
4931 (set (attr "prefix_rex")
4933 (and (eq_attr "prefix" "maybe_vex")
4934 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4936 (const_string "*")))
4937 (set_attr "unit" "i387,*,*")
4938 (set_attr "athlon_decode" "*,double,direct")
4939 (set_attr "amdfam10_decode" "*,vector,double")
4940 (set_attr "bdver1_decode" "*,double,direct")
4941 (set_attr "fp_int_src" "true")])
4943 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4944 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4946 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4947 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4948 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4949 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4952 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4953 [(set_attr "type" "fmov,sseicvt")
4954 (set_attr "prefix" "orig,maybe_vex")
4955 (set_attr "mode" "<MODEF:MODE>")
4956 (set (attr "prefix_rex")
4958 (and (eq_attr "prefix" "maybe_vex")
4959 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4961 (const_string "*")))
4962 (set_attr "athlon_decode" "*,direct")
4963 (set_attr "amdfam10_decode" "*,double")
4964 (set_attr "bdver1_decode" "*,direct")
4965 (set_attr "fp_int_src" "true")])
4967 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4968 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4970 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4971 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4972 "TARGET_SSE2 && TARGET_SSE_MATH
4973 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4975 [(set_attr "type" "sseicvt")
4976 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4977 (set_attr "athlon_decode" "double,direct,double")
4978 (set_attr "amdfam10_decode" "vector,double,double")
4979 (set_attr "bdver1_decode" "double,direct,double")
4980 (set_attr "fp_int_src" "true")])
4982 (define_insn "*floatsi<mode>2_vector_sse"
4983 [(set (match_operand:MODEF 0 "register_operand" "=x")
4984 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4985 "TARGET_SSE2 && TARGET_SSE_MATH
4986 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4988 [(set_attr "type" "sseicvt")
4989 (set_attr "mode" "<MODE>")
4990 (set_attr "athlon_decode" "direct")
4991 (set_attr "amdfam10_decode" "double")
4992 (set_attr "bdver1_decode" "direct")
4993 (set_attr "fp_int_src" "true")])
4996 [(set (match_operand:MODEF 0 "register_operand" "")
4997 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4998 (clobber (match_operand:SI 2 "memory_operand" ""))]
4999 "TARGET_SSE2 && TARGET_SSE_MATH
5000 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5002 && (SSE_REG_P (operands[0])
5003 || (GET_CODE (operands[0]) == SUBREG
5004 && SSE_REG_P (operands[0])))"
5007 rtx op1 = operands[1];
5009 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5011 if (GET_CODE (op1) == SUBREG)
5012 op1 = SUBREG_REG (op1);
5014 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5016 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5017 emit_insn (gen_sse2_loadld (operands[4],
5018 CONST0_RTX (V4SImode), operands[1]));
5020 /* We can ignore possible trapping value in the
5021 high part of SSE register for non-trapping math. */
5022 else if (SSE_REG_P (op1) && !flag_trapping_math)
5023 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5026 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5027 emit_move_insn (operands[2], operands[1]);
5028 emit_insn (gen_sse2_loadld (operands[4],
5029 CONST0_RTX (V4SImode), operands[2]));
5032 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5037 [(set (match_operand:MODEF 0 "register_operand" "")
5038 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5039 (clobber (match_operand:SI 2 "memory_operand" ""))]
5040 "TARGET_SSE2 && TARGET_SSE_MATH
5041 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5043 && (SSE_REG_P (operands[0])
5044 || (GET_CODE (operands[0]) == SUBREG
5045 && SSE_REG_P (operands[0])))"
5048 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5050 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5052 emit_insn (gen_sse2_loadld (operands[4],
5053 CONST0_RTX (V4SImode), operands[1]));
5055 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5060 [(set (match_operand:MODEF 0 "register_operand" "")
5061 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5062 "TARGET_SSE2 && TARGET_SSE_MATH
5063 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5065 && (SSE_REG_P (operands[0])
5066 || (GET_CODE (operands[0]) == SUBREG
5067 && SSE_REG_P (operands[0])))"
5070 rtx op1 = operands[1];
5072 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5074 if (GET_CODE (op1) == SUBREG)
5075 op1 = SUBREG_REG (op1);
5077 if (GENERAL_REG_P (op1))
5079 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5080 if (TARGET_INTER_UNIT_MOVES)
5081 emit_insn (gen_sse2_loadld (operands[4],
5082 CONST0_RTX (V4SImode), operands[1]));
5085 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5087 emit_insn (gen_sse2_loadld (operands[4],
5088 CONST0_RTX (V4SImode), operands[5]));
5089 ix86_free_from_memory (GET_MODE (operands[1]));
5092 /* We can ignore possible trapping value in the
5093 high part of SSE register for non-trapping math. */
5094 else if (SSE_REG_P (op1) && !flag_trapping_math)
5095 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5099 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5104 [(set (match_operand:MODEF 0 "register_operand" "")
5105 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5106 "TARGET_SSE2 && TARGET_SSE_MATH
5107 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5109 && (SSE_REG_P (operands[0])
5110 || (GET_CODE (operands[0]) == SUBREG
5111 && SSE_REG_P (operands[0])))"
5114 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5118 emit_insn (gen_sse2_loadld (operands[4],
5119 CONST0_RTX (V4SImode), operands[1]));
5121 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5125 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5126 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5128 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5129 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5130 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5131 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5133 [(set_attr "type" "sseicvt")
5134 (set_attr "mode" "<MODEF:MODE>")
5135 (set_attr "athlon_decode" "double,direct")
5136 (set_attr "amdfam10_decode" "vector,double")
5137 (set_attr "bdver1_decode" "double,direct")
5138 (set_attr "fp_int_src" "true")])
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5141 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5143 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5144 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5145 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5146 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5147 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5148 [(set_attr "type" "sseicvt")
5149 (set_attr "prefix" "maybe_vex")
5150 (set_attr "mode" "<MODEF:MODE>")
5151 (set (attr "prefix_rex")
5153 (and (eq_attr "prefix" "maybe_vex")
5154 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5156 (const_string "*")))
5157 (set_attr "athlon_decode" "double,direct")
5158 (set_attr "amdfam10_decode" "vector,double")
5159 (set_attr "bdver1_decode" "double,direct")
5160 (set_attr "fp_int_src" "true")])
5163 [(set (match_operand:MODEF 0 "register_operand" "")
5164 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5165 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5166 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5167 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5168 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5170 && (SSE_REG_P (operands[0])
5171 || (GET_CODE (operands[0]) == SUBREG
5172 && SSE_REG_P (operands[0])))"
5173 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5175 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5176 [(set (match_operand:MODEF 0 "register_operand" "=x")
5178 (match_operand:SWI48x 1 "memory_operand" "m")))]
5179 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5180 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5181 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5182 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5183 [(set_attr "type" "sseicvt")
5184 (set_attr "prefix" "maybe_vex")
5185 (set_attr "mode" "<MODEF:MODE>")
5186 (set (attr "prefix_rex")
5188 (and (eq_attr "prefix" "maybe_vex")
5189 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5191 (const_string "*")))
5192 (set_attr "athlon_decode" "direct")
5193 (set_attr "amdfam10_decode" "double")
5194 (set_attr "bdver1_decode" "direct")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5201 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5205 && (SSE_REG_P (operands[0])
5206 || (GET_CODE (operands[0]) == SUBREG
5207 && SSE_REG_P (operands[0])))"
5208 [(set (match_dup 2) (match_dup 1))
5209 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5212 [(set (match_operand:MODEF 0 "register_operand" "")
5213 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5214 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5215 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5216 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5218 && (SSE_REG_P (operands[0])
5219 || (GET_CODE (operands[0]) == SUBREG
5220 && SSE_REG_P (operands[0])))"
5221 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5223 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5224 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5226 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5227 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5229 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5233 [(set_attr "type" "fmov,multi")
5234 (set_attr "mode" "<X87MODEF:MODE>")
5235 (set_attr "unit" "*,i387")
5236 (set_attr "fp_int_src" "true")])
5238 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5239 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5241 (match_operand:SWI48x 1 "memory_operand" "m")))]
5243 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5245 [(set_attr "type" "fmov")
5246 (set_attr "mode" "<X87MODEF:MODE>")
5247 (set_attr "fp_int_src" "true")])
5250 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5251 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5252 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5254 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5255 && reload_completed"
5256 [(set (match_dup 2) (match_dup 1))
5257 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5260 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5261 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5262 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5264 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5265 && reload_completed"
5266 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5268 ;; Avoid store forwarding (partial memory) stall penalty
5269 ;; by passing DImode value through XMM registers. */
5271 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5274 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5275 (clobber (match_scratch:V4SI 3 "=X,x"))
5276 (clobber (match_scratch:V4SI 4 "=X,x"))
5277 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5278 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5279 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5280 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5282 [(set_attr "type" "multi")
5283 (set_attr "mode" "<X87MODEF:MODE>")
5284 (set_attr "unit" "i387")
5285 (set_attr "fp_int_src" "true")])
5288 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5289 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5290 (clobber (match_scratch:V4SI 3 ""))
5291 (clobber (match_scratch:V4SI 4 ""))
5292 (clobber (match_operand:DI 2 "memory_operand" ""))]
5293 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5294 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5295 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5296 && reload_completed"
5297 [(set (match_dup 2) (match_dup 3))
5298 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5300 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5301 Assemble the 64-bit DImode value in an xmm register. */
5302 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5303 gen_rtx_SUBREG (SImode, operands[1], 0)));
5304 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5305 gen_rtx_SUBREG (SImode, operands[1], 4)));
5306 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5309 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5314 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5315 (clobber (match_scratch:V4SI 3 ""))
5316 (clobber (match_scratch:V4SI 4 ""))
5317 (clobber (match_operand:DI 2 "memory_operand" ""))]
5318 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5319 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5320 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5321 && reload_completed"
5322 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5324 ;; Avoid store forwarding (partial memory) stall penalty by extending
5325 ;; SImode value to DImode through XMM register instead of pushing two
5326 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5327 ;; targets benefit from this optimization. Also note that fild
5328 ;; loads from memory only.
5330 (define_insn "*floatunssi<mode>2_1"
5331 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5332 (unsigned_float:X87MODEF
5333 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5334 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5335 (clobber (match_scratch:SI 3 "=X,x"))]
5337 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340 [(set_attr "type" "multi")
5341 (set_attr "mode" "<MODE>")])
5344 [(set (match_operand:X87MODEF 0 "register_operand" "")
5345 (unsigned_float:X87MODEF
5346 (match_operand:SI 1 "register_operand" "")))
5347 (clobber (match_operand:DI 2 "memory_operand" ""))
5348 (clobber (match_scratch:SI 3 ""))]
5350 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352 && reload_completed"
5353 [(set (match_dup 2) (match_dup 1))
5355 (float:X87MODEF (match_dup 2)))]
5356 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (unsigned_float:X87MODEF
5361 (match_operand:SI 1 "memory_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 3))
5370 (float:X87MODEF (match_dup 2)))]
5372 emit_move_insn (operands[3], operands[1]);
5373 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5376 (define_expand "floatunssi<mode>2"
5378 [(set (match_operand:X87MODEF 0 "register_operand" "")
5379 (unsigned_float:X87MODEF
5380 (match_operand:SI 1 "nonimmediate_operand" "")))
5381 (clobber (match_dup 2))
5382 (clobber (match_scratch:SI 3 ""))])]
5384 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5388 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5390 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5395 enum ix86_stack_slot slot = (virtuals_instantiated
5398 operands[2] = assign_386_stack_local (DImode, slot);
5402 (define_expand "floatunsdisf2"
5403 [(use (match_operand:SF 0 "register_operand" ""))
5404 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5405 "TARGET_64BIT && TARGET_SSE_MATH"
5406 "x86_emit_floatuns (operands); DONE;")
5408 (define_expand "floatunsdidf2"
5409 [(use (match_operand:DF 0 "register_operand" ""))
5410 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5411 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5412 && TARGET_SSE2 && TARGET_SSE_MATH"
5415 x86_emit_floatuns (operands);
5417 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5423 (define_expand "add<mode>3"
5424 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5425 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5426 (match_operand:SDWIM 2 "<general_operand>" "")))]
5428 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5430 (define_insn_and_split "*add<dwi>3_doubleword"
5431 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5433 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5434 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5435 (clobber (reg:CC FLAGS_REG))]
5436 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5439 [(parallel [(set (reg:CC FLAGS_REG)
5440 (unspec:CC [(match_dup 1) (match_dup 2)]
5443 (plus:DWIH (match_dup 1) (match_dup 2)))])
5444 (parallel [(set (match_dup 3)
5448 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5450 (clobber (reg:CC FLAGS_REG))])]
5451 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5453 (define_insn "*add<mode>3_cc"
5454 [(set (reg:CC FLAGS_REG)
5456 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5457 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5459 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5460 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5461 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5462 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5463 [(set_attr "type" "alu")
5464 (set_attr "mode" "<MODE>")])
5466 (define_insn "addqi3_cc"
5467 [(set (reg:CC FLAGS_REG)
5469 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:QI 2 "general_operand" "qn,qm")]
5472 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5473 (plus:QI (match_dup 1) (match_dup 2)))]
5474 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5475 "add{b}\t{%2, %0|%0, %2}"
5476 [(set_attr "type" "alu")
5477 (set_attr "mode" "QI")])
5479 (define_insn "*lea_1"
5480 [(set (match_operand:SWI48 0 "register_operand" "=r")
5481 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5483 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5484 [(set_attr "type" "lea")
5485 (set_attr "mode" "<MODE>")])
5487 (define_insn "*lea_1_zext"
5488 [(set (match_operand:DI 0 "register_operand" "=r")
5490 (match_operand:SI 1 "lea_address_operand" "p")))]
5492 "lea{l}\t{%a1, %k0|%k0, %a1}"
5493 [(set_attr "type" "lea")
5494 (set_attr "mode" "SI")])
5496 (define_insn "*lea_2"
5497 [(set (match_operand:SI 0 "register_operand" "=r")
5498 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5500 "lea{l}\t{%a1, %0|%0, %a1}"
5501 [(set_attr "type" "lea")
5502 (set_attr "mode" "SI")])
5504 (define_insn "*lea_2_zext"
5505 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5509 "lea{l}\t{%a1, %k0|%k0, %a1}"
5510 [(set_attr "type" "lea")
5511 (set_attr "mode" "SI")])
5513 (define_insn "*add<mode>_1"
5514 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5516 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5517 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5521 switch (get_attr_type (insn))
5527 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5528 if (operands[2] == const1_rtx)
5529 return "inc{<imodesuffix>}\t%0";
5532 gcc_assert (operands[2] == constm1_rtx);
5533 return "dec{<imodesuffix>}\t%0";
5537 /* For most processors, ADD is faster than LEA. This alternative
5538 was added to use ADD as much as possible. */
5539 if (which_alternative == 2)
5542 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5546 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5547 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5549 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5553 (cond [(eq_attr "alternative" "3")
5554 (const_string "lea")
5555 (match_operand:SWI48 2 "incdec_operand" "")
5556 (const_string "incdec")
5558 (const_string "alu")))
5559 (set (attr "length_immediate")
5561 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5563 (const_string "*")))
5564 (set_attr "mode" "<MODE>")])
5566 ;; It may seem that nonimmediate operand is proper one for operand 1.
5567 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5568 ;; we take care in ix86_binary_operator_ok to not allow two memory
5569 ;; operands so proper swapping will be done in reload. This allow
5570 ;; patterns constructed from addsi_1 to match.
5572 (define_insn "addsi_1_zext"
5573 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5575 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5576 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5577 (clobber (reg:CC FLAGS_REG))]
5578 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5580 switch (get_attr_type (insn))
5586 if (operands[2] == const1_rtx)
5587 return "inc{l}\t%k0";
5590 gcc_assert (operands[2] == constm1_rtx);
5591 return "dec{l}\t%k0";
5595 /* For most processors, ADD is faster than LEA. This alternative
5596 was added to use ADD as much as possible. */
5597 if (which_alternative == 1)
5600 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5603 if (x86_maybe_negate_const_int (&operands[2], SImode))
5604 return "sub{l}\t{%2, %k0|%k0, %2}";
5606 return "add{l}\t{%2, %k0|%k0, %2}";
5610 (cond [(eq_attr "alternative" "2")
5611 (const_string "lea")
5612 (match_operand:SI 2 "incdec_operand" "")
5613 (const_string "incdec")
5615 (const_string "alu")))
5616 (set (attr "length_immediate")
5618 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5620 (const_string "*")))
5621 (set_attr "mode" "SI")])
5623 (define_insn "*addhi_1"
5624 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5625 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5626 (match_operand:HI 2 "general_operand" "rn,rm")))
5627 (clobber (reg:CC FLAGS_REG))]
5628 "TARGET_PARTIAL_REG_STALL
5629 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5631 switch (get_attr_type (insn))
5634 if (operands[2] == const1_rtx)
5635 return "inc{w}\t%0";
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{w}\t%0";
5643 if (x86_maybe_negate_const_int (&operands[2], HImode))
5644 return "sub{w}\t{%2, %0|%0, %2}";
5646 return "add{w}\t{%2, %0|%0, %2}";
5650 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5651 (const_string "incdec")
5652 (const_string "alu")))
5653 (set (attr "length_immediate")
5655 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5657 (const_string "*")))
5658 (set_attr "mode" "HI")])
5660 (define_insn "*addhi_1_lea"
5661 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5662 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5663 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "!TARGET_PARTIAL_REG_STALL
5666 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5668 switch (get_attr_type (insn))
5674 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5675 if (operands[2] == const1_rtx)
5676 return "inc{w}\t%0";
5679 gcc_assert (operands[2] == constm1_rtx);
5680 return "dec{w}\t%0";
5684 /* For most processors, ADD is faster than LEA. This alternative
5685 was added to use ADD as much as possible. */
5686 if (which_alternative == 2)
5689 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5692 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5693 if (x86_maybe_negate_const_int (&operands[2], HImode))
5694 return "sub{w}\t{%2, %0|%0, %2}";
5696 return "add{w}\t{%2, %0|%0, %2}";
5700 (cond [(eq_attr "alternative" "3")
5701 (const_string "lea")
5702 (match_operand:HI 2 "incdec_operand" "")
5703 (const_string "incdec")
5705 (const_string "alu")))
5706 (set (attr "length_immediate")
5708 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5710 (const_string "*")))
5711 (set_attr "mode" "HI,HI,HI,SI")])
5713 ;; %%% Potential partial reg stall on alternative 2. What to do?
5714 (define_insn "*addqi_1"
5715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5716 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5717 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5718 (clobber (reg:CC FLAGS_REG))]
5719 "TARGET_PARTIAL_REG_STALL
5720 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5722 int widen = (which_alternative == 2);
5723 switch (get_attr_type (insn))
5726 if (operands[2] == const1_rtx)
5727 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5730 gcc_assert (operands[2] == constm1_rtx);
5731 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5735 if (x86_maybe_negate_const_int (&operands[2], QImode))
5738 return "sub{l}\t{%2, %k0|%k0, %2}";
5740 return "sub{b}\t{%2, %0|%0, %2}";
5743 return "add{l}\t{%k2, %k0|%k0, %k2}";
5745 return "add{b}\t{%2, %0|%0, %2}";
5749 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5750 (const_string "incdec")
5751 (const_string "alu")))
5752 (set (attr "length_immediate")
5754 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5756 (const_string "*")))
5757 (set_attr "mode" "QI,QI,SI")])
5759 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5760 (define_insn "*addqi_1_lea"
5761 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5762 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5763 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "!TARGET_PARTIAL_REG_STALL
5766 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5768 int widen = (which_alternative == 3 || which_alternative == 4);
5770 switch (get_attr_type (insn))
5776 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5777 if (operands[2] == const1_rtx)
5778 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5781 gcc_assert (operands[2] == constm1_rtx);
5782 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5786 /* For most processors, ADD is faster than LEA. These alternatives
5787 were added to use ADD as much as possible. */
5788 if (which_alternative == 2 || which_alternative == 4)
5791 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5795 if (x86_maybe_negate_const_int (&operands[2], QImode))
5798 return "sub{l}\t{%2, %k0|%k0, %2}";
5800 return "sub{b}\t{%2, %0|%0, %2}";
5803 return "add{l}\t{%k2, %k0|%k0, %k2}";
5805 return "add{b}\t{%2, %0|%0, %2}";
5809 (cond [(eq_attr "alternative" "5")
5810 (const_string "lea")
5811 (match_operand:QI 2 "incdec_operand" "")
5812 (const_string "incdec")
5814 (const_string "alu")))
5815 (set (attr "length_immediate")
5817 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5819 (const_string "*")))
5820 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5822 (define_insn "*addqi_1_slp"
5823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5824 (plus:QI (match_dup 0)
5825 (match_operand:QI 1 "general_operand" "qn,qnm")))
5826 (clobber (reg:CC FLAGS_REG))]
5827 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5828 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5830 switch (get_attr_type (insn))
5833 if (operands[1] == const1_rtx)
5834 return "inc{b}\t%0";
5837 gcc_assert (operands[1] == constm1_rtx);
5838 return "dec{b}\t%0";
5842 if (x86_maybe_negate_const_int (&operands[1], QImode))
5843 return "sub{b}\t{%1, %0|%0, %1}";
5845 return "add{b}\t{%1, %0|%0, %1}";
5849 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5850 (const_string "incdec")
5851 (const_string "alu1")))
5852 (set (attr "memory")
5853 (if_then_else (match_operand 1 "memory_operand" "")
5854 (const_string "load")
5855 (const_string "none")))
5856 (set_attr "mode" "QI")])
5858 ;; Convert add to the lea pattern to avoid flags dependency.
5860 [(set (match_operand:SWI 0 "register_operand" "")
5861 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5862 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5867 enum machine_mode mode = <MODE>mode;
5870 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5873 operands[0] = gen_lowpart (mode, operands[0]);
5874 operands[1] = gen_lowpart (mode, operands[1]);
5875 operands[2] = gen_lowpart (mode, operands[2]);
5878 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5884 ;; Convert add to the lea pattern to avoid flags dependency.
5886 [(set (match_operand:DI 0 "register_operand" "")
5888 (plus:SI (match_operand:SI 1 "register_operand" "")
5889 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5890 (clobber (reg:CC FLAGS_REG))]
5891 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5893 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5895 (define_insn "*add<mode>_2"
5896 [(set (reg FLAGS_REG)
5899 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5900 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5902 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5903 (plus:SWI (match_dup 1) (match_dup 2)))]
5904 "ix86_match_ccmode (insn, CCGOCmode)
5905 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5907 switch (get_attr_type (insn))
5910 if (operands[2] == const1_rtx)
5911 return "inc{<imodesuffix>}\t%0";
5914 gcc_assert (operands[2] == constm1_rtx);
5915 return "dec{<imodesuffix>}\t%0";
5919 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5920 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5922 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5926 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5927 (const_string "incdec")
5928 (const_string "alu")))
5929 (set (attr "length_immediate")
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5933 (const_string "*")))
5934 (set_attr "mode" "<MODE>")])
5936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5937 (define_insn "*addsi_2_zext"
5938 [(set (reg FLAGS_REG)
5940 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5941 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5943 (set (match_operand:DI 0 "register_operand" "=r")
5944 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5945 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5946 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5948 switch (get_attr_type (insn))
5951 if (operands[2] == const1_rtx)
5952 return "inc{l}\t%k0";
5955 gcc_assert (operands[2] == constm1_rtx);
5956 return "dec{l}\t%k0";
5960 if (x86_maybe_negate_const_int (&operands[2], SImode))
5961 return "sub{l}\t{%2, %k0|%k0, %2}";
5963 return "add{l}\t{%2, %k0|%k0, %2}";
5967 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5968 (const_string "incdec")
5969 (const_string "alu")))
5970 (set (attr "length_immediate")
5972 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5974 (const_string "*")))
5975 (set_attr "mode" "SI")])
5977 (define_insn "*add<mode>_3"
5978 [(set (reg FLAGS_REG)
5980 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5981 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5982 (clobber (match_scratch:SWI 0 "=<r>"))]
5983 "ix86_match_ccmode (insn, CCZmode)
5984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5986 switch (get_attr_type (insn))
5989 if (operands[2] == const1_rtx)
5990 return "inc{<imodesuffix>}\t%0";
5993 gcc_assert (operands[2] == constm1_rtx);
5994 return "dec{<imodesuffix>}\t%0";
5998 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5999 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6001 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6005 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set (attr "length_immediate")
6010 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6012 (const_string "*")))
6013 (set_attr "mode" "<MODE>")])
6015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6016 (define_insn "*addsi_3_zext"
6017 [(set (reg FLAGS_REG)
6019 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
6020 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6021 (set (match_operand:DI 0 "register_operand" "=r")
6022 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6023 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6024 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6026 switch (get_attr_type (insn))
6029 if (operands[2] == const1_rtx)
6030 return "inc{l}\t%k0";
6033 gcc_assert (operands[2] == constm1_rtx);
6034 return "dec{l}\t%k0";
6038 if (x86_maybe_negate_const_int (&operands[2], SImode))
6039 return "sub{l}\t{%2, %k0|%k0, %2}";
6041 return "add{l}\t{%2, %k0|%k0, %2}";
6045 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6046 (const_string "incdec")
6047 (const_string "alu")))
6048 (set (attr "length_immediate")
6050 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6052 (const_string "*")))
6053 (set_attr "mode" "SI")])
6055 ; For comparisons against 1, -1 and 128, we may generate better code
6056 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6057 ; is matched then. We can't accept general immediate, because for
6058 ; case of overflows, the result is messed up.
6059 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6060 ; only for comparisons not depending on it.
6062 (define_insn "*adddi_4"
6063 [(set (reg FLAGS_REG)
6065 (match_operand:DI 1 "nonimmediate_operand" "0")
6066 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6067 (clobber (match_scratch:DI 0 "=rm"))]
6069 && ix86_match_ccmode (insn, CCGCmode)"
6071 switch (get_attr_type (insn))
6074 if (operands[2] == constm1_rtx)
6075 return "inc{q}\t%0";
6078 gcc_assert (operands[2] == const1_rtx);
6079 return "dec{q}\t%0";
6083 if (x86_maybe_negate_const_int (&operands[2], DImode))
6084 return "add{q}\t{%2, %0|%0, %2}";
6086 return "sub{q}\t{%2, %0|%0, %2}";
6090 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6091 (const_string "incdec")
6092 (const_string "alu")))
6093 (set (attr "length_immediate")
6095 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6097 (const_string "*")))
6098 (set_attr "mode" "DI")])
6100 ; For comparisons against 1, -1 and 128, we may generate better code
6101 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6102 ; is matched then. We can't accept general immediate, because for
6103 ; case of overflows, the result is messed up.
6104 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6105 ; only for comparisons not depending on it.
6107 (define_insn "*add<mode>_4"
6108 [(set (reg FLAGS_REG)
6110 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6111 (match_operand:SWI124 2 "const_int_operand" "n")))
6112 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6113 "ix86_match_ccmode (insn, CCGCmode)"
6115 switch (get_attr_type (insn))
6118 if (operands[2] == constm1_rtx)
6119 return "inc{<imodesuffix>}\t%0";
6122 gcc_assert (operands[2] == const1_rtx);
6123 return "dec{<imodesuffix>}\t%0";
6127 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6128 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6130 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6134 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set (attr "length_immediate")
6139 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141 (const_string "*")))
6142 (set_attr "mode" "<MODE>")])
6144 (define_insn "*add<mode>_5"
6145 [(set (reg FLAGS_REG)
6148 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6149 (match_operand:SWI 2 "<general_operand>" "<g>"))
6151 (clobber (match_scratch:SWI 0 "=<r>"))]
6152 "ix86_match_ccmode (insn, CCGOCmode)
6153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6155 switch (get_attr_type (insn))
6158 if (operands[2] == const1_rtx)
6159 return "inc{<imodesuffix>}\t%0";
6162 gcc_assert (operands[2] == constm1_rtx);
6163 return "dec{<imodesuffix>}\t%0";
6167 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6168 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6170 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6174 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set (attr "length_immediate")
6179 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6181 (const_string "*")))
6182 (set_attr "mode" "<MODE>")])
6184 (define_insn "*addqi_ext_1_rex64"
6185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6190 (match_operand 1 "ext_register_operand" "0")
6193 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6194 (clobber (reg:CC FLAGS_REG))]
6197 switch (get_attr_type (insn))
6200 if (operands[2] == const1_rtx)
6201 return "inc{b}\t%h0";
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{b}\t%h0";
6209 return "add{b}\t{%2, %h0|%h0, %2}";
6213 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6214 (const_string "incdec")
6215 (const_string "alu")))
6216 (set_attr "modrm" "1")
6217 (set_attr "mode" "QI")])
6219 (define_insn "addqi_ext_1"
6220 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6225 (match_operand 1 "ext_register_operand" "0")
6228 (match_operand:QI 2 "general_operand" "Qmn")))
6229 (clobber (reg:CC FLAGS_REG))]
6232 switch (get_attr_type (insn))
6235 if (operands[2] == const1_rtx)
6236 return "inc{b}\t%h0";
6239 gcc_assert (operands[2] == constm1_rtx);
6240 return "dec{b}\t%h0";
6244 return "add{b}\t{%2, %h0|%h0, %2}";
6248 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249 (const_string "incdec")
6250 (const_string "alu")))
6251 (set_attr "modrm" "1")
6252 (set_attr "mode" "QI")])
6254 (define_insn "*addqi_ext_2"
6255 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6260 (match_operand 1 "ext_register_operand" "%0")
6264 (match_operand 2 "ext_register_operand" "Q")
6267 (clobber (reg:CC FLAGS_REG))]
6269 "add{b}\t{%h2, %h0|%h0, %h2}"
6270 [(set_attr "type" "alu")
6271 (set_attr "mode" "QI")])
6273 ;; The lea patterns for modes less than 32 bits need to be matched by
6274 ;; several insns converted to real lea by splitters.
6276 (define_insn_and_split "*lea_general_1"
6277 [(set (match_operand 0 "register_operand" "=r")
6278 (plus (plus (match_operand 1 "index_register_operand" "l")
6279 (match_operand 2 "register_operand" "r"))
6280 (match_operand 3 "immediate_operand" "i")))]
6281 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6283 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6284 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6285 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6286 || GET_MODE (operands[3]) == VOIDmode)"
6288 "&& reload_completed"
6291 enum machine_mode mode = SImode;
6294 operands[0] = gen_lowpart (mode, operands[0]);
6295 operands[1] = gen_lowpart (mode, operands[1]);
6296 operands[2] = gen_lowpart (mode, operands[2]);
6297 operands[3] = gen_lowpart (mode, operands[3]);
6299 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6302 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6305 [(set_attr "type" "lea")
6306 (set_attr "mode" "SI")])
6308 (define_insn_and_split "*lea_general_2"
6309 [(set (match_operand 0 "register_operand" "=r")
6310 (plus (mult (match_operand 1 "index_register_operand" "l")
6311 (match_operand 2 "const248_operand" "n"))
6312 (match_operand 3 "nonmemory_operand" "ri")))]
6313 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6315 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6316 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6317 || GET_MODE (operands[3]) == VOIDmode)"
6319 "&& reload_completed"
6322 enum machine_mode mode = SImode;
6325 operands[0] = gen_lowpart (mode, operands[0]);
6326 operands[1] = gen_lowpart (mode, operands[1]);
6327 operands[3] = gen_lowpart (mode, operands[3]);
6329 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6332 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6335 [(set_attr "type" "lea")
6336 (set_attr "mode" "SI")])
6338 (define_insn_and_split "*lea_general_3"
6339 [(set (match_operand 0 "register_operand" "=r")
6340 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6341 (match_operand 2 "const248_operand" "n"))
6342 (match_operand 3 "register_operand" "r"))
6343 (match_operand 4 "immediate_operand" "i")))]
6344 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6346 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6349 "&& reload_completed"
6352 enum machine_mode mode = SImode;
6355 operands[0] = gen_lowpart (mode, operands[0]);
6356 operands[1] = gen_lowpart (mode, operands[1]);
6357 operands[3] = gen_lowpart (mode, operands[3]);
6358 operands[4] = gen_lowpart (mode, operands[4]);
6360 pat = gen_rtx_PLUS (mode,
6362 gen_rtx_MULT (mode, operands[1],
6367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370 [(set_attr "type" "lea")
6371 (set_attr "mode" "SI")])
6373 (define_insn_and_split "*lea_general_4"
6374 [(set (match_operand 0 "register_operand" "=r")
6376 (match_operand 1 "index_register_operand" "l")
6377 (match_operand 2 "const_int_operand" "n"))
6378 (match_operand 3 "const_int_operand" "n")))]
6379 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6380 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6381 || GET_MODE (operands[0]) == SImode
6382 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6383 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6384 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6385 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6386 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6388 "&& reload_completed"
6391 enum machine_mode mode = GET_MODE (operands[0]);
6394 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6397 operands[0] = gen_lowpart (mode, operands[0]);
6398 operands[1] = gen_lowpart (mode, operands[1]);
6401 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6403 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6404 INTVAL (operands[3]));
6406 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6409 [(set_attr "type" "lea")
6411 (if_then_else (match_operand:DI 0 "" "")
6413 (const_string "SI")))])
6415 ;; Subtract instructions
6417 (define_expand "sub<mode>3"
6418 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6419 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6420 (match_operand:SDWIM 2 "<general_operand>" "")))]
6422 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6424 (define_insn_and_split "*sub<dwi>3_doubleword"
6425 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6427 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6428 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433 [(parallel [(set (reg:CC FLAGS_REG)
6434 (compare:CC (match_dup 1) (match_dup 2)))
6436 (minus:DWIH (match_dup 1) (match_dup 2)))])
6437 (parallel [(set (match_dup 3)
6441 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6443 (clobber (reg:CC FLAGS_REG))])]
6444 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6446 (define_insn "*sub<mode>_1"
6447 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6450 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "mode" "<MODE>")])
6457 (define_insn "*subsi_1_zext"
6458 [(set (match_operand:DI 0 "register_operand" "=r")
6460 (minus:SI (match_operand:SI 1 "register_operand" "0")
6461 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6464 "sub{l}\t{%2, %k0|%k0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "mode" "SI")])
6468 (define_insn "*subqi_1_slp"
6469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6470 (minus:QI (match_dup 0)
6471 (match_operand:QI 1 "general_operand" "qn,qm")))
6472 (clobber (reg:CC FLAGS_REG))]
6473 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6475 "sub{b}\t{%1, %0|%0, %1}"
6476 [(set_attr "type" "alu1")
6477 (set_attr "mode" "QI")])
6479 (define_insn "*sub<mode>_2"
6480 [(set (reg FLAGS_REG)
6483 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6484 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6486 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6487 (minus:SWI (match_dup 1) (match_dup 2)))]
6488 "ix86_match_ccmode (insn, CCGOCmode)
6489 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6490 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "mode" "<MODE>")])
6494 (define_insn "*subsi_2_zext"
6495 [(set (reg FLAGS_REG)
6497 (minus:SI (match_operand:SI 1 "register_operand" "0")
6498 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6500 (set (match_operand:DI 0 "register_operand" "=r")
6502 (minus:SI (match_dup 1)
6504 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6505 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6506 "sub{l}\t{%2, %k0|%k0, %2}"
6507 [(set_attr "type" "alu")
6508 (set_attr "mode" "SI")])
6510 (define_insn "*sub<mode>_3"
6511 [(set (reg FLAGS_REG)
6512 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6513 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6514 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515 (minus:SWI (match_dup 1) (match_dup 2)))]
6516 "ix86_match_ccmode (insn, CCmode)
6517 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6518 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6519 [(set_attr "type" "alu")
6520 (set_attr "mode" "<MODE>")])
6522 (define_insn "*subsi_3_zext"
6523 [(set (reg FLAGS_REG)
6524 (compare (match_operand:SI 1 "register_operand" "0")
6525 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6526 (set (match_operand:DI 0 "register_operand" "=r")
6528 (minus:SI (match_dup 1)
6530 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6531 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6532 "sub{l}\t{%2, %1|%1, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "SI")])
6536 ;; Add with carry and subtract with borrow
6538 (define_expand "<plusminus_insn><mode>3_carry"
6540 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6542 (match_operand:SWI 1 "nonimmediate_operand" "")
6543 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6544 [(match_operand 3 "flags_reg_operand" "")
6546 (match_operand:SWI 2 "<general_operand>" ""))))
6547 (clobber (reg:CC FLAGS_REG))])]
6548 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6550 (define_insn "*<plusminus_insn><mode>3_carry"
6551 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6553 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6555 (match_operator 3 "ix86_carry_flag_operator"
6556 [(reg FLAGS_REG) (const_int 0)])
6557 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6558 (clobber (reg:CC FLAGS_REG))]
6559 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6560 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6561 [(set_attr "type" "alu")
6562 (set_attr "use_carry" "1")
6563 (set_attr "pent_pair" "pu")
6564 (set_attr "mode" "<MODE>")])
6566 (define_insn "*addsi3_carry_zext"
6567 [(set (match_operand:DI 0 "register_operand" "=r")
6569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6570 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6571 [(reg FLAGS_REG) (const_int 0)])
6572 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6575 "adc{l}\t{%2, %k0|%k0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "use_carry" "1")
6578 (set_attr "pent_pair" "pu")
6579 (set_attr "mode" "SI")])
6581 (define_insn "*subsi3_carry_zext"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (minus:SI (match_operand:SI 1 "register_operand" "0")
6585 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6590 "sbb{l}\t{%2, %k0|%k0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "pent_pair" "pu")
6593 (set_attr "mode" "SI")])
6595 ;; Overflow setting add and subtract instructions
6597 (define_insn "*add<mode>3_cconly_overflow"
6598 [(set (reg:CCC FLAGS_REG)
6601 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6602 (match_operand:SWI 2 "<general_operand>" "<g>"))
6604 (clobber (match_scratch:SWI 0 "=<r>"))]
6605 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6606 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "mode" "<MODE>")])
6610 (define_insn "*sub<mode>3_cconly_overflow"
6611 [(set (reg:CCC FLAGS_REG)
6614 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6615 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6618 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6619 [(set_attr "type" "icmp")
6620 (set_attr "mode" "<MODE>")])
6622 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6623 [(set (reg:CCC FLAGS_REG)
6626 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6627 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6629 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6630 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6631 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6632 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "mode" "<MODE>")])
6636 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6637 [(set (reg:CCC FLAGS_REG)
6640 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6641 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6643 (set (match_operand:DI 0 "register_operand" "=r")
6644 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6645 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6646 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6647 [(set_attr "type" "alu")
6648 (set_attr "mode" "SI")])
6650 ;; The patterns that match these are at the end of this file.
6652 (define_expand "<plusminus_insn>xf3"
6653 [(set (match_operand:XF 0 "register_operand" "")
6655 (match_operand:XF 1 "register_operand" "")
6656 (match_operand:XF 2 "register_operand" "")))]
6659 (define_expand "<plusminus_insn><mode>3"
6660 [(set (match_operand:MODEF 0 "register_operand" "")
6662 (match_operand:MODEF 1 "register_operand" "")
6663 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6664 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6665 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6667 ;; Multiply instructions
6669 (define_expand "mul<mode>3"
6670 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6672 (match_operand:SWIM248 1 "register_operand" "")
6673 (match_operand:SWIM248 2 "<general_operand>" "")))
6674 (clobber (reg:CC FLAGS_REG))])])
6676 (define_expand "mulqi3"
6677 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6679 (match_operand:QI 1 "register_operand" "")
6680 (match_operand:QI 2 "nonimmediate_operand" "")))
6681 (clobber (reg:CC FLAGS_REG))])]
6682 "TARGET_QIMODE_MATH")
6685 ;; IMUL reg32/64, reg32/64, imm8 Direct
6686 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6687 ;; IMUL reg32/64, reg32/64, imm32 Direct
6688 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6689 ;; IMUL reg32/64, reg32/64 Direct
6690 ;; IMUL reg32/64, mem32/64 Direct
6692 ;; On BDVER1, all above IMULs use DirectPath
6694 (define_insn "*mul<mode>3_1"
6695 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6697 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6698 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6699 (clobber (reg:CC FLAGS_REG))]
6700 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6702 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6703 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6704 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6705 [(set_attr "type" "imul")
6706 (set_attr "prefix_0f" "0,0,1")
6707 (set (attr "athlon_decode")
6708 (cond [(eq_attr "cpu" "athlon")
6709 (const_string "vector")
6710 (eq_attr "alternative" "1")
6711 (const_string "vector")
6712 (and (eq_attr "alternative" "2")
6713 (match_operand 1 "memory_operand" ""))
6714 (const_string "vector")]
6715 (const_string "direct")))
6716 (set (attr "amdfam10_decode")
6717 (cond [(and (eq_attr "alternative" "0,1")
6718 (match_operand 1 "memory_operand" ""))
6719 (const_string "vector")]
6720 (const_string "direct")))
6721 (set_attr "bdver1_decode" "direct")
6722 (set_attr "mode" "<MODE>")])
6724 (define_insn "*mulsi3_1_zext"
6725 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6727 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6728 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6729 (clobber (reg:CC FLAGS_REG))]
6731 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6734 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6735 imul{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "imul")
6737 (set_attr "prefix_0f" "0,0,1")
6738 (set (attr "athlon_decode")
6739 (cond [(eq_attr "cpu" "athlon")
6740 (const_string "vector")
6741 (eq_attr "alternative" "1")
6742 (const_string "vector")
6743 (and (eq_attr "alternative" "2")
6744 (match_operand 1 "memory_operand" ""))
6745 (const_string "vector")]
6746 (const_string "direct")))
6747 (set (attr "amdfam10_decode")
6748 (cond [(and (eq_attr "alternative" "0,1")
6749 (match_operand 1 "memory_operand" ""))
6750 (const_string "vector")]
6751 (const_string "direct")))
6752 (set_attr "bdver1_decode" "direct")
6753 (set_attr "mode" "SI")])
6756 ;; IMUL reg16, reg16, imm8 VectorPath
6757 ;; IMUL reg16, mem16, imm8 VectorPath
6758 ;; IMUL reg16, reg16, imm16 VectorPath
6759 ;; IMUL reg16, mem16, imm16 VectorPath
6760 ;; IMUL reg16, reg16 Direct
6761 ;; IMUL reg16, mem16 Direct
6763 ;; On BDVER1, all HI MULs use DoublePath
6765 (define_insn "*mulhi3_1"
6766 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6767 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6768 (match_operand:HI 2 "general_operand" "K,n,mr")))
6769 (clobber (reg:CC FLAGS_REG))]
6771 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6773 imul{w}\t{%2, %1, %0|%0, %1, %2}
6774 imul{w}\t{%2, %1, %0|%0, %1, %2}
6775 imul{w}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "imul")
6777 (set_attr "prefix_0f" "0,0,1")
6778 (set (attr "athlon_decode")
6779 (cond [(eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (eq_attr "alternative" "1,2")
6782 (const_string "vector")]
6783 (const_string "direct")))
6784 (set (attr "amdfam10_decode")
6785 (cond [(eq_attr "alternative" "0,1")
6786 (const_string "vector")]
6787 (const_string "direct")))
6788 (set_attr "bdver1_decode" "double")
6789 (set_attr "mode" "HI")])
6791 ;;On AMDFAM10 and BDVER1
6795 (define_insn "*mulqi3_1"
6796 [(set (match_operand:QI 0 "register_operand" "=a")
6797 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6798 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6799 (clobber (reg:CC FLAGS_REG))]
6801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 [(set_attr "type" "imul")
6804 (set_attr "length_immediate" "0")
6805 (set (attr "athlon_decode")
6806 (if_then_else (eq_attr "cpu" "athlon")
6807 (const_string "vector")
6808 (const_string "direct")))
6809 (set_attr "amdfam10_decode" "direct")
6810 (set_attr "bdver1_decode" "direct")
6811 (set_attr "mode" "QI")])
6813 (define_expand "<u>mul<mode><dwi>3"
6814 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6817 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6819 (match_operand:DWIH 2 "register_operand" ""))))
6820 (clobber (reg:CC FLAGS_REG))])])
6822 (define_expand "<u>mulqihi3"
6823 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6826 (match_operand:QI 1 "nonimmediate_operand" ""))
6828 (match_operand:QI 2 "register_operand" ""))))
6829 (clobber (reg:CC FLAGS_REG))])]
6830 "TARGET_QIMODE_MATH")
6832 (define_insn "*<u>mul<mode><dwi>3_1"
6833 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6836 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6838 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6839 (clobber (reg:CC FLAGS_REG))]
6840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 "<sgnprefix>mul{<imodesuffix>}\t%2"
6842 [(set_attr "type" "imul")
6843 (set_attr "length_immediate" "0")
6844 (set (attr "athlon_decode")
6845 (if_then_else (eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (const_string "double")))
6848 (set_attr "amdfam10_decode" "double")
6849 (set_attr "bdver1_decode" "direct")
6850 (set_attr "mode" "<MODE>")])
6852 (define_insn "*<u>mulqihi3_1"
6853 [(set (match_operand:HI 0 "register_operand" "=a")
6856 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6858 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6859 (clobber (reg:CC FLAGS_REG))]
6861 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862 "<sgnprefix>mul{b}\t%2"
6863 [(set_attr "type" "imul")
6864 (set_attr "length_immediate" "0")
6865 (set (attr "athlon_decode")
6866 (if_then_else (eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (const_string "direct")))
6869 (set_attr "amdfam10_decode" "direct")
6870 (set_attr "bdver1_decode" "direct")
6871 (set_attr "mode" "QI")])
6873 (define_expand "<s>mul<mode>3_highpart"
6874 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6879 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6881 (match_operand:SWI48 2 "register_operand" "")))
6883 (clobber (match_scratch:SWI48 3 ""))
6884 (clobber (reg:CC FLAGS_REG))])]
6886 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6888 (define_insn "*<s>muldi3_highpart_1"
6889 [(set (match_operand:DI 0 "register_operand" "=d")
6894 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6896 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6898 (clobber (match_scratch:DI 3 "=1"))
6899 (clobber (reg:CC FLAGS_REG))]
6901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 "<sgnprefix>mul{q}\t%2"
6903 [(set_attr "type" "imul")
6904 (set_attr "length_immediate" "0")
6905 (set (attr "athlon_decode")
6906 (if_then_else (eq_attr "cpu" "athlon")
6907 (const_string "vector")
6908 (const_string "double")))
6909 (set_attr "amdfam10_decode" "double")
6910 (set_attr "bdver1_decode" "direct")
6911 (set_attr "mode" "DI")])
6913 (define_insn "*<s>mulsi3_highpart_1"
6914 [(set (match_operand:SI 0 "register_operand" "=d")
6919 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6921 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6923 (clobber (match_scratch:SI 3 "=1"))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926 "<sgnprefix>mul{l}\t%2"
6927 [(set_attr "type" "imul")
6928 (set_attr "length_immediate" "0")
6929 (set (attr "athlon_decode")
6930 (if_then_else (eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (const_string "double")))
6933 (set_attr "amdfam10_decode" "double")
6934 (set_attr "bdver1_decode" "direct")
6935 (set_attr "mode" "SI")])
6937 (define_insn "*<s>mulsi3_highpart_zext"
6938 [(set (match_operand:DI 0 "register_operand" "=d")
6939 (zero_extend:DI (truncate:SI
6941 (mult:DI (any_extend:DI
6942 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6944 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6946 (clobber (match_scratch:SI 3 "=1"))
6947 (clobber (reg:CC FLAGS_REG))]
6949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "<sgnprefix>mul{l}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "SI")])
6961 ;; The patterns that match these are at the end of this file.
6963 (define_expand "mulxf3"
6964 [(set (match_operand:XF 0 "register_operand" "")
6965 (mult:XF (match_operand:XF 1 "register_operand" "")
6966 (match_operand:XF 2 "register_operand" "")))]
6969 (define_expand "mul<mode>3"
6970 [(set (match_operand:MODEF 0 "register_operand" "")
6971 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6972 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6973 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6974 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6976 ;; Divide instructions
6978 ;; The patterns that match these are at the end of this file.
6980 (define_expand "divxf3"
6981 [(set (match_operand:XF 0 "register_operand" "")
6982 (div:XF (match_operand:XF 1 "register_operand" "")
6983 (match_operand:XF 2 "register_operand" "")))]
6986 (define_expand "divdf3"
6987 [(set (match_operand:DF 0 "register_operand" "")
6988 (div:DF (match_operand:DF 1 "register_operand" "")
6989 (match_operand:DF 2 "nonimmediate_operand" "")))]
6990 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6991 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6993 (define_expand "divsf3"
6994 [(set (match_operand:SF 0 "register_operand" "")
6995 (div:SF (match_operand:SF 1 "register_operand" "")
6996 (match_operand:SF 2 "nonimmediate_operand" "")))]
6997 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7000 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7001 && flag_finite_math_only && !flag_trapping_math
7002 && flag_unsafe_math_optimizations)
7004 ix86_emit_swdivsf (operands[0], operands[1],
7005 operands[2], SFmode);
7010 ;; Divmod instructions.
7012 (define_expand "divmod<mode>4"
7013 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7015 (match_operand:SWIM248 1 "register_operand" "")
7016 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7017 (set (match_operand:SWIM248 3 "register_operand" "")
7018 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7019 (clobber (reg:CC FLAGS_REG))])])
7021 ;; Split with 8bit unsigned divide:
7022 ;; if (dividend an divisor are in [0-255])
7023 ;; use 8bit unsigned integer divide
7025 ;; use original integer divide
7027 [(set (match_operand:SWI48 0 "register_operand" "")
7028 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7029 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7030 (set (match_operand:SWI48 1 "register_operand" "")
7031 (mod:SWI48 (match_dup 2) (match_dup 3)))
7032 (clobber (reg:CC FLAGS_REG))]
7033 "TARGET_USE_8BIT_IDIV
7034 && TARGET_QIMODE_MATH
7035 && can_create_pseudo_p ()
7036 && !optimize_insn_for_size_p ()"
7038 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7040 (define_insn_and_split "divmod<mode>4_1"
7041 [(set (match_operand:SWI48 0 "register_operand" "=a")
7042 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7043 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7044 (set (match_operand:SWI48 1 "register_operand" "=&d")
7045 (mod:SWI48 (match_dup 2) (match_dup 3)))
7046 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7047 (clobber (reg:CC FLAGS_REG))]
7051 [(parallel [(set (match_dup 1)
7052 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7053 (clobber (reg:CC FLAGS_REG))])
7054 (parallel [(set (match_dup 0)
7055 (div:SWI48 (match_dup 2) (match_dup 3)))
7057 (mod:SWI48 (match_dup 2) (match_dup 3)))
7059 (clobber (reg:CC FLAGS_REG))])]
7061 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7063 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7064 operands[4] = operands[2];
7067 /* Avoid use of cltd in favor of a mov+shift. */
7068 emit_move_insn (operands[1], operands[2]);
7069 operands[4] = operands[1];
7072 [(set_attr "type" "multi")
7073 (set_attr "mode" "<MODE>")])
7075 (define_insn_and_split "*divmod<mode>4"
7076 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7077 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7078 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7079 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7080 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7081 (clobber (reg:CC FLAGS_REG))]
7085 [(parallel [(set (match_dup 1)
7086 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7087 (clobber (reg:CC FLAGS_REG))])
7088 (parallel [(set (match_dup 0)
7089 (div:SWIM248 (match_dup 2) (match_dup 3)))
7091 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7093 (clobber (reg:CC FLAGS_REG))])]
7095 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7097 if (<MODE>mode != HImode
7098 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7099 operands[4] = operands[2];
7102 /* Avoid use of cltd in favor of a mov+shift. */
7103 emit_move_insn (operands[1], operands[2]);
7104 operands[4] = operands[1];
7107 [(set_attr "type" "multi")
7108 (set_attr "mode" "<MODE>")])
7110 (define_insn "*divmod<mode>4_noext"
7111 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7112 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7113 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7114 (set (match_operand:SWIM248 1 "register_operand" "=d")
7115 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (use (match_operand:SWIM248 4 "register_operand" "1"))
7117 (clobber (reg:CC FLAGS_REG))]
7119 "idiv{<imodesuffix>}\t%3"
7120 [(set_attr "type" "idiv")
7121 (set_attr "mode" "<MODE>")])
7123 (define_expand "divmodqi4"
7124 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7126 (match_operand:QI 1 "register_operand" "")
7127 (match_operand:QI 2 "nonimmediate_operand" "")))
7128 (set (match_operand:QI 3 "register_operand" "")
7129 (mod:QI (match_dup 1) (match_dup 2)))
7130 (clobber (reg:CC FLAGS_REG))])]
7131 "TARGET_QIMODE_MATH"
7136 tmp0 = gen_reg_rtx (HImode);
7137 tmp1 = gen_reg_rtx (HImode);
7139 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7141 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7142 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7144 /* Extract remainder from AH. */
7145 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7146 insn = emit_move_insn (operands[3], tmp1);
7148 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7149 set_unique_reg_note (insn, REG_EQUAL, mod);
7151 /* Extract quotient from AL. */
7152 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7154 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7155 set_unique_reg_note (insn, REG_EQUAL, div);
7160 ;; Divide AX by r/m8, with result stored in
7163 ;; Change div/mod to HImode and extend the second argument to HImode
7164 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7165 ;; combine may fail.
7166 (define_insn "divmodhiqi3"
7167 [(set (match_operand:HI 0 "register_operand" "=a")
7172 (mod:HI (match_operand:HI 1 "register_operand" "0")
7174 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7178 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "TARGET_QIMODE_MATH"
7182 [(set_attr "type" "idiv")
7183 (set_attr "mode" "QI")])
7185 (define_expand "udivmod<mode>4"
7186 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7188 (match_operand:SWIM248 1 "register_operand" "")
7189 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7190 (set (match_operand:SWIM248 3 "register_operand" "")
7191 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7192 (clobber (reg:CC FLAGS_REG))])])
7194 ;; Split with 8bit unsigned divide:
7195 ;; if (dividend an divisor are in [0-255])
7196 ;; use 8bit unsigned integer divide
7198 ;; use original integer divide
7200 [(set (match_operand:SWI48 0 "register_operand" "")
7201 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7202 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7203 (set (match_operand:SWI48 1 "register_operand" "")
7204 (umod:SWI48 (match_dup 2) (match_dup 3)))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "TARGET_USE_8BIT_IDIV
7207 && TARGET_QIMODE_MATH
7208 && can_create_pseudo_p ()
7209 && !optimize_insn_for_size_p ()"
7211 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7213 (define_insn_and_split "udivmod<mode>4_1"
7214 [(set (match_operand:SWI48 0 "register_operand" "=a")
7215 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7216 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7217 (set (match_operand:SWI48 1 "register_operand" "=&d")
7218 (umod:SWI48 (match_dup 2) (match_dup 3)))
7219 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7220 (clobber (reg:CC FLAGS_REG))]
7224 [(set (match_dup 1) (const_int 0))
7225 (parallel [(set (match_dup 0)
7226 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7228 (umod:SWI48 (match_dup 2) (match_dup 3)))
7230 (clobber (reg:CC FLAGS_REG))])]
7232 [(set_attr "type" "multi")
7233 (set_attr "mode" "<MODE>")])
7235 (define_insn_and_split "*udivmod<mode>4"
7236 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7237 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7238 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7239 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7240 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7241 (clobber (reg:CC FLAGS_REG))]
7245 [(set (match_dup 1) (const_int 0))
7246 (parallel [(set (match_dup 0)
7247 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7249 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7251 (clobber (reg:CC FLAGS_REG))])]
7253 [(set_attr "type" "multi")
7254 (set_attr "mode" "<MODE>")])
7256 (define_insn "*udivmod<mode>4_noext"
7257 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7258 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7259 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7260 (set (match_operand:SWIM248 1 "register_operand" "=d")
7261 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7262 (use (match_operand:SWIM248 4 "register_operand" "1"))
7263 (clobber (reg:CC FLAGS_REG))]
7265 "div{<imodesuffix>}\t%3"
7266 [(set_attr "type" "idiv")
7267 (set_attr "mode" "<MODE>")])
7269 (define_expand "udivmodqi4"
7270 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7272 (match_operand:QI 1 "register_operand" "")
7273 (match_operand:QI 2 "nonimmediate_operand" "")))
7274 (set (match_operand:QI 3 "register_operand" "")
7275 (umod:QI (match_dup 1) (match_dup 2)))
7276 (clobber (reg:CC FLAGS_REG))])]
7277 "TARGET_QIMODE_MATH"
7282 tmp0 = gen_reg_rtx (HImode);
7283 tmp1 = gen_reg_rtx (HImode);
7285 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7287 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7288 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7290 /* Extract remainder from AH. */
7291 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7292 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7293 insn = emit_move_insn (operands[3], tmp1);
7295 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7296 set_unique_reg_note (insn, REG_EQUAL, mod);
7298 /* Extract quotient from AL. */
7299 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7301 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7302 set_unique_reg_note (insn, REG_EQUAL, div);
7307 (define_insn "udivmodhiqi3"
7308 [(set (match_operand:HI 0 "register_operand" "=a")
7313 (mod:HI (match_operand:HI 1 "register_operand" "0")
7315 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7319 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7320 (clobber (reg:CC FLAGS_REG))]
7321 "TARGET_QIMODE_MATH"
7323 [(set_attr "type" "idiv")
7324 (set_attr "mode" "QI")])
7326 ;; We cannot use div/idiv for double division, because it causes
7327 ;; "division by zero" on the overflow and that's not what we expect
7328 ;; from truncate. Because true (non truncating) double division is
7329 ;; never generated, we can't create this insn anyway.
7332 ; [(set (match_operand:SI 0 "register_operand" "=a")
7334 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7336 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7337 ; (set (match_operand:SI 3 "register_operand" "=d")
7339 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7340 ; (clobber (reg:CC FLAGS_REG))]
7342 ; "div{l}\t{%2, %0|%0, %2}"
7343 ; [(set_attr "type" "idiv")])
7345 ;;- Logical AND instructions
7347 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7348 ;; Note that this excludes ah.
7350 (define_expand "testsi_ccno_1"
7351 [(set (reg:CCNO FLAGS_REG)
7353 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7354 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7357 (define_expand "testqi_ccz_1"
7358 [(set (reg:CCZ FLAGS_REG)
7359 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7360 (match_operand:QI 1 "nonmemory_operand" ""))
7363 (define_expand "testdi_ccno_1"
7364 [(set (reg:CCNO FLAGS_REG)
7366 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7367 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7369 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7371 (define_insn "*testdi_1"
7372 [(set (reg FLAGS_REG)
7375 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7376 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7378 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7379 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7381 test{l}\t{%k1, %k0|%k0, %k1}
7382 test{l}\t{%k1, %k0|%k0, %k1}
7383 test{q}\t{%1, %0|%0, %1}
7384 test{q}\t{%1, %0|%0, %1}
7385 test{q}\t{%1, %0|%0, %1}"
7386 [(set_attr "type" "test")
7387 (set_attr "modrm" "0,1,0,1,1")
7388 (set_attr "mode" "SI,SI,DI,DI,DI")])
7390 (define_insn "*testqi_1_maybe_si"
7391 [(set (reg FLAGS_REG)
7394 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7395 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7397 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7398 && ix86_match_ccmode (insn,
7399 CONST_INT_P (operands[1])
7400 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7402 if (which_alternative == 3)
7404 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7405 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7406 return "test{l}\t{%1, %k0|%k0, %1}";
7408 return "test{b}\t{%1, %0|%0, %1}";
7410 [(set_attr "type" "test")
7411 (set_attr "modrm" "0,1,1,1")
7412 (set_attr "mode" "QI,QI,QI,SI")
7413 (set_attr "pent_pair" "uv,np,uv,np")])
7415 (define_insn "*test<mode>_1"
7416 [(set (reg FLAGS_REG)
7419 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7420 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7422 "ix86_match_ccmode (insn, CCNOmode)
7423 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7424 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7425 [(set_attr "type" "test")
7426 (set_attr "modrm" "0,1,1")
7427 (set_attr "mode" "<MODE>")
7428 (set_attr "pent_pair" "uv,np,uv")])
7430 (define_expand "testqi_ext_ccno_0"
7431 [(set (reg:CCNO FLAGS_REG)
7435 (match_operand 0 "ext_register_operand" "")
7438 (match_operand 1 "const_int_operand" ""))
7441 (define_insn "*testqi_ext_0"
7442 [(set (reg FLAGS_REG)
7446 (match_operand 0 "ext_register_operand" "Q")
7449 (match_operand 1 "const_int_operand" "n"))
7451 "ix86_match_ccmode (insn, CCNOmode)"
7452 "test{b}\t{%1, %h0|%h0, %1}"
7453 [(set_attr "type" "test")
7454 (set_attr "mode" "QI")
7455 (set_attr "length_immediate" "1")
7456 (set_attr "modrm" "1")
7457 (set_attr "pent_pair" "np")])
7459 (define_insn "*testqi_ext_1_rex64"
7460 [(set (reg FLAGS_REG)
7464 (match_operand 0 "ext_register_operand" "Q")
7468 (match_operand:QI 1 "register_operand" "Q")))
7470 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7471 "test{b}\t{%1, %h0|%h0, %1}"
7472 [(set_attr "type" "test")
7473 (set_attr "mode" "QI")])
7475 (define_insn "*testqi_ext_1"
7476 [(set (reg FLAGS_REG)
7480 (match_operand 0 "ext_register_operand" "Q")
7484 (match_operand:QI 1 "general_operand" "Qm")))
7486 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7487 "test{b}\t{%1, %h0|%h0, %1}"
7488 [(set_attr "type" "test")
7489 (set_attr "mode" "QI")])
7491 (define_insn "*testqi_ext_2"
7492 [(set (reg FLAGS_REG)
7496 (match_operand 0 "ext_register_operand" "Q")
7500 (match_operand 1 "ext_register_operand" "Q")
7504 "ix86_match_ccmode (insn, CCNOmode)"
7505 "test{b}\t{%h1, %h0|%h0, %h1}"
7506 [(set_attr "type" "test")
7507 (set_attr "mode" "QI")])
7509 (define_insn "*testqi_ext_3_rex64"
7510 [(set (reg FLAGS_REG)
7511 (compare (zero_extract:DI
7512 (match_operand 0 "nonimmediate_operand" "rm")
7513 (match_operand:DI 1 "const_int_operand" "")
7514 (match_operand:DI 2 "const_int_operand" ""))
7517 && ix86_match_ccmode (insn, CCNOmode)
7518 && INTVAL (operands[1]) > 0
7519 && INTVAL (operands[2]) >= 0
7520 /* Ensure that resulting mask is zero or sign extended operand. */
7521 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7522 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7523 && INTVAL (operands[1]) > 32))
7524 && (GET_MODE (operands[0]) == SImode
7525 || GET_MODE (operands[0]) == DImode
7526 || GET_MODE (operands[0]) == HImode
7527 || GET_MODE (operands[0]) == QImode)"
7530 ;; Combine likes to form bit extractions for some tests. Humor it.
7531 (define_insn "*testqi_ext_3"
7532 [(set (reg FLAGS_REG)
7533 (compare (zero_extract:SI
7534 (match_operand 0 "nonimmediate_operand" "rm")
7535 (match_operand:SI 1 "const_int_operand" "")
7536 (match_operand:SI 2 "const_int_operand" ""))
7538 "ix86_match_ccmode (insn, CCNOmode)
7539 && INTVAL (operands[1]) > 0
7540 && INTVAL (operands[2]) >= 0
7541 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7542 && (GET_MODE (operands[0]) == SImode
7543 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7544 || GET_MODE (operands[0]) == HImode
7545 || GET_MODE (operands[0]) == QImode)"
7549 [(set (match_operand 0 "flags_reg_operand" "")
7550 (match_operator 1 "compare_operator"
7552 (match_operand 2 "nonimmediate_operand" "")
7553 (match_operand 3 "const_int_operand" "")
7554 (match_operand 4 "const_int_operand" ""))
7556 "ix86_match_ccmode (insn, CCNOmode)"
7557 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7559 rtx val = operands[2];
7560 HOST_WIDE_INT len = INTVAL (operands[3]);
7561 HOST_WIDE_INT pos = INTVAL (operands[4]);
7563 enum machine_mode mode, submode;
7565 mode = GET_MODE (val);
7568 /* ??? Combine likes to put non-volatile mem extractions in QImode
7569 no matter the size of the test. So find a mode that works. */
7570 if (! MEM_VOLATILE_P (val))
7572 mode = smallest_mode_for_size (pos + len, MODE_INT);
7573 val = adjust_address (val, mode, 0);
7576 else if (GET_CODE (val) == SUBREG
7577 && (submode = GET_MODE (SUBREG_REG (val)),
7578 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7579 && pos + len <= GET_MODE_BITSIZE (submode)
7580 && GET_MODE_CLASS (submode) == MODE_INT)
7582 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7584 val = SUBREG_REG (val);
7586 else if (mode == HImode && pos + len <= 8)
7588 /* Small HImode tests can be converted to QImode. */
7590 val = gen_lowpart (QImode, val);
7593 if (len == HOST_BITS_PER_WIDE_INT)
7596 mask = ((HOST_WIDE_INT)1 << len) - 1;
7599 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7602 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7603 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7604 ;; this is relatively important trick.
7605 ;; Do the conversion only post-reload to avoid limiting of the register class
7608 [(set (match_operand 0 "flags_reg_operand" "")
7609 (match_operator 1 "compare_operator"
7610 [(and (match_operand 2 "register_operand" "")
7611 (match_operand 3 "const_int_operand" ""))
7614 && QI_REG_P (operands[2])
7615 && GET_MODE (operands[2]) != QImode
7616 && ((ix86_match_ccmode (insn, CCZmode)
7617 && !(INTVAL (operands[3]) & ~(255 << 8)))
7618 || (ix86_match_ccmode (insn, CCNOmode)
7619 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7622 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7625 "operands[2] = gen_lowpart (SImode, operands[2]);
7626 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7629 [(set (match_operand 0 "flags_reg_operand" "")
7630 (match_operator 1 "compare_operator"
7631 [(and (match_operand 2 "nonimmediate_operand" "")
7632 (match_operand 3 "const_int_operand" ""))
7635 && GET_MODE (operands[2]) != QImode
7636 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7637 && ((ix86_match_ccmode (insn, CCZmode)
7638 && !(INTVAL (operands[3]) & ~255))
7639 || (ix86_match_ccmode (insn, CCNOmode)
7640 && !(INTVAL (operands[3]) & ~127)))"
7642 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7644 "operands[2] = gen_lowpart (QImode, operands[2]);
7645 operands[3] = gen_lowpart (QImode, operands[3]);")
7647 ;; %%% This used to optimize known byte-wide and operations to memory,
7648 ;; and sometimes to QImode registers. If this is considered useful,
7649 ;; it should be done with splitters.
7651 (define_expand "and<mode>3"
7652 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7653 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7654 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7656 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7658 (define_insn "*anddi_1"
7659 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7661 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7662 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7666 switch (get_attr_type (insn))
7670 enum machine_mode mode;
7672 gcc_assert (CONST_INT_P (operands[2]));
7673 if (INTVAL (operands[2]) == 0xff)
7677 gcc_assert (INTVAL (operands[2]) == 0xffff);
7681 operands[1] = gen_lowpart (mode, operands[1]);
7683 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7685 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7690 if (get_attr_mode (insn) == MODE_SI)
7691 return "and{l}\t{%k2, %k0|%k0, %k2}";
7693 return "and{q}\t{%2, %0|%0, %2}";
7696 [(set_attr "type" "alu,alu,alu,imovx")
7697 (set_attr "length_immediate" "*,*,*,0")
7698 (set (attr "prefix_rex")
7700 (and (eq_attr "type" "imovx")
7701 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7702 (match_operand 1 "ext_QIreg_operand" "")))
7704 (const_string "*")))
7705 (set_attr "mode" "SI,DI,DI,SI")])
7707 (define_insn "*andsi_1"
7708 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7709 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7710 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "ix86_binary_operator_ok (AND, SImode, operands)"
7714 switch (get_attr_type (insn))
7718 enum machine_mode mode;
7720 gcc_assert (CONST_INT_P (operands[2]));
7721 if (INTVAL (operands[2]) == 0xff)
7725 gcc_assert (INTVAL (operands[2]) == 0xffff);
7729 operands[1] = gen_lowpart (mode, operands[1]);
7731 return "movz{bl|x}\t{%1, %0|%0, %1}";
7733 return "movz{wl|x}\t{%1, %0|%0, %1}";
7737 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7738 return "and{l}\t{%2, %0|%0, %2}";
7741 [(set_attr "type" "alu,alu,imovx")
7742 (set (attr "prefix_rex")
7744 (and (eq_attr "type" "imovx")
7745 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7746 (match_operand 1 "ext_QIreg_operand" "")))
7748 (const_string "*")))
7749 (set_attr "length_immediate" "*,*,0")
7750 (set_attr "mode" "SI")])
7752 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7753 (define_insn "*andsi_1_zext"
7754 [(set (match_operand:DI 0 "register_operand" "=r")
7756 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7757 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7760 "and{l}\t{%2, %k0|%k0, %2}"
7761 [(set_attr "type" "alu")
7762 (set_attr "mode" "SI")])
7764 (define_insn "*andhi_1"
7765 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7766 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7767 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7768 (clobber (reg:CC FLAGS_REG))]
7769 "ix86_binary_operator_ok (AND, HImode, operands)"
7771 switch (get_attr_type (insn))
7774 gcc_assert (CONST_INT_P (operands[2]));
7775 gcc_assert (INTVAL (operands[2]) == 0xff);
7776 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7779 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7781 return "and{w}\t{%2, %0|%0, %2}";
7784 [(set_attr "type" "alu,alu,imovx")
7785 (set_attr "length_immediate" "*,*,0")
7786 (set (attr "prefix_rex")
7788 (and (eq_attr "type" "imovx")
7789 (match_operand 1 "ext_QIreg_operand" ""))
7791 (const_string "*")))
7792 (set_attr "mode" "HI,HI,SI")])
7794 ;; %%% Potential partial reg stall on alternative 2. What to do?
7795 (define_insn "*andqi_1"
7796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7797 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7798 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7799 (clobber (reg:CC FLAGS_REG))]
7800 "ix86_binary_operator_ok (AND, QImode, operands)"
7802 and{b}\t{%2, %0|%0, %2}
7803 and{b}\t{%2, %0|%0, %2}
7804 and{l}\t{%k2, %k0|%k0, %k2}"
7805 [(set_attr "type" "alu")
7806 (set_attr "mode" "QI,QI,SI")])
7808 (define_insn "*andqi_1_slp"
7809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7810 (and:QI (match_dup 0)
7811 (match_operand:QI 1 "general_operand" "qn,qmn")))
7812 (clobber (reg:CC FLAGS_REG))]
7813 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815 "and{b}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "alu1")
7817 (set_attr "mode" "QI")])
7820 [(set (match_operand 0 "register_operand" "")
7822 (const_int -65536)))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7825 || optimize_function_for_size_p (cfun)"
7826 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7827 "operands[1] = gen_lowpart (HImode, operands[0]);")
7830 [(set (match_operand 0 "ext_register_operand" "")
7833 (clobber (reg:CC FLAGS_REG))]
7834 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7835 && reload_completed"
7836 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7837 "operands[1] = gen_lowpart (QImode, operands[0]);")
7840 [(set (match_operand 0 "ext_register_operand" "")
7842 (const_int -65281)))
7843 (clobber (reg:CC FLAGS_REG))]
7844 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7845 && reload_completed"
7846 [(parallel [(set (zero_extract:SI (match_dup 0)
7850 (zero_extract:SI (match_dup 0)
7853 (zero_extract:SI (match_dup 0)
7856 (clobber (reg:CC FLAGS_REG))])]
7857 "operands[0] = gen_lowpart (SImode, operands[0]);")
7859 (define_insn "*anddi_2"
7860 [(set (reg FLAGS_REG)
7863 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7864 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7866 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7867 (and:DI (match_dup 1) (match_dup 2)))]
7868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7869 && ix86_binary_operator_ok (AND, DImode, operands)"
7871 and{l}\t{%k2, %k0|%k0, %k2}
7872 and{q}\t{%2, %0|%0, %2}
7873 and{q}\t{%2, %0|%0, %2}"
7874 [(set_attr "type" "alu")
7875 (set_attr "mode" "SI,DI,DI")])
7877 (define_insn "*andqi_2_maybe_si"
7878 [(set (reg FLAGS_REG)
7880 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7881 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7883 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7884 (and:QI (match_dup 1) (match_dup 2)))]
7885 "ix86_binary_operator_ok (AND, QImode, operands)
7886 && ix86_match_ccmode (insn,
7887 CONST_INT_P (operands[2])
7888 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7890 if (which_alternative == 2)
7892 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7893 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7894 return "and{l}\t{%2, %k0|%k0, %2}";
7896 return "and{b}\t{%2, %0|%0, %2}";
7898 [(set_attr "type" "alu")
7899 (set_attr "mode" "QI,QI,SI")])
7901 (define_insn "*and<mode>_2"
7902 [(set (reg FLAGS_REG)
7903 (compare (and:SWI124
7904 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7905 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7907 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7908 (and:SWI124 (match_dup 1) (match_dup 2)))]
7909 "ix86_match_ccmode (insn, CCNOmode)
7910 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7911 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7912 [(set_attr "type" "alu")
7913 (set_attr "mode" "<MODE>")])
7915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7916 (define_insn "*andsi_2_zext"
7917 [(set (reg FLAGS_REG)
7919 (match_operand:SI 1 "nonimmediate_operand" "%0")
7920 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7922 (set (match_operand:DI 0 "register_operand" "=r")
7923 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7924 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7925 && ix86_binary_operator_ok (AND, SImode, operands)"
7926 "and{l}\t{%2, %k0|%k0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "SI")])
7930 (define_insn "*andqi_2_slp"
7931 [(set (reg FLAGS_REG)
7933 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7934 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7936 (set (strict_low_part (match_dup 0))
7937 (and:QI (match_dup 0) (match_dup 1)))]
7938 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7939 && ix86_match_ccmode (insn, CCNOmode)
7940 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7941 "and{b}\t{%1, %0|%0, %1}"
7942 [(set_attr "type" "alu1")
7943 (set_attr "mode" "QI")])
7945 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7946 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7947 ;; for a QImode operand, which of course failed.
7948 (define_insn "andqi_ext_0"
7949 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7954 (match_operand 1 "ext_register_operand" "0")
7957 (match_operand 2 "const_int_operand" "n")))
7958 (clobber (reg:CC FLAGS_REG))]
7960 "and{b}\t{%2, %h0|%h0, %2}"
7961 [(set_attr "type" "alu")
7962 (set_attr "length_immediate" "1")
7963 (set_attr "modrm" "1")
7964 (set_attr "mode" "QI")])
7966 ;; Generated by peephole translating test to and. This shows up
7967 ;; often in fp comparisons.
7968 (define_insn "*andqi_ext_0_cc"
7969 [(set (reg FLAGS_REG)
7973 (match_operand 1 "ext_register_operand" "0")
7976 (match_operand 2 "const_int_operand" "n"))
7978 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7987 "ix86_match_ccmode (insn, CCNOmode)"
7988 "and{b}\t{%2, %h0|%h0, %2}"
7989 [(set_attr "type" "alu")
7990 (set_attr "length_immediate" "1")
7991 (set_attr "modrm" "1")
7992 (set_attr "mode" "QI")])
7994 (define_insn "*andqi_ext_1_rex64"
7995 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8000 (match_operand 1 "ext_register_operand" "0")
8004 (match_operand 2 "ext_register_operand" "Q"))))
8005 (clobber (reg:CC FLAGS_REG))]
8007 "and{b}\t{%2, %h0|%h0, %2}"
8008 [(set_attr "type" "alu")
8009 (set_attr "length_immediate" "0")
8010 (set_attr "mode" "QI")])
8012 (define_insn "*andqi_ext_1"
8013 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8018 (match_operand 1 "ext_register_operand" "0")
8022 (match_operand:QI 2 "general_operand" "Qm"))))
8023 (clobber (reg:CC FLAGS_REG))]
8025 "and{b}\t{%2, %h0|%h0, %2}"
8026 [(set_attr "type" "alu")
8027 (set_attr "length_immediate" "0")
8028 (set_attr "mode" "QI")])
8030 (define_insn "*andqi_ext_2"
8031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8036 (match_operand 1 "ext_register_operand" "%0")
8040 (match_operand 2 "ext_register_operand" "Q")
8043 (clobber (reg:CC FLAGS_REG))]
8045 "and{b}\t{%h2, %h0|%h0, %h2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "length_immediate" "0")
8048 (set_attr "mode" "QI")])
8050 ;; Convert wide AND instructions with immediate operand to shorter QImode
8051 ;; equivalents when possible.
8052 ;; Don't do the splitting with memory operands, since it introduces risk
8053 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8054 ;; for size, but that can (should?) be handled by generic code instead.
8056 [(set (match_operand 0 "register_operand" "")
8057 (and (match_operand 1 "register_operand" "")
8058 (match_operand 2 "const_int_operand" "")))
8059 (clobber (reg:CC FLAGS_REG))]
8061 && QI_REG_P (operands[0])
8062 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8063 && !(~INTVAL (operands[2]) & ~(255 << 8))
8064 && GET_MODE (operands[0]) != QImode"
8065 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8066 (and:SI (zero_extract:SI (match_dup 1)
8067 (const_int 8) (const_int 8))
8069 (clobber (reg:CC FLAGS_REG))])]
8070 "operands[0] = gen_lowpart (SImode, operands[0]);
8071 operands[1] = gen_lowpart (SImode, operands[1]);
8072 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8074 ;; Since AND can be encoded with sign extended immediate, this is only
8075 ;; profitable when 7th bit is not set.
8077 [(set (match_operand 0 "register_operand" "")
8078 (and (match_operand 1 "general_operand" "")
8079 (match_operand 2 "const_int_operand" "")))
8080 (clobber (reg:CC FLAGS_REG))]
8082 && ANY_QI_REG_P (operands[0])
8083 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8084 && !(~INTVAL (operands[2]) & ~255)
8085 && !(INTVAL (operands[2]) & 128)
8086 && GET_MODE (operands[0]) != QImode"
8087 [(parallel [(set (strict_low_part (match_dup 0))
8088 (and:QI (match_dup 1)
8090 (clobber (reg:CC FLAGS_REG))])]
8091 "operands[0] = gen_lowpart (QImode, operands[0]);
8092 operands[1] = gen_lowpart (QImode, operands[1]);
8093 operands[2] = gen_lowpart (QImode, operands[2]);")
8095 ;; Logical inclusive and exclusive OR instructions
8097 ;; %%% This used to optimize known byte-wide and operations to memory.
8098 ;; If this is considered useful, it should be done with splitters.
8100 (define_expand "<code><mode>3"
8101 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8102 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8103 (match_operand:SWIM 2 "<general_operand>" "")))]
8105 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8107 (define_insn "*<code><mode>_1"
8108 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8110 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8111 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8112 (clobber (reg:CC FLAGS_REG))]
8113 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8114 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "<MODE>")])
8118 ;; %%% Potential partial reg stall on alternative 2. What to do?
8119 (define_insn "*<code>qi_1"
8120 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8121 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8122 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8123 (clobber (reg:CC FLAGS_REG))]
8124 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8126 <logic>{b}\t{%2, %0|%0, %2}
8127 <logic>{b}\t{%2, %0|%0, %2}
8128 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8129 [(set_attr "type" "alu")
8130 (set_attr "mode" "QI,QI,SI")])
8132 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8133 (define_insn "*<code>si_1_zext"
8134 [(set (match_operand:DI 0 "register_operand" "=r")
8136 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8137 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8140 "<logic>{l}\t{%2, %k0|%k0, %2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "mode" "SI")])
8144 (define_insn "*<code>si_1_zext_imm"
8145 [(set (match_operand:DI 0 "register_operand" "=r")
8147 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8148 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8149 (clobber (reg:CC FLAGS_REG))]
8150 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8151 "<logic>{l}\t{%2, %k0|%k0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "SI")])
8155 (define_insn "*<code>qi_1_slp"
8156 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8157 (any_or:QI (match_dup 0)
8158 (match_operand:QI 1 "general_operand" "qmn,qn")))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8162 "<logic>{b}\t{%1, %0|%0, %1}"
8163 [(set_attr "type" "alu1")
8164 (set_attr "mode" "QI")])
8166 (define_insn "*<code><mode>_2"
8167 [(set (reg FLAGS_REG)
8168 (compare (any_or:SWI
8169 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8170 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8172 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8173 (any_or:SWI (match_dup 1) (match_dup 2)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8176 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "<MODE>")])
8180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8181 ;; ??? Special case for immediate operand is missing - it is tricky.
8182 (define_insn "*<code>si_2_zext"
8183 [(set (reg FLAGS_REG)
8184 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8185 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8187 (set (match_operand:DI 0 "register_operand" "=r")
8188 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8189 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8190 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8191 "<logic>{l}\t{%2, %k0|%k0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "SI")])
8195 (define_insn "*<code>si_2_zext_imm"
8196 [(set (reg FLAGS_REG)
8198 (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8201 (set (match_operand:DI 0 "register_operand" "=r")
8202 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8205 "<logic>{l}\t{%2, %k0|%k0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 (define_insn "*<code>qi_2_slp"
8210 [(set (reg FLAGS_REG)
8211 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8212 (match_operand:QI 1 "general_operand" "qmn,qn"))
8214 (set (strict_low_part (match_dup 0))
8215 (any_or:QI (match_dup 0) (match_dup 1)))]
8216 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8217 && ix86_match_ccmode (insn, CCNOmode)
8218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8219 "<logic>{b}\t{%1, %0|%0, %1}"
8220 [(set_attr "type" "alu1")
8221 (set_attr "mode" "QI")])
8223 (define_insn "*<code><mode>_3"
8224 [(set (reg FLAGS_REG)
8225 (compare (any_or:SWI
8226 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8227 (match_operand:SWI 2 "<general_operand>" "<g>"))
8229 (clobber (match_scratch:SWI 0 "=<r>"))]
8230 "ix86_match_ccmode (insn, CCNOmode)
8231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8232 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8233 [(set_attr "type" "alu")
8234 (set_attr "mode" "<MODE>")])
8236 (define_insn "*<code>qi_ext_0"
8237 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242 (match_operand 1 "ext_register_operand" "0")
8245 (match_operand 2 "const_int_operand" "n")))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8248 "<logic>{b}\t{%2, %h0|%h0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "length_immediate" "1")
8251 (set_attr "modrm" "1")
8252 (set_attr "mode" "QI")])
8254 (define_insn "*<code>qi_ext_1_rex64"
8255 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8260 (match_operand 1 "ext_register_operand" "0")
8264 (match_operand 2 "ext_register_operand" "Q"))))
8265 (clobber (reg:CC FLAGS_REG))]
8267 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8268 "<logic>{b}\t{%2, %h0|%h0, %2}"
8269 [(set_attr "type" "alu")
8270 (set_attr "length_immediate" "0")
8271 (set_attr "mode" "QI")])
8273 (define_insn "*<code>qi_ext_1"
8274 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8279 (match_operand 1 "ext_register_operand" "0")
8283 (match_operand:QI 2 "general_operand" "Qm"))))
8284 (clobber (reg:CC FLAGS_REG))]
8286 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8287 "<logic>{b}\t{%2, %h0|%h0, %2}"
8288 [(set_attr "type" "alu")
8289 (set_attr "length_immediate" "0")
8290 (set_attr "mode" "QI")])
8292 (define_insn "*<code>qi_ext_2"
8293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8297 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8300 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8303 (clobber (reg:CC FLAGS_REG))]
8304 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8305 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "length_immediate" "0")
8308 (set_attr "mode" "QI")])
8311 [(set (match_operand 0 "register_operand" "")
8312 (any_or (match_operand 1 "register_operand" "")
8313 (match_operand 2 "const_int_operand" "")))
8314 (clobber (reg:CC FLAGS_REG))]
8316 && QI_REG_P (operands[0])
8317 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8318 && !(INTVAL (operands[2]) & ~(255 << 8))
8319 && GET_MODE (operands[0]) != QImode"
8320 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8321 (any_or:SI (zero_extract:SI (match_dup 1)
8322 (const_int 8) (const_int 8))
8324 (clobber (reg:CC FLAGS_REG))])]
8325 "operands[0] = gen_lowpart (SImode, operands[0]);
8326 operands[1] = gen_lowpart (SImode, operands[1]);
8327 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8329 ;; Since OR can be encoded with sign extended immediate, this is only
8330 ;; profitable when 7th bit is set.
8332 [(set (match_operand 0 "register_operand" "")
8333 (any_or (match_operand 1 "general_operand" "")
8334 (match_operand 2 "const_int_operand" "")))
8335 (clobber (reg:CC FLAGS_REG))]
8337 && ANY_QI_REG_P (operands[0])
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8339 && !(INTVAL (operands[2]) & ~255)
8340 && (INTVAL (operands[2]) & 128)
8341 && GET_MODE (operands[0]) != QImode"
8342 [(parallel [(set (strict_low_part (match_dup 0))
8343 (any_or:QI (match_dup 1)
8345 (clobber (reg:CC FLAGS_REG))])]
8346 "operands[0] = gen_lowpart (QImode, operands[0]);
8347 operands[1] = gen_lowpart (QImode, operands[1]);
8348 operands[2] = gen_lowpart (QImode, operands[2]);")
8350 (define_expand "xorqi_cc_ext_1"
8352 (set (reg:CCNO FLAGS_REG)
8356 (match_operand 1 "ext_register_operand" "")
8359 (match_operand:QI 2 "general_operand" ""))
8361 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8371 (define_insn "*xorqi_cc_ext_1_rex64"
8372 [(set (reg FLAGS_REG)
8376 (match_operand 1 "ext_register_operand" "0")
8379 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8381 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8390 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8391 "xor{b}\t{%2, %h0|%h0, %2}"
8392 [(set_attr "type" "alu")
8393 (set_attr "modrm" "1")
8394 (set_attr "mode" "QI")])
8396 (define_insn "*xorqi_cc_ext_1"
8397 [(set (reg FLAGS_REG)
8401 (match_operand 1 "ext_register_operand" "0")
8404 (match_operand:QI 2 "general_operand" "qmn"))
8406 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8415 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8416 "xor{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "modrm" "1")
8419 (set_attr "mode" "QI")])
8421 ;; Negation instructions
8423 (define_expand "neg<mode>2"
8424 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8425 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8427 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8429 (define_insn_and_split "*neg<dwi>2_doubleword"
8430 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8431 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8437 [(set (reg:CCZ FLAGS_REG)
8438 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8439 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8442 (plus:DWIH (match_dup 3)
8443 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8445 (clobber (reg:CC FLAGS_REG))])
8448 (neg:DWIH (match_dup 2)))
8449 (clobber (reg:CC FLAGS_REG))])]
8450 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8452 (define_insn "*neg<mode>2_1"
8453 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8454 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8455 (clobber (reg:CC FLAGS_REG))]
8456 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8457 "neg{<imodesuffix>}\t%0"
8458 [(set_attr "type" "negnot")
8459 (set_attr "mode" "<MODE>")])
8461 ;; Combine is quite creative about this pattern.
8462 (define_insn "*negsi2_1_zext"
8463 [(set (match_operand:DI 0 "register_operand" "=r")
8465 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8468 (clobber (reg:CC FLAGS_REG))]
8469 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8471 [(set_attr "type" "negnot")
8472 (set_attr "mode" "SI")])
8474 ;; The problem with neg is that it does not perform (compare x 0),
8475 ;; it really performs (compare 0 x), which leaves us with the zero
8476 ;; flag being the only useful item.
8478 (define_insn "*neg<mode>2_cmpz"
8479 [(set (reg:CCZ FLAGS_REG)
8481 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8483 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8484 (neg:SWI (match_dup 1)))]
8485 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8486 "neg{<imodesuffix>}\t%0"
8487 [(set_attr "type" "negnot")
8488 (set_attr "mode" "<MODE>")])
8490 (define_insn "*negsi2_cmpz_zext"
8491 [(set (reg:CCZ FLAGS_REG)
8495 (match_operand:DI 1 "register_operand" "0")
8499 (set (match_operand:DI 0 "register_operand" "=r")
8500 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8503 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8505 [(set_attr "type" "negnot")
8506 (set_attr "mode" "SI")])
8508 ;; Changing of sign for FP values is doable using integer unit too.
8510 (define_expand "<code><mode>2"
8511 [(set (match_operand:X87MODEF 0 "register_operand" "")
8512 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8513 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8514 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8516 (define_insn "*absneg<mode>2_mixed"
8517 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8518 (match_operator:MODEF 3 "absneg_operator"
8519 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8520 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8525 (define_insn "*absneg<mode>2_sse"
8526 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8527 (match_operator:MODEF 3 "absneg_operator"
8528 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8529 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8534 (define_insn "*absneg<mode>2_i387"
8535 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8536 (match_operator:X87MODEF 3 "absneg_operator"
8537 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8538 (use (match_operand 2 "" ""))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8543 (define_expand "<code>tf2"
8544 [(set (match_operand:TF 0 "register_operand" "")
8545 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8547 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8549 (define_insn "*absnegtf2_sse"
8550 [(set (match_operand:TF 0 "register_operand" "=x,x")
8551 (match_operator:TF 3 "absneg_operator"
8552 [(match_operand:TF 1 "register_operand" "0,x")]))
8553 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8554 (clobber (reg:CC FLAGS_REG))]
8558 ;; Splitters for fp abs and neg.
8561 [(set (match_operand 0 "fp_register_operand" "")
8562 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8563 (use (match_operand 2 "" ""))
8564 (clobber (reg:CC FLAGS_REG))]
8566 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8569 [(set (match_operand 0 "register_operand" "")
8570 (match_operator 3 "absneg_operator"
8571 [(match_operand 1 "register_operand" "")]))
8572 (use (match_operand 2 "nonimmediate_operand" ""))
8573 (clobber (reg:CC FLAGS_REG))]
8574 "reload_completed && SSE_REG_P (operands[0])"
8575 [(set (match_dup 0) (match_dup 3))]
8577 enum machine_mode mode = GET_MODE (operands[0]);
8578 enum machine_mode vmode = GET_MODE (operands[2]);
8581 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8582 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8583 if (operands_match_p (operands[0], operands[2]))
8586 operands[1] = operands[2];
8589 if (GET_CODE (operands[3]) == ABS)
8590 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8592 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8597 [(set (match_operand:SF 0 "register_operand" "")
8598 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8599 (use (match_operand:V4SF 2 "" ""))
8600 (clobber (reg:CC FLAGS_REG))]
8602 [(parallel [(set (match_dup 0) (match_dup 1))
8603 (clobber (reg:CC FLAGS_REG))])]
8606 operands[0] = gen_lowpart (SImode, operands[0]);
8607 if (GET_CODE (operands[1]) == ABS)
8609 tmp = gen_int_mode (0x7fffffff, SImode);
8610 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8614 tmp = gen_int_mode (0x80000000, SImode);
8615 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8621 [(set (match_operand:DF 0 "register_operand" "")
8622 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8623 (use (match_operand 2 "" ""))
8624 (clobber (reg:CC FLAGS_REG))]
8626 [(parallel [(set (match_dup 0) (match_dup 1))
8627 (clobber (reg:CC FLAGS_REG))])]
8632 tmp = gen_lowpart (DImode, operands[0]);
8633 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8636 if (GET_CODE (operands[1]) == ABS)
8639 tmp = gen_rtx_NOT (DImode, tmp);
8643 operands[0] = gen_highpart (SImode, operands[0]);
8644 if (GET_CODE (operands[1]) == ABS)
8646 tmp = gen_int_mode (0x7fffffff, SImode);
8647 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8651 tmp = gen_int_mode (0x80000000, SImode);
8652 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8659 [(set (match_operand:XF 0 "register_operand" "")
8660 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8661 (use (match_operand 2 "" ""))
8662 (clobber (reg:CC FLAGS_REG))]
8664 [(parallel [(set (match_dup 0) (match_dup 1))
8665 (clobber (reg:CC FLAGS_REG))])]
8668 operands[0] = gen_rtx_REG (SImode,
8669 true_regnum (operands[0])
8670 + (TARGET_64BIT ? 1 : 2));
8671 if (GET_CODE (operands[1]) == ABS)
8673 tmp = GEN_INT (0x7fff);
8674 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8678 tmp = GEN_INT (0x8000);
8679 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8684 ;; Conditionalize these after reload. If they match before reload, we
8685 ;; lose the clobber and ability to use integer instructions.
8687 (define_insn "*<code><mode>2_1"
8688 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8689 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8691 && (reload_completed
8692 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8693 "f<absneg_mnemonic>"
8694 [(set_attr "type" "fsgn")
8695 (set_attr "mode" "<MODE>")])
8697 (define_insn "*<code>extendsfdf2"
8698 [(set (match_operand:DF 0 "register_operand" "=f")
8699 (absneg:DF (float_extend:DF
8700 (match_operand:SF 1 "register_operand" "0"))))]
8701 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8702 "f<absneg_mnemonic>"
8703 [(set_attr "type" "fsgn")
8704 (set_attr "mode" "DF")])
8706 (define_insn "*<code>extendsfxf2"
8707 [(set (match_operand:XF 0 "register_operand" "=f")
8708 (absneg:XF (float_extend:XF
8709 (match_operand:SF 1 "register_operand" "0"))))]
8711 "f<absneg_mnemonic>"
8712 [(set_attr "type" "fsgn")
8713 (set_attr "mode" "XF")])
8715 (define_insn "*<code>extenddfxf2"
8716 [(set (match_operand:XF 0 "register_operand" "=f")
8717 (absneg:XF (float_extend:XF
8718 (match_operand:DF 1 "register_operand" "0"))))]
8720 "f<absneg_mnemonic>"
8721 [(set_attr "type" "fsgn")
8722 (set_attr "mode" "XF")])
8724 ;; Copysign instructions
8726 (define_mode_iterator CSGNMODE [SF DF TF])
8727 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8729 (define_expand "copysign<mode>3"
8730 [(match_operand:CSGNMODE 0 "register_operand" "")
8731 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8732 (match_operand:CSGNMODE 2 "register_operand" "")]
8733 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8734 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8735 "ix86_expand_copysign (operands); DONE;")
8737 (define_insn_and_split "copysign<mode>3_const"
8738 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8740 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8741 (match_operand:CSGNMODE 2 "register_operand" "0")
8742 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8744 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8745 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8747 "&& reload_completed"
8749 "ix86_split_copysign_const (operands); DONE;")
8751 (define_insn "copysign<mode>3_var"
8752 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8754 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8755 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8756 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8757 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8759 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8760 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8761 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8765 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8767 [(match_operand:CSGNMODE 2 "register_operand" "")
8768 (match_operand:CSGNMODE 3 "register_operand" "")
8769 (match_operand:<CSGNVMODE> 4 "" "")
8770 (match_operand:<CSGNVMODE> 5 "" "")]
8772 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8773 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8774 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8775 && reload_completed"
8777 "ix86_split_copysign_var (operands); DONE;")
8779 ;; One complement instructions
8781 (define_expand "one_cmpl<mode>2"
8782 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8783 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8785 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8787 (define_insn "*one_cmpl<mode>2_1"
8788 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8789 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8790 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8791 "not{<imodesuffix>}\t%0"
8792 [(set_attr "type" "negnot")
8793 (set_attr "mode" "<MODE>")])
8795 ;; %%% Potential partial reg stall on alternative 1. What to do?
8796 (define_insn "*one_cmplqi2_1"
8797 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8798 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8799 "ix86_unary_operator_ok (NOT, QImode, operands)"
8803 [(set_attr "type" "negnot")
8804 (set_attr "mode" "QI,SI")])
8806 ;; ??? Currently never generated - xor is used instead.
8807 (define_insn "*one_cmplsi2_1_zext"
8808 [(set (match_operand:DI 0 "register_operand" "=r")
8810 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8811 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8813 [(set_attr "type" "negnot")
8814 (set_attr "mode" "SI")])
8816 (define_insn "*one_cmpl<mode>2_2"
8817 [(set (reg FLAGS_REG)
8818 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8821 (not:SWI (match_dup 1)))]
8822 "ix86_match_ccmode (insn, CCNOmode)
8823 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8825 [(set_attr "type" "alu1")
8826 (set_attr "mode" "<MODE>")])
8829 [(set (match_operand 0 "flags_reg_operand" "")
8830 (match_operator 2 "compare_operator"
8831 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8833 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8834 (not:SWI (match_dup 3)))]
8835 "ix86_match_ccmode (insn, CCNOmode)"
8836 [(parallel [(set (match_dup 0)
8837 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8840 (xor:SWI (match_dup 3) (const_int -1)))])])
8842 ;; ??? Currently never generated - xor is used instead.
8843 (define_insn "*one_cmplsi2_2_zext"
8844 [(set (reg FLAGS_REG)
8845 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8847 (set (match_operand:DI 0 "register_operand" "=r")
8848 (zero_extend:DI (not:SI (match_dup 1))))]
8849 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8850 && ix86_unary_operator_ok (NOT, SImode, operands)"
8852 [(set_attr "type" "alu1")
8853 (set_attr "mode" "SI")])
8856 [(set (match_operand 0 "flags_reg_operand" "")
8857 (match_operator 2 "compare_operator"
8858 [(not:SI (match_operand:SI 3 "register_operand" ""))
8860 (set (match_operand:DI 1 "register_operand" "")
8861 (zero_extend:DI (not:SI (match_dup 3))))]
8862 "ix86_match_ccmode (insn, CCNOmode)"
8863 [(parallel [(set (match_dup 0)
8864 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8867 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8869 ;; Shift instructions
8871 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8872 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8873 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8874 ;; from the assembler input.
8876 ;; This instruction shifts the target reg/mem as usual, but instead of
8877 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8878 ;; is a left shift double, bits are taken from the high order bits of
8879 ;; reg, else if the insn is a shift right double, bits are taken from the
8880 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8881 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8883 ;; Since sh[lr]d does not change the `reg' operand, that is done
8884 ;; separately, making all shifts emit pairs of shift double and normal
8885 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8886 ;; support a 63 bit shift, each shift where the count is in a reg expands
8887 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8889 ;; If the shift count is a constant, we need never emit more than one
8890 ;; shift pair, instead using moves and sign extension for counts greater
8893 (define_expand "ashl<mode>3"
8894 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8895 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8896 (match_operand:QI 2 "nonmemory_operand" "")))]
8898 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8900 (define_insn "*ashl<mode>3_doubleword"
8901 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8902 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8903 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8904 (clobber (reg:CC FLAGS_REG))]
8907 [(set_attr "type" "multi")])
8910 [(set (match_operand:DWI 0 "register_operand" "")
8911 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8912 (match_operand:QI 2 "nonmemory_operand" "")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8916 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8918 ;; By default we don't ask for a scratch register, because when DWImode
8919 ;; values are manipulated, registers are already at a premium. But if
8920 ;; we have one handy, we won't turn it away.
8923 [(match_scratch:DWIH 3 "r")
8924 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8926 (match_operand:<DWI> 1 "nonmemory_operand" "")
8927 (match_operand:QI 2 "nonmemory_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))])
8932 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8934 (define_insn "x86_64_shld"
8935 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8936 (ior:DI (ashift:DI (match_dup 0)
8937 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8938 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8939 (minus:QI (const_int 64) (match_dup 2)))))
8940 (clobber (reg:CC FLAGS_REG))]
8942 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8943 [(set_attr "type" "ishift")
8944 (set_attr "prefix_0f" "1")
8945 (set_attr "mode" "DI")
8946 (set_attr "athlon_decode" "vector")
8947 (set_attr "amdfam10_decode" "vector")
8948 (set_attr "bdver1_decode" "vector")])
8950 (define_insn "x86_shld"
8951 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8952 (ior:SI (ashift:SI (match_dup 0)
8953 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8954 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8955 (minus:QI (const_int 32) (match_dup 2)))))
8956 (clobber (reg:CC FLAGS_REG))]
8958 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8959 [(set_attr "type" "ishift")
8960 (set_attr "prefix_0f" "1")
8961 (set_attr "mode" "SI")
8962 (set_attr "pent_pair" "np")
8963 (set_attr "athlon_decode" "vector")
8964 (set_attr "amdfam10_decode" "vector")
8965 (set_attr "bdver1_decode" "vector")])
8967 (define_expand "x86_shift<mode>_adj_1"
8968 [(set (reg:CCZ FLAGS_REG)
8969 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8972 (set (match_operand:SWI48 0 "register_operand" "")
8973 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8974 (match_operand:SWI48 1 "register_operand" "")
8977 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8978 (match_operand:SWI48 3 "register_operand" "r")
8981 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8983 (define_expand "x86_shift<mode>_adj_2"
8984 [(use (match_operand:SWI48 0 "register_operand" ""))
8985 (use (match_operand:SWI48 1 "register_operand" ""))
8986 (use (match_operand:QI 2 "register_operand" ""))]
8989 rtx label = gen_label_rtx ();
8992 emit_insn (gen_testqi_ccz_1 (operands[2],
8993 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8995 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8996 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8997 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8998 gen_rtx_LABEL_REF (VOIDmode, label),
9000 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9001 JUMP_LABEL (tmp) = label;
9003 emit_move_insn (operands[0], operands[1]);
9004 ix86_expand_clear (operands[1]);
9007 LABEL_NUSES (label) = 1;
9012 ;; Avoid useless masking of count operand.
9013 (define_insn_and_split "*ashl<mode>3_mask"
9014 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9016 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9019 (match_operand:SI 2 "nonimmediate_operand" "c")
9020 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9023 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9024 == GET_MODE_BITSIZE (<MODE>mode)-1"
9027 [(parallel [(set (match_dup 0)
9028 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9029 (clobber (reg:CC FLAGS_REG))])]
9031 if (can_create_pseudo_p ())
9032 operands [2] = force_reg (SImode, operands[2]);
9034 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9036 [(set_attr "type" "ishift")
9037 (set_attr "mode" "<MODE>")])
9039 (define_insn "*ashl<mode>3_1"
9040 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9041 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9042 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9046 switch (get_attr_type (insn))
9052 gcc_assert (operands[2] == const1_rtx);
9053 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9054 return "add{<imodesuffix>}\t%0, %0";
9057 if (operands[2] == const1_rtx
9058 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9059 return "sal{<imodesuffix>}\t%0";
9061 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9065 (cond [(eq_attr "alternative" "1")
9066 (const_string "lea")
9067 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9069 (match_operand 0 "register_operand" ""))
9070 (match_operand 2 "const1_operand" ""))
9071 (const_string "alu")
9073 (const_string "ishift")))
9074 (set (attr "length_immediate")
9076 (ior (eq_attr "type" "alu")
9077 (and (eq_attr "type" "ishift")
9078 (and (match_operand 2 "const1_operand" "")
9079 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9082 (const_string "*")))
9083 (set_attr "mode" "<MODE>")])
9085 (define_insn "*ashlsi3_1_zext"
9086 [(set (match_operand:DI 0 "register_operand" "=r,r")
9088 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9089 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9093 switch (get_attr_type (insn))
9099 gcc_assert (operands[2] == const1_rtx);
9100 return "add{l}\t%k0, %k0";
9103 if (operands[2] == const1_rtx
9104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9105 return "sal{l}\t%k0";
9107 return "sal{l}\t{%2, %k0|%k0, %2}";
9111 (cond [(eq_attr "alternative" "1")
9112 (const_string "lea")
9113 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9115 (match_operand 2 "const1_operand" ""))
9116 (const_string "alu")
9118 (const_string "ishift")))
9119 (set (attr "length_immediate")
9121 (ior (eq_attr "type" "alu")
9122 (and (eq_attr "type" "ishift")
9123 (and (match_operand 2 "const1_operand" "")
9124 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9127 (const_string "*")))
9128 (set_attr "mode" "SI")])
9130 (define_insn "*ashlhi3_1"
9131 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9132 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9133 (match_operand:QI 2 "nonmemory_operand" "cI")))
9134 (clobber (reg:CC FLAGS_REG))]
9135 "TARGET_PARTIAL_REG_STALL
9136 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9138 switch (get_attr_type (insn))
9141 gcc_assert (operands[2] == const1_rtx);
9142 return "add{w}\t%0, %0";
9145 if (operands[2] == const1_rtx
9146 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9147 return "sal{w}\t%0";
9149 return "sal{w}\t{%2, %0|%0, %2}";
9153 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9155 (match_operand 0 "register_operand" ""))
9156 (match_operand 2 "const1_operand" ""))
9157 (const_string "alu")
9159 (const_string "ishift")))
9160 (set (attr "length_immediate")
9162 (ior (eq_attr "type" "alu")
9163 (and (eq_attr "type" "ishift")
9164 (and (match_operand 2 "const1_operand" "")
9165 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9168 (const_string "*")))
9169 (set_attr "mode" "HI")])
9171 (define_insn "*ashlhi3_1_lea"
9172 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9173 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9174 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9175 (clobber (reg:CC FLAGS_REG))]
9176 "!TARGET_PARTIAL_REG_STALL
9177 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9179 switch (get_attr_type (insn))
9185 gcc_assert (operands[2] == const1_rtx);
9186 return "add{w}\t%0, %0";
9189 if (operands[2] == const1_rtx
9190 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9191 return "sal{w}\t%0";
9193 return "sal{w}\t{%2, %0|%0, %2}";
9197 (cond [(eq_attr "alternative" "1")
9198 (const_string "lea")
9199 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9201 (match_operand 0 "register_operand" ""))
9202 (match_operand 2 "const1_operand" ""))
9203 (const_string "alu")
9205 (const_string "ishift")))
9206 (set (attr "length_immediate")
9208 (ior (eq_attr "type" "alu")
9209 (and (eq_attr "type" "ishift")
9210 (and (match_operand 2 "const1_operand" "")
9211 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9214 (const_string "*")))
9215 (set_attr "mode" "HI,SI")])
9217 (define_insn "*ashlqi3_1"
9218 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9219 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9220 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9221 (clobber (reg:CC FLAGS_REG))]
9222 "TARGET_PARTIAL_REG_STALL
9223 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9225 switch (get_attr_type (insn))
9228 gcc_assert (operands[2] == const1_rtx);
9229 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9230 return "add{l}\t%k0, %k0";
9232 return "add{b}\t%0, %0";
9235 if (operands[2] == const1_rtx
9236 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9238 if (get_attr_mode (insn) == MODE_SI)
9239 return "sal{l}\t%k0";
9241 return "sal{b}\t%0";
9245 if (get_attr_mode (insn) == MODE_SI)
9246 return "sal{l}\t{%2, %k0|%k0, %2}";
9248 return "sal{b}\t{%2, %0|%0, %2}";
9253 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9255 (match_operand 0 "register_operand" ""))
9256 (match_operand 2 "const1_operand" ""))
9257 (const_string "alu")
9259 (const_string "ishift")))
9260 (set (attr "length_immediate")
9262 (ior (eq_attr "type" "alu")
9263 (and (eq_attr "type" "ishift")
9264 (and (match_operand 2 "const1_operand" "")
9265 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9268 (const_string "*")))
9269 (set_attr "mode" "QI,SI")])
9271 ;; %%% Potential partial reg stall on alternative 2. What to do?
9272 (define_insn "*ashlqi3_1_lea"
9273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9275 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "!TARGET_PARTIAL_REG_STALL
9278 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9280 switch (get_attr_type (insn))
9286 gcc_assert (operands[2] == const1_rtx);
9287 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9288 return "add{l}\t%k0, %k0";
9290 return "add{b}\t%0, %0";
9293 if (operands[2] == const1_rtx
9294 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9296 if (get_attr_mode (insn) == MODE_SI)
9297 return "sal{l}\t%k0";
9299 return "sal{b}\t%0";
9303 if (get_attr_mode (insn) == MODE_SI)
9304 return "sal{l}\t{%2, %k0|%k0, %2}";
9306 return "sal{b}\t{%2, %0|%0, %2}";
9311 (cond [(eq_attr "alternative" "2")
9312 (const_string "lea")
9313 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9315 (match_operand 0 "register_operand" ""))
9316 (match_operand 2 "const1_operand" ""))
9317 (const_string "alu")
9319 (const_string "ishift")))
9320 (set (attr "length_immediate")
9322 (ior (eq_attr "type" "alu")
9323 (and (eq_attr "type" "ishift")
9324 (and (match_operand 2 "const1_operand" "")
9325 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9328 (const_string "*")))
9329 (set_attr "mode" "QI,SI,SI")])
9331 (define_insn "*ashlqi3_1_slp"
9332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9333 (ashift:QI (match_dup 0)
9334 (match_operand:QI 1 "nonmemory_operand" "cI")))
9335 (clobber (reg:CC FLAGS_REG))]
9336 "(optimize_function_for_size_p (cfun)
9337 || !TARGET_PARTIAL_FLAG_REG_STALL
9338 || (operands[1] == const1_rtx
9340 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9342 switch (get_attr_type (insn))
9345 gcc_assert (operands[1] == const1_rtx);
9346 return "add{b}\t%0, %0";
9349 if (operands[1] == const1_rtx
9350 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9351 return "sal{b}\t%0";
9353 return "sal{b}\t{%1, %0|%0, %1}";
9357 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9359 (match_operand 0 "register_operand" ""))
9360 (match_operand 1 "const1_operand" ""))
9361 (const_string "alu")
9363 (const_string "ishift1")))
9364 (set (attr "length_immediate")
9366 (ior (eq_attr "type" "alu")
9367 (and (eq_attr "type" "ishift1")
9368 (and (match_operand 1 "const1_operand" "")
9369 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9372 (const_string "*")))
9373 (set_attr "mode" "QI")])
9375 ;; Convert ashift to the lea pattern to avoid flags dependency.
9377 [(set (match_operand 0 "register_operand" "")
9378 (ashift (match_operand 1 "index_register_operand" "")
9379 (match_operand:QI 2 "const_int_operand" "")))
9380 (clobber (reg:CC FLAGS_REG))]
9381 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9383 && true_regnum (operands[0]) != true_regnum (operands[1])"
9386 enum machine_mode mode = GET_MODE (operands[0]);
9389 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9392 operands[0] = gen_lowpart (mode, operands[0]);
9393 operands[1] = gen_lowpart (mode, operands[1]);
9396 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9398 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9400 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9404 ;; Convert ashift to the lea pattern to avoid flags dependency.
9406 [(set (match_operand:DI 0 "register_operand" "")
9408 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9409 (match_operand:QI 2 "const_int_operand" ""))))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "TARGET_64BIT && reload_completed
9412 && true_regnum (operands[0]) != true_regnum (operands[1])"
9414 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9416 operands[1] = gen_lowpart (DImode, operands[1]);
9417 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9420 ;; This pattern can't accept a variable shift count, since shifts by
9421 ;; zero don't affect the flags. We assume that shifts by constant
9422 ;; zero are optimized away.
9423 (define_insn "*ashl<mode>3_cmp"
9424 [(set (reg FLAGS_REG)
9426 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9427 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9429 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9430 (ashift:SWI (match_dup 1) (match_dup 2)))]
9431 "(optimize_function_for_size_p (cfun)
9432 || !TARGET_PARTIAL_FLAG_REG_STALL
9433 || (operands[2] == const1_rtx
9435 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9436 && ix86_match_ccmode (insn, CCGOCmode)
9437 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9439 switch (get_attr_type (insn))
9442 gcc_assert (operands[2] == const1_rtx);
9443 return "add{<imodesuffix>}\t%0, %0";
9446 if (operands[2] == const1_rtx
9447 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9448 return "sal{<imodesuffix>}\t%0";
9450 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9454 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 0 "register_operand" ""))
9457 (match_operand 2 "const1_operand" ""))
9458 (const_string "alu")
9460 (const_string "ishift")))
9461 (set (attr "length_immediate")
9463 (ior (eq_attr "type" "alu")
9464 (and (eq_attr "type" "ishift")
9465 (and (match_operand 2 "const1_operand" "")
9466 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9469 (const_string "*")))
9470 (set_attr "mode" "<MODE>")])
9472 (define_insn "*ashlsi3_cmp_zext"
9473 [(set (reg FLAGS_REG)
9475 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9476 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9478 (set (match_operand:DI 0 "register_operand" "=r")
9479 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9481 && (optimize_function_for_size_p (cfun)
9482 || !TARGET_PARTIAL_FLAG_REG_STALL
9483 || (operands[2] == const1_rtx
9485 || TARGET_DOUBLE_WITH_ADD)))
9486 && ix86_match_ccmode (insn, CCGOCmode)
9487 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9489 switch (get_attr_type (insn))
9492 gcc_assert (operands[2] == const1_rtx);
9493 return "add{l}\t%k0, %k0";
9496 if (operands[2] == const1_rtx
9497 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9498 return "sal{l}\t%k0";
9500 return "sal{l}\t{%2, %k0|%k0, %2}";
9504 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9506 (match_operand 2 "const1_operand" ""))
9507 (const_string "alu")
9509 (const_string "ishift")))
9510 (set (attr "length_immediate")
9512 (ior (eq_attr "type" "alu")
9513 (and (eq_attr "type" "ishift")
9514 (and (match_operand 2 "const1_operand" "")
9515 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9518 (const_string "*")))
9519 (set_attr "mode" "SI")])
9521 (define_insn "*ashl<mode>3_cconly"
9522 [(set (reg FLAGS_REG)
9524 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9525 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9527 (clobber (match_scratch:SWI 0 "=<r>"))]
9528 "(optimize_function_for_size_p (cfun)
9529 || !TARGET_PARTIAL_FLAG_REG_STALL
9530 || (operands[2] == const1_rtx
9532 || TARGET_DOUBLE_WITH_ADD)))
9533 && ix86_match_ccmode (insn, CCGOCmode)"
9535 switch (get_attr_type (insn))
9538 gcc_assert (operands[2] == const1_rtx);
9539 return "add{<imodesuffix>}\t%0, %0";
9542 if (operands[2] == const1_rtx
9543 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9544 return "sal{<imodesuffix>}\t%0";
9546 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9550 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9552 (match_operand 0 "register_operand" ""))
9553 (match_operand 2 "const1_operand" ""))
9554 (const_string "alu")
9556 (const_string "ishift")))
9557 (set (attr "length_immediate")
9559 (ior (eq_attr "type" "alu")
9560 (and (eq_attr "type" "ishift")
9561 (and (match_operand 2 "const1_operand" "")
9562 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9565 (const_string "*")))
9566 (set_attr "mode" "<MODE>")])
9568 ;; See comment above `ashl<mode>3' about how this works.
9570 (define_expand "<shiftrt_insn><mode>3"
9571 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9572 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9573 (match_operand:QI 2 "nonmemory_operand" "")))]
9575 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9577 ;; Avoid useless masking of count operand.
9578 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9579 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9581 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9584 (match_operand:SI 2 "nonimmediate_operand" "c")
9585 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9586 (clobber (reg:CC FLAGS_REG))]
9587 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9588 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9589 == GET_MODE_BITSIZE (<MODE>mode)-1"
9592 [(parallel [(set (match_dup 0)
9593 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9594 (clobber (reg:CC FLAGS_REG))])]
9596 if (can_create_pseudo_p ())
9597 operands [2] = force_reg (SImode, operands[2]);
9599 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9601 [(set_attr "type" "ishift")
9602 (set_attr "mode" "<MODE>")])
9604 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9605 [(set (match_operand:DWI 0 "register_operand" "=r")
9606 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9607 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9608 (clobber (reg:CC FLAGS_REG))]
9611 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9613 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9614 [(set_attr "type" "multi")])
9616 ;; By default we don't ask for a scratch register, because when DWImode
9617 ;; values are manipulated, registers are already at a premium. But if
9618 ;; we have one handy, we won't turn it away.
9621 [(match_scratch:DWIH 3 "r")
9622 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9624 (match_operand:<DWI> 1 "register_operand" "")
9625 (match_operand:QI 2 "nonmemory_operand" "")))
9626 (clobber (reg:CC FLAGS_REG))])
9630 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9632 (define_insn "x86_64_shrd"
9633 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9634 (ior:DI (ashiftrt:DI (match_dup 0)
9635 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9636 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9637 (minus:QI (const_int 64) (match_dup 2)))))
9638 (clobber (reg:CC FLAGS_REG))]
9640 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9641 [(set_attr "type" "ishift")
9642 (set_attr "prefix_0f" "1")
9643 (set_attr "mode" "DI")
9644 (set_attr "athlon_decode" "vector")
9645 (set_attr "amdfam10_decode" "vector")
9646 (set_attr "bdver1_decode" "vector")])
9648 (define_insn "x86_shrd"
9649 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9650 (ior:SI (ashiftrt:SI (match_dup 0)
9651 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9652 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9653 (minus:QI (const_int 32) (match_dup 2)))))
9654 (clobber (reg:CC FLAGS_REG))]
9656 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9657 [(set_attr "type" "ishift")
9658 (set_attr "prefix_0f" "1")
9659 (set_attr "mode" "SI")
9660 (set_attr "pent_pair" "np")
9661 (set_attr "athlon_decode" "vector")
9662 (set_attr "amdfam10_decode" "vector")
9663 (set_attr "bdver1_decode" "vector")])
9665 (define_insn "ashrdi3_cvt"
9666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9667 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9668 (match_operand:QI 2 "const_int_operand" "")))
9669 (clobber (reg:CC FLAGS_REG))]
9670 "TARGET_64BIT && INTVAL (operands[2]) == 63
9671 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9672 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9675 sar{q}\t{%2, %0|%0, %2}"
9676 [(set_attr "type" "imovx,ishift")
9677 (set_attr "prefix_0f" "0,*")
9678 (set_attr "length_immediate" "0,*")
9679 (set_attr "modrm" "0,1")
9680 (set_attr "mode" "DI")])
9682 (define_insn "ashrsi3_cvt"
9683 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9684 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9685 (match_operand:QI 2 "const_int_operand" "")))
9686 (clobber (reg:CC FLAGS_REG))]
9687 "INTVAL (operands[2]) == 31
9688 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9689 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9692 sar{l}\t{%2, %0|%0, %2}"
9693 [(set_attr "type" "imovx,ishift")
9694 (set_attr "prefix_0f" "0,*")
9695 (set_attr "length_immediate" "0,*")
9696 (set_attr "modrm" "0,1")
9697 (set_attr "mode" "SI")])
9699 (define_insn "*ashrsi3_cvt_zext"
9700 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9702 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9703 (match_operand:QI 2 "const_int_operand" ""))))
9704 (clobber (reg:CC FLAGS_REG))]
9705 "TARGET_64BIT && INTVAL (operands[2]) == 31
9706 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9707 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9710 sar{l}\t{%2, %k0|%k0, %2}"
9711 [(set_attr "type" "imovx,ishift")
9712 (set_attr "prefix_0f" "0,*")
9713 (set_attr "length_immediate" "0,*")
9714 (set_attr "modrm" "0,1")
9715 (set_attr "mode" "SI")])
9717 (define_expand "x86_shift<mode>_adj_3"
9718 [(use (match_operand:SWI48 0 "register_operand" ""))
9719 (use (match_operand:SWI48 1 "register_operand" ""))
9720 (use (match_operand:QI 2 "register_operand" ""))]
9723 rtx label = gen_label_rtx ();
9726 emit_insn (gen_testqi_ccz_1 (operands[2],
9727 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9729 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9730 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9731 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9732 gen_rtx_LABEL_REF (VOIDmode, label),
9734 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9735 JUMP_LABEL (tmp) = label;
9737 emit_move_insn (operands[0], operands[1]);
9738 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9739 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9741 LABEL_NUSES (label) = 1;
9746 (define_insn "*<shiftrt_insn><mode>3_1"
9747 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9748 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9749 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9753 if (operands[2] == const1_rtx
9754 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9755 return "<shiftrt>{<imodesuffix>}\t%0";
9757 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9759 [(set_attr "type" "ishift")
9760 (set (attr "length_immediate")
9762 (and (match_operand 2 "const1_operand" "")
9763 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9766 (const_string "*")))
9767 (set_attr "mode" "<MODE>")])
9769 (define_insn "*<shiftrt_insn>si3_1_zext"
9770 [(set (match_operand:DI 0 "register_operand" "=r")
9772 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9773 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9777 if (operands[2] == const1_rtx
9778 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9779 return "<shiftrt>{l}\t%k0";
9781 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9783 [(set_attr "type" "ishift")
9784 (set (attr "length_immediate")
9786 (and (match_operand 2 "const1_operand" "")
9787 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9790 (const_string "*")))
9791 (set_attr "mode" "SI")])
9793 (define_insn "*<shiftrt_insn>qi3_1_slp"
9794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9795 (any_shiftrt:QI (match_dup 0)
9796 (match_operand:QI 1 "nonmemory_operand" "cI")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "(optimize_function_for_size_p (cfun)
9799 || !TARGET_PARTIAL_REG_STALL
9800 || (operands[1] == const1_rtx
9803 if (operands[1] == const1_rtx
9804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9805 return "<shiftrt>{b}\t%0";
9807 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9809 [(set_attr "type" "ishift1")
9810 (set (attr "length_immediate")
9812 (and (match_operand 1 "const1_operand" "")
9813 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9816 (const_string "*")))
9817 (set_attr "mode" "QI")])
9819 ;; This pattern can't accept a variable shift count, since shifts by
9820 ;; zero don't affect the flags. We assume that shifts by constant
9821 ;; zero are optimized away.
9822 (define_insn "*<shiftrt_insn><mode>3_cmp"
9823 [(set (reg FLAGS_REG)
9826 (match_operand:SWI 1 "nonimmediate_operand" "0")
9827 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9829 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9830 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9831 "(optimize_function_for_size_p (cfun)
9832 || !TARGET_PARTIAL_FLAG_REG_STALL
9833 || (operands[2] == const1_rtx
9835 && ix86_match_ccmode (insn, CCGOCmode)
9836 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9838 if (operands[2] == const1_rtx
9839 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9840 return "<shiftrt>{<imodesuffix>}\t%0";
9842 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9844 [(set_attr "type" "ishift")
9845 (set (attr "length_immediate")
9847 (and (match_operand 2 "const1_operand" "")
9848 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9851 (const_string "*")))
9852 (set_attr "mode" "<MODE>")])
9854 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9855 [(set (reg FLAGS_REG)
9857 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9858 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9860 (set (match_operand:DI 0 "register_operand" "=r")
9861 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9863 && (optimize_function_for_size_p (cfun)
9864 || !TARGET_PARTIAL_FLAG_REG_STALL
9865 || (operands[2] == const1_rtx
9867 && ix86_match_ccmode (insn, CCGOCmode)
9868 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<shiftrt>{l}\t%k0";
9874 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9876 [(set_attr "type" "ishift")
9877 (set (attr "length_immediate")
9879 (and (match_operand 2 "const1_operand" "")
9880 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9883 (const_string "*")))
9884 (set_attr "mode" "SI")])
9886 (define_insn "*<shiftrt_insn><mode>3_cconly"
9887 [(set (reg FLAGS_REG)
9890 (match_operand:SWI 1 "register_operand" "0")
9891 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9893 (clobber (match_scratch:SWI 0 "=<r>"))]
9894 "(optimize_function_for_size_p (cfun)
9895 || !TARGET_PARTIAL_FLAG_REG_STALL
9896 || (operands[2] == const1_rtx
9898 && ix86_match_ccmode (insn, CCGOCmode)"
9900 if (operands[2] == const1_rtx
9901 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9902 return "<shiftrt>{<imodesuffix>}\t%0";
9904 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9906 [(set_attr "type" "ishift")
9907 (set (attr "length_immediate")
9909 (and (match_operand 2 "const1_operand" "")
9910 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913 (const_string "*")))
9914 (set_attr "mode" "<MODE>")])
9916 ;; Rotate instructions
9918 (define_expand "<rotate_insn>ti3"
9919 [(set (match_operand:TI 0 "register_operand" "")
9920 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9921 (match_operand:QI 2 "nonmemory_operand" "")))]
9924 if (const_1_to_63_operand (operands[2], VOIDmode))
9925 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9926 (operands[0], operands[1], operands[2]));
9933 (define_expand "<rotate_insn>di3"
9934 [(set (match_operand:DI 0 "shiftdi_operand" "")
9935 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9936 (match_operand:QI 2 "nonmemory_operand" "")))]
9940 ix86_expand_binary_operator (<CODE>, DImode, operands);
9941 else if (const_1_to_31_operand (operands[2], VOIDmode))
9942 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9943 (operands[0], operands[1], operands[2]));
9950 (define_expand "<rotate_insn><mode>3"
9951 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9952 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9953 (match_operand:QI 2 "nonmemory_operand" "")))]
9955 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9957 ;; Avoid useless masking of count operand.
9958 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9959 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9961 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9964 (match_operand:SI 2 "nonimmediate_operand" "c")
9965 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9968 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9969 == GET_MODE_BITSIZE (<MODE>mode)-1"
9972 [(parallel [(set (match_dup 0)
9973 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9974 (clobber (reg:CC FLAGS_REG))])]
9976 if (can_create_pseudo_p ())
9977 operands [2] = force_reg (SImode, operands[2]);
9979 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9981 [(set_attr "type" "rotate")
9982 (set_attr "mode" "<MODE>")])
9984 ;; Implement rotation using two double-precision
9985 ;; shift instructions and a scratch register.
9987 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9988 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9989 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9990 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9991 (clobber (reg:CC FLAGS_REG))
9992 (clobber (match_scratch:DWIH 3 "=&r"))]
9996 [(set (match_dup 3) (match_dup 4))
9999 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10000 (lshiftrt:DWIH (match_dup 5)
10001 (minus:QI (match_dup 6) (match_dup 2)))))
10002 (clobber (reg:CC FLAGS_REG))])
10004 [(set (match_dup 5)
10005 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10006 (lshiftrt:DWIH (match_dup 3)
10007 (minus:QI (match_dup 6) (match_dup 2)))))
10008 (clobber (reg:CC FLAGS_REG))])]
10010 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10012 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10015 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10016 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10017 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10018 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10019 (clobber (reg:CC FLAGS_REG))
10020 (clobber (match_scratch:DWIH 3 "=&r"))]
10024 [(set (match_dup 3) (match_dup 4))
10026 [(set (match_dup 4)
10027 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10028 (ashift:DWIH (match_dup 5)
10029 (minus:QI (match_dup 6) (match_dup 2)))))
10030 (clobber (reg:CC FLAGS_REG))])
10032 [(set (match_dup 5)
10033 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10034 (ashift:DWIH (match_dup 3)
10035 (minus:QI (match_dup 6) (match_dup 2)))))
10036 (clobber (reg:CC FLAGS_REG))])]
10038 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10040 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10043 (define_insn "*<rotate_insn><mode>3_1"
10044 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10045 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10046 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10047 (clobber (reg:CC FLAGS_REG))]
10048 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10050 if (operands[2] == const1_rtx
10051 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10052 return "<rotate>{<imodesuffix>}\t%0";
10054 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10056 [(set_attr "type" "rotate")
10057 (set (attr "length_immediate")
10059 (and (match_operand 2 "const1_operand" "")
10060 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10063 (const_string "*")))
10064 (set_attr "mode" "<MODE>")])
10066 (define_insn "*<rotate_insn>si3_1_zext"
10067 [(set (match_operand:DI 0 "register_operand" "=r")
10069 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10070 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10071 (clobber (reg:CC FLAGS_REG))]
10072 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10074 if (operands[2] == const1_rtx
10075 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10076 return "<rotate>{l}\t%k0";
10078 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10080 [(set_attr "type" "rotate")
10081 (set (attr "length_immediate")
10083 (and (match_operand 2 "const1_operand" "")
10084 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10087 (const_string "*")))
10088 (set_attr "mode" "SI")])
10090 (define_insn "*<rotate_insn>qi3_1_slp"
10091 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10092 (any_rotate:QI (match_dup 0)
10093 (match_operand:QI 1 "nonmemory_operand" "cI")))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "(optimize_function_for_size_p (cfun)
10096 || !TARGET_PARTIAL_REG_STALL
10097 || (operands[1] == const1_rtx
10098 && TARGET_SHIFT1))"
10100 if (operands[1] == const1_rtx
10101 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10102 return "<rotate>{b}\t%0";
10104 return "<rotate>{b}\t{%1, %0|%0, %1}";
10106 [(set_attr "type" "rotate1")
10107 (set (attr "length_immediate")
10109 (and (match_operand 1 "const1_operand" "")
10110 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10113 (const_string "*")))
10114 (set_attr "mode" "QI")])
10117 [(set (match_operand:HI 0 "register_operand" "")
10118 (any_rotate:HI (match_dup 0) (const_int 8)))
10119 (clobber (reg:CC FLAGS_REG))]
10121 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10122 [(parallel [(set (strict_low_part (match_dup 0))
10123 (bswap:HI (match_dup 0)))
10124 (clobber (reg:CC FLAGS_REG))])])
10126 ;; Bit set / bit test instructions
10128 (define_expand "extv"
10129 [(set (match_operand:SI 0 "register_operand" "")
10130 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10131 (match_operand:SI 2 "const8_operand" "")
10132 (match_operand:SI 3 "const8_operand" "")))]
10135 /* Handle extractions from %ah et al. */
10136 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10139 /* From mips.md: extract_bit_field doesn't verify that our source
10140 matches the predicate, so check it again here. */
10141 if (! ext_register_operand (operands[1], VOIDmode))
10145 (define_expand "extzv"
10146 [(set (match_operand:SI 0 "register_operand" "")
10147 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10148 (match_operand:SI 2 "const8_operand" "")
10149 (match_operand:SI 3 "const8_operand" "")))]
10152 /* Handle extractions from %ah et al. */
10153 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10156 /* From mips.md: extract_bit_field doesn't verify that our source
10157 matches the predicate, so check it again here. */
10158 if (! ext_register_operand (operands[1], VOIDmode))
10162 (define_expand "insv"
10163 [(set (zero_extract (match_operand 0 "register_operand" "")
10164 (match_operand 1 "const_int_operand" "")
10165 (match_operand 2 "const_int_operand" ""))
10166 (match_operand 3 "register_operand" ""))]
10169 rtx (*gen_mov_insv_1) (rtx, rtx);
10171 if (ix86_expand_pinsr (operands))
10174 /* Handle insertions to %ah et al. */
10175 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10178 /* From mips.md: insert_bit_field doesn't verify that our source
10179 matches the predicate, so check it again here. */
10180 if (! ext_register_operand (operands[0], VOIDmode))
10183 gen_mov_insv_1 = (TARGET_64BIT
10184 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10186 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10190 ;; %%% bts, btr, btc, bt.
10191 ;; In general these instructions are *slow* when applied to memory,
10192 ;; since they enforce atomic operation. When applied to registers,
10193 ;; it depends on the cpu implementation. They're never faster than
10194 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10195 ;; no point. But in 64-bit, we can't hold the relevant immediates
10196 ;; within the instruction itself, so operating on bits in the high
10197 ;; 32-bits of a register becomes easier.
10199 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10200 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10201 ;; negdf respectively, so they can never be disabled entirely.
10203 (define_insn "*btsq"
10204 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10206 (match_operand:DI 1 "const_0_to_63_operand" ""))
10208 (clobber (reg:CC FLAGS_REG))]
10209 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10210 "bts{q}\t{%1, %0|%0, %1}"
10211 [(set_attr "type" "alu1")
10212 (set_attr "prefix_0f" "1")
10213 (set_attr "mode" "DI")])
10215 (define_insn "*btrq"
10216 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10218 (match_operand:DI 1 "const_0_to_63_operand" ""))
10220 (clobber (reg:CC FLAGS_REG))]
10221 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10222 "btr{q}\t{%1, %0|%0, %1}"
10223 [(set_attr "type" "alu1")
10224 (set_attr "prefix_0f" "1")
10225 (set_attr "mode" "DI")])
10227 (define_insn "*btcq"
10228 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10230 (match_operand:DI 1 "const_0_to_63_operand" ""))
10231 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10232 (clobber (reg:CC FLAGS_REG))]
10233 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10234 "btc{q}\t{%1, %0|%0, %1}"
10235 [(set_attr "type" "alu1")
10236 (set_attr "prefix_0f" "1")
10237 (set_attr "mode" "DI")])
10239 ;; Allow Nocona to avoid these instructions if a register is available.
10242 [(match_scratch:DI 2 "r")
10243 (parallel [(set (zero_extract:DI
10244 (match_operand:DI 0 "register_operand" "")
10246 (match_operand:DI 1 "const_0_to_63_operand" ""))
10248 (clobber (reg:CC FLAGS_REG))])]
10249 "TARGET_64BIT && !TARGET_USE_BT"
10252 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10255 if (HOST_BITS_PER_WIDE_INT >= 64)
10256 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10257 else if (i < HOST_BITS_PER_WIDE_INT)
10258 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10260 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10262 op1 = immed_double_const (lo, hi, DImode);
10265 emit_move_insn (operands[2], op1);
10269 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10274 [(match_scratch:DI 2 "r")
10275 (parallel [(set (zero_extract:DI
10276 (match_operand:DI 0 "register_operand" "")
10278 (match_operand:DI 1 "const_0_to_63_operand" ""))
10280 (clobber (reg:CC FLAGS_REG))])]
10281 "TARGET_64BIT && !TARGET_USE_BT"
10284 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10287 if (HOST_BITS_PER_WIDE_INT >= 64)
10288 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10289 else if (i < HOST_BITS_PER_WIDE_INT)
10290 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10292 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10294 op1 = immed_double_const (~lo, ~hi, DImode);
10297 emit_move_insn (operands[2], op1);
10301 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10306 [(match_scratch:DI 2 "r")
10307 (parallel [(set (zero_extract:DI
10308 (match_operand:DI 0 "register_operand" "")
10310 (match_operand:DI 1 "const_0_to_63_operand" ""))
10311 (not:DI (zero_extract:DI
10312 (match_dup 0) (const_int 1) (match_dup 1))))
10313 (clobber (reg:CC FLAGS_REG))])]
10314 "TARGET_64BIT && !TARGET_USE_BT"
10317 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10320 if (HOST_BITS_PER_WIDE_INT >= 64)
10321 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10322 else if (i < HOST_BITS_PER_WIDE_INT)
10323 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10325 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10327 op1 = immed_double_const (lo, hi, DImode);
10330 emit_move_insn (operands[2], op1);
10334 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10338 (define_insn "*bt<mode>"
10339 [(set (reg:CCC FLAGS_REG)
10341 (zero_extract:SWI48
10342 (match_operand:SWI48 0 "register_operand" "r")
10344 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10346 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10347 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10348 [(set_attr "type" "alu1")
10349 (set_attr "prefix_0f" "1")
10350 (set_attr "mode" "<MODE>")])
10352 ;; Store-flag instructions.
10354 ;; For all sCOND expanders, also expand the compare or test insn that
10355 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10357 (define_insn_and_split "*setcc_di_1"
10358 [(set (match_operand:DI 0 "register_operand" "=q")
10359 (match_operator:DI 1 "ix86_comparison_operator"
10360 [(reg FLAGS_REG) (const_int 0)]))]
10361 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10363 "&& reload_completed"
10364 [(set (match_dup 2) (match_dup 1))
10365 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10367 PUT_MODE (operands[1], QImode);
10368 operands[2] = gen_lowpart (QImode, operands[0]);
10371 (define_insn_and_split "*setcc_si_1_and"
10372 [(set (match_operand:SI 0 "register_operand" "=q")
10373 (match_operator:SI 1 "ix86_comparison_operator"
10374 [(reg FLAGS_REG) (const_int 0)]))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "!TARGET_PARTIAL_REG_STALL
10377 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10379 "&& reload_completed"
10380 [(set (match_dup 2) (match_dup 1))
10381 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10382 (clobber (reg:CC FLAGS_REG))])]
10384 PUT_MODE (operands[1], QImode);
10385 operands[2] = gen_lowpart (QImode, operands[0]);
10388 (define_insn_and_split "*setcc_si_1_movzbl"
10389 [(set (match_operand:SI 0 "register_operand" "=q")
10390 (match_operator:SI 1 "ix86_comparison_operator"
10391 [(reg FLAGS_REG) (const_int 0)]))]
10392 "!TARGET_PARTIAL_REG_STALL
10393 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10395 "&& reload_completed"
10396 [(set (match_dup 2) (match_dup 1))
10397 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10399 PUT_MODE (operands[1], QImode);
10400 operands[2] = gen_lowpart (QImode, operands[0]);
10403 (define_insn "*setcc_qi"
10404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10405 (match_operator:QI 1 "ix86_comparison_operator"
10406 [(reg FLAGS_REG) (const_int 0)]))]
10409 [(set_attr "type" "setcc")
10410 (set_attr "mode" "QI")])
10412 (define_insn "*setcc_qi_slp"
10413 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10414 (match_operator:QI 1 "ix86_comparison_operator"
10415 [(reg FLAGS_REG) (const_int 0)]))]
10418 [(set_attr "type" "setcc")
10419 (set_attr "mode" "QI")])
10421 ;; In general it is not safe to assume too much about CCmode registers,
10422 ;; so simplify-rtx stops when it sees a second one. Under certain
10423 ;; conditions this is safe on x86, so help combine not create
10430 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10431 (ne:QI (match_operator 1 "ix86_comparison_operator"
10432 [(reg FLAGS_REG) (const_int 0)])
10435 [(set (match_dup 0) (match_dup 1))]
10436 "PUT_MODE (operands[1], QImode);")
10439 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10440 (ne:QI (match_operator 1 "ix86_comparison_operator"
10441 [(reg FLAGS_REG) (const_int 0)])
10444 [(set (match_dup 0) (match_dup 1))]
10445 "PUT_MODE (operands[1], QImode);")
10448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10449 (eq:QI (match_operator 1 "ix86_comparison_operator"
10450 [(reg FLAGS_REG) (const_int 0)])
10453 [(set (match_dup 0) (match_dup 1))]
10455 rtx new_op1 = copy_rtx (operands[1]);
10456 operands[1] = new_op1;
10457 PUT_MODE (new_op1, QImode);
10458 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10459 GET_MODE (XEXP (new_op1, 0))));
10461 /* Make sure that (a) the CCmode we have for the flags is strong
10462 enough for the reversed compare or (b) we have a valid FP compare. */
10463 if (! ix86_comparison_operator (new_op1, VOIDmode))
10468 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10469 (eq:QI (match_operator 1 "ix86_comparison_operator"
10470 [(reg FLAGS_REG) (const_int 0)])
10473 [(set (match_dup 0) (match_dup 1))]
10475 rtx new_op1 = copy_rtx (operands[1]);
10476 operands[1] = new_op1;
10477 PUT_MODE (new_op1, QImode);
10478 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10479 GET_MODE (XEXP (new_op1, 0))));
10481 /* Make sure that (a) the CCmode we have for the flags is strong
10482 enough for the reversed compare or (b) we have a valid FP compare. */
10483 if (! ix86_comparison_operator (new_op1, VOIDmode))
10487 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10488 ;; subsequent logical operations are used to imitate conditional moves.
10489 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10492 (define_insn "setcc_<mode>_sse"
10493 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10494 (match_operator:MODEF 3 "sse_comparison_operator"
10495 [(match_operand:MODEF 1 "register_operand" "0,x")
10496 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10497 "SSE_FLOAT_MODE_P (<MODE>mode)"
10499 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10500 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10501 [(set_attr "isa" "noavx,avx")
10502 (set_attr "type" "ssecmp")
10503 (set_attr "length_immediate" "1")
10504 (set_attr "prefix" "orig,vex")
10505 (set_attr "mode" "<MODE>")])
10507 ;; Basic conditional jump instructions.
10508 ;; We ignore the overflow flag for signed branch instructions.
10510 (define_insn "*jcc_1"
10512 (if_then_else (match_operator 1 "ix86_comparison_operator"
10513 [(reg FLAGS_REG) (const_int 0)])
10514 (label_ref (match_operand 0 "" ""))
10518 [(set_attr "type" "ibr")
10519 (set_attr "modrm" "0")
10520 (set (attr "length")
10521 (if_then_else (and (ge (minus (match_dup 0) (pc))
10523 (lt (minus (match_dup 0) (pc))
10528 (define_insn "*jcc_2"
10530 (if_then_else (match_operator 1 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)])
10533 (label_ref (match_operand 0 "" ""))))]
10536 [(set_attr "type" "ibr")
10537 (set_attr "modrm" "0")
10538 (set (attr "length")
10539 (if_then_else (and (ge (minus (match_dup 0) (pc))
10541 (lt (minus (match_dup 0) (pc))
10546 ;; In general it is not safe to assume too much about CCmode registers,
10547 ;; so simplify-rtx stops when it sees a second one. Under certain
10548 ;; conditions this is safe on x86, so help combine not create
10556 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10557 [(reg FLAGS_REG) (const_int 0)])
10559 (label_ref (match_operand 1 "" ""))
10563 (if_then_else (match_dup 0)
10564 (label_ref (match_dup 1))
10566 "PUT_MODE (operands[0], VOIDmode);")
10570 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10571 [(reg FLAGS_REG) (const_int 0)])
10573 (label_ref (match_operand 1 "" ""))
10577 (if_then_else (match_dup 0)
10578 (label_ref (match_dup 1))
10581 rtx new_op0 = copy_rtx (operands[0]);
10582 operands[0] = new_op0;
10583 PUT_MODE (new_op0, VOIDmode);
10584 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10585 GET_MODE (XEXP (new_op0, 0))));
10587 /* Make sure that (a) the CCmode we have for the flags is strong
10588 enough for the reversed compare or (b) we have a valid FP compare. */
10589 if (! ix86_comparison_operator (new_op0, VOIDmode))
10593 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10594 ;; pass generates from shift insn with QImode operand. Actually, the mode
10595 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10596 ;; appropriate modulo of the bit offset value.
10598 (define_insn_and_split "*jcc_bt<mode>"
10600 (if_then_else (match_operator 0 "bt_comparison_operator"
10601 [(zero_extract:SWI48
10602 (match_operand:SWI48 1 "register_operand" "r")
10605 (match_operand:QI 2 "register_operand" "r")))
10607 (label_ref (match_operand 3 "" ""))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10613 [(set (reg:CCC FLAGS_REG)
10615 (zero_extract:SWI48
10621 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10622 (label_ref (match_dup 3))
10625 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10627 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10630 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10631 ;; also for DImode, this is what combine produces.
10632 (define_insn_and_split "*jcc_bt<mode>_mask"
10634 (if_then_else (match_operator 0 "bt_comparison_operator"
10635 [(zero_extract:SWI48
10636 (match_operand:SWI48 1 "register_operand" "r")
10639 (match_operand:SI 2 "register_operand" "r")
10640 (match_operand:SI 3 "const_int_operand" "n")))])
10641 (label_ref (match_operand 4 "" ""))
10643 (clobber (reg:CC FLAGS_REG))]
10644 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10645 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10646 == GET_MODE_BITSIZE (<MODE>mode)-1"
10649 [(set (reg:CCC FLAGS_REG)
10651 (zero_extract:SWI48
10657 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10658 (label_ref (match_dup 4))
10661 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10663 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10666 (define_insn_and_split "*jcc_btsi_1"
10668 (if_then_else (match_operator 0 "bt_comparison_operator"
10671 (match_operand:SI 1 "register_operand" "r")
10672 (match_operand:QI 2 "register_operand" "r"))
10675 (label_ref (match_operand 3 "" ""))
10677 (clobber (reg:CC FLAGS_REG))]
10678 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10681 [(set (reg:CCC FLAGS_REG)
10689 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10690 (label_ref (match_dup 3))
10693 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10695 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10698 ;; avoid useless masking of bit offset operand
10699 (define_insn_and_split "*jcc_btsi_mask_1"
10702 (match_operator 0 "bt_comparison_operator"
10705 (match_operand:SI 1 "register_operand" "r")
10708 (match_operand:SI 2 "register_operand" "r")
10709 (match_operand:SI 3 "const_int_operand" "n")) 0))
10712 (label_ref (match_operand 4 "" ""))
10714 (clobber (reg:CC FLAGS_REG))]
10715 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10716 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10719 [(set (reg:CCC FLAGS_REG)
10727 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10728 (label_ref (match_dup 4))
10730 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10732 ;; Define combination compare-and-branch fp compare instructions to help
10735 (define_insn "*fp_jcc_1_387"
10737 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10738 [(match_operand 1 "register_operand" "f")
10739 (match_operand 2 "nonimmediate_operand" "fm")])
10740 (label_ref (match_operand 3 "" ""))
10742 (clobber (reg:CCFP FPSR_REG))
10743 (clobber (reg:CCFP FLAGS_REG))
10744 (clobber (match_scratch:HI 4 "=a"))]
10746 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10747 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10748 && SELECT_CC_MODE (GET_CODE (operands[0]),
10749 operands[1], operands[2]) == CCFPmode
10753 (define_insn "*fp_jcc_1r_387"
10755 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10756 [(match_operand 1 "register_operand" "f")
10757 (match_operand 2 "nonimmediate_operand" "fm")])
10759 (label_ref (match_operand 3 "" ""))))
10760 (clobber (reg:CCFP FPSR_REG))
10761 (clobber (reg:CCFP FLAGS_REG))
10762 (clobber (match_scratch:HI 4 "=a"))]
10764 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10765 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10766 && SELECT_CC_MODE (GET_CODE (operands[0]),
10767 operands[1], operands[2]) == CCFPmode
10771 (define_insn "*fp_jcc_2_387"
10773 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10774 [(match_operand 1 "register_operand" "f")
10775 (match_operand 2 "register_operand" "f")])
10776 (label_ref (match_operand 3 "" ""))
10778 (clobber (reg:CCFP FPSR_REG))
10779 (clobber (reg:CCFP FLAGS_REG))
10780 (clobber (match_scratch:HI 4 "=a"))]
10781 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10782 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10786 (define_insn "*fp_jcc_2r_387"
10788 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789 [(match_operand 1 "register_operand" "f")
10790 (match_operand 2 "register_operand" "f")])
10792 (label_ref (match_operand 3 "" ""))))
10793 (clobber (reg:CCFP FPSR_REG))
10794 (clobber (reg:CCFP FLAGS_REG))
10795 (clobber (match_scratch:HI 4 "=a"))]
10796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10801 (define_insn "*fp_jcc_3_387"
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "const0_operand" "")])
10806 (label_ref (match_operand 3 "" ""))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10813 && SELECT_CC_MODE (GET_CODE (operands[0]),
10814 operands[1], operands[2]) == CCFPmode
10820 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10821 [(match_operand 1 "register_operand" "")
10822 (match_operand 2 "nonimmediate_operand" "")])
10823 (match_operand 3 "" "")
10824 (match_operand 4 "" "")))
10825 (clobber (reg:CCFP FPSR_REG))
10826 (clobber (reg:CCFP FLAGS_REG))]
10830 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10831 operands[3], operands[4], NULL_RTX, NULL_RTX);
10837 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10838 [(match_operand 1 "register_operand" "")
10839 (match_operand 2 "general_operand" "")])
10840 (match_operand 3 "" "")
10841 (match_operand 4 "" "")))
10842 (clobber (reg:CCFP FPSR_REG))
10843 (clobber (reg:CCFP FLAGS_REG))
10844 (clobber (match_scratch:HI 5 "=a"))]
10848 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10849 operands[3], operands[4], operands[5], NULL_RTX);
10853 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10854 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10855 ;; with a precedence over other operators and is always put in the first
10856 ;; place. Swap condition and operands to match ficom instruction.
10858 (define_insn "*fp_jcc_4_<mode>_387"
10861 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10862 [(match_operator 1 "float_operator"
10863 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10864 (match_operand 3 "register_operand" "f,f")])
10865 (label_ref (match_operand 4 "" ""))
10867 (clobber (reg:CCFP FPSR_REG))
10868 (clobber (reg:CCFP FLAGS_REG))
10869 (clobber (match_scratch:HI 5 "=a,a"))]
10870 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10871 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10872 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10873 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10880 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10881 [(match_operator 1 "float_operator"
10882 [(match_operand:SWI24 2 "memory_operand" "")])
10883 (match_operand 3 "register_operand" "")])
10884 (match_operand 4 "" "")
10885 (match_operand 5 "" "")))
10886 (clobber (reg:CCFP FPSR_REG))
10887 (clobber (reg:CCFP FLAGS_REG))
10888 (clobber (match_scratch:HI 6 "=a"))]
10892 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10894 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10895 operands[3], operands[7],
10896 operands[4], operands[5], operands[6], NULL_RTX);
10900 ;; %%% Kill this when reload knows how to do it.
10904 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10905 [(match_operator 1 "float_operator"
10906 [(match_operand:SWI24 2 "register_operand" "")])
10907 (match_operand 3 "register_operand" "")])
10908 (match_operand 4 "" "")
10909 (match_operand 5 "" "")))
10910 (clobber (reg:CCFP FPSR_REG))
10911 (clobber (reg:CCFP FLAGS_REG))
10912 (clobber (match_scratch:HI 6 "=a"))]
10916 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10917 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10919 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10920 operands[3], operands[7],
10921 operands[4], operands[5], operands[6], operands[2]);
10925 ;; Unconditional and other jump instructions
10927 (define_insn "jump"
10929 (label_ref (match_operand 0 "" "")))]
10932 [(set_attr "type" "ibr")
10933 (set (attr "length")
10934 (if_then_else (and (ge (minus (match_dup 0) (pc))
10936 (lt (minus (match_dup 0) (pc))
10940 (set_attr "modrm" "0")])
10942 (define_expand "indirect_jump"
10943 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10945 (define_insn "*indirect_jump"
10946 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10949 [(set_attr "type" "ibr")
10950 (set_attr "length_immediate" "0")])
10952 (define_expand "tablejump"
10953 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10954 (use (label_ref (match_operand 1 "" "")))])]
10957 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10958 relative. Convert the relative address to an absolute address. */
10962 enum rtx_code code;
10964 /* We can't use @GOTOFF for text labels on VxWorks;
10965 see gotoff_operand. */
10966 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10970 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10972 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10976 op1 = pic_offset_table_rtx;
10981 op0 = pic_offset_table_rtx;
10985 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10988 else if (TARGET_X32)
10989 operands[0] = convert_memory_address (Pmode, operands[0]);
10992 (define_insn "*tablejump_1"
10993 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10994 (use (label_ref (match_operand 1 "" "")))]
10997 [(set_attr "type" "ibr")
10998 (set_attr "length_immediate" "0")])
11000 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11003 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11004 (set (match_operand:QI 1 "register_operand" "")
11005 (match_operator:QI 2 "ix86_comparison_operator"
11006 [(reg FLAGS_REG) (const_int 0)]))
11007 (set (match_operand 3 "q_regs_operand" "")
11008 (zero_extend (match_dup 1)))]
11009 "(peep2_reg_dead_p (3, operands[1])
11010 || operands_match_p (operands[1], operands[3]))
11011 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11012 [(set (match_dup 4) (match_dup 0))
11013 (set (strict_low_part (match_dup 5))
11016 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11017 operands[5] = gen_lowpart (QImode, operands[3]);
11018 ix86_expand_clear (operands[3]);
11021 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11024 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11025 (set (match_operand:QI 1 "register_operand" "")
11026 (match_operator:QI 2 "ix86_comparison_operator"
11027 [(reg FLAGS_REG) (const_int 0)]))
11028 (parallel [(set (match_operand 3 "q_regs_operand" "")
11029 (zero_extend (match_dup 1)))
11030 (clobber (reg:CC FLAGS_REG))])]
11031 "(peep2_reg_dead_p (3, operands[1])
11032 || operands_match_p (operands[1], operands[3]))
11033 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11034 [(set (match_dup 4) (match_dup 0))
11035 (set (strict_low_part (match_dup 5))
11038 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11039 operands[5] = gen_lowpart (QImode, operands[3]);
11040 ix86_expand_clear (operands[3]);
11043 ;; Call instructions.
11045 ;; The predicates normally associated with named expanders are not properly
11046 ;; checked for calls. This is a bug in the generic code, but it isn't that
11047 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11049 ;; P6 processors will jump to the address after the decrement when %esp
11050 ;; is used as a call operand, so they will execute return address as a code.
11051 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11053 ;; Register constraint for call instruction.
11054 (define_mode_attr c [(SI "l") (DI "r")])
11056 ;; Call subroutine returning no value.
11058 (define_expand "call"
11059 [(call (match_operand:QI 0 "" "")
11060 (match_operand 1 "" ""))
11061 (use (match_operand 2 "" ""))]
11064 ix86_expand_call (NULL, operands[0], operands[1],
11065 operands[2], NULL, false);
11069 (define_expand "sibcall"
11070 [(call (match_operand:QI 0 "" "")
11071 (match_operand 1 "" ""))
11072 (use (match_operand 2 "" ""))]
11075 ix86_expand_call (NULL, operands[0], operands[1],
11076 operands[2], NULL, true);
11080 (define_insn_and_split "*call_vzeroupper"
11081 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11082 (match_operand 1 "" ""))
11083 (unspec [(match_operand 2 "const_int_operand" "")]
11084 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11085 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11087 "&& reload_completed"
11089 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11090 [(set_attr "type" "call")])
11092 (define_insn "*call"
11093 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11094 (match_operand 1 "" ""))]
11095 "!SIBLING_CALL_P (insn)"
11096 "* return ix86_output_call_insn (insn, operands[0]);"
11097 [(set_attr "type" "call")])
11099 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11100 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11101 (match_operand 1 "" ""))
11102 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11103 (clobber (reg:TI XMM6_REG))
11104 (clobber (reg:TI XMM7_REG))
11105 (clobber (reg:TI XMM8_REG))
11106 (clobber (reg:TI XMM9_REG))
11107 (clobber (reg:TI XMM10_REG))
11108 (clobber (reg:TI XMM11_REG))
11109 (clobber (reg:TI XMM12_REG))
11110 (clobber (reg:TI XMM13_REG))
11111 (clobber (reg:TI XMM14_REG))
11112 (clobber (reg:TI XMM15_REG))
11113 (clobber (reg:DI SI_REG))
11114 (clobber (reg:DI DI_REG))
11115 (unspec [(match_operand 2 "const_int_operand" "")]
11116 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11117 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11119 "&& reload_completed"
11121 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11122 [(set_attr "type" "call")])
11124 (define_insn "*call_rex64_ms_sysv"
11125 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11126 (match_operand 1 "" ""))
11127 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11128 (clobber (reg:TI XMM6_REG))
11129 (clobber (reg:TI XMM7_REG))
11130 (clobber (reg:TI XMM8_REG))
11131 (clobber (reg:TI XMM9_REG))
11132 (clobber (reg:TI XMM10_REG))
11133 (clobber (reg:TI XMM11_REG))
11134 (clobber (reg:TI XMM12_REG))
11135 (clobber (reg:TI XMM13_REG))
11136 (clobber (reg:TI XMM14_REG))
11137 (clobber (reg:TI XMM15_REG))
11138 (clobber (reg:DI SI_REG))
11139 (clobber (reg:DI DI_REG))]
11140 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11141 "* return ix86_output_call_insn (insn, operands[0]);"
11142 [(set_attr "type" "call")])
11144 (define_insn_and_split "*sibcall_vzeroupper"
11145 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11146 (match_operand 1 "" ""))
11147 (unspec [(match_operand 2 "const_int_operand" "")]
11148 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11149 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11151 "&& reload_completed"
11153 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11154 [(set_attr "type" "call")])
11156 (define_insn "*sibcall"
11157 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11158 (match_operand 1 "" ""))]
11159 "SIBLING_CALL_P (insn)"
11160 "* return ix86_output_call_insn (insn, operands[0]);"
11161 [(set_attr "type" "call")])
11163 (define_expand "call_pop"
11164 [(parallel [(call (match_operand:QI 0 "" "")
11165 (match_operand:SI 1 "" ""))
11166 (set (reg:SI SP_REG)
11167 (plus:SI (reg:SI SP_REG)
11168 (match_operand:SI 3 "" "")))])]
11171 ix86_expand_call (NULL, operands[0], operands[1],
11172 operands[2], operands[3], false);
11176 (define_insn_and_split "*call_pop_vzeroupper"
11177 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11178 (match_operand:SI 1 "" ""))
11179 (set (reg:SI SP_REG)
11180 (plus:SI (reg:SI SP_REG)
11181 (match_operand:SI 2 "immediate_operand" "i")))
11182 (unspec [(match_operand 3 "const_int_operand" "")]
11183 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11184 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11186 "&& reload_completed"
11188 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11189 [(set_attr "type" "call")])
11191 (define_insn "*call_pop"
11192 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11193 (match_operand 1 "" ""))
11194 (set (reg:SI SP_REG)
11195 (plus:SI (reg:SI SP_REG)
11196 (match_operand:SI 2 "immediate_operand" "i")))]
11197 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11198 "* return ix86_output_call_insn (insn, operands[0]);"
11199 [(set_attr "type" "call")])
11201 (define_insn_and_split "*sibcall_pop_vzeroupper"
11202 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11203 (match_operand 1 "" ""))
11204 (set (reg:SI SP_REG)
11205 (plus:SI (reg:SI SP_REG)
11206 (match_operand:SI 2 "immediate_operand" "i")))
11207 (unspec [(match_operand 3 "const_int_operand" "")]
11208 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11209 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11211 "&& reload_completed"
11213 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11214 [(set_attr "type" "call")])
11216 (define_insn "*sibcall_pop"
11217 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11218 (match_operand 1 "" ""))
11219 (set (reg:SI SP_REG)
11220 (plus:SI (reg:SI SP_REG)
11221 (match_operand:SI 2 "immediate_operand" "i")))]
11222 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11223 "* return ix86_output_call_insn (insn, operands[0]);"
11224 [(set_attr "type" "call")])
11226 ;; Call subroutine, returning value in operand 0
11228 (define_expand "call_value"
11229 [(set (match_operand 0 "" "")
11230 (call (match_operand:QI 1 "" "")
11231 (match_operand 2 "" "")))
11232 (use (match_operand 3 "" ""))]
11235 ix86_expand_call (operands[0], operands[1], operands[2],
11236 operands[3], NULL, false);
11240 (define_expand "sibcall_value"
11241 [(set (match_operand 0 "" "")
11242 (call (match_operand:QI 1 "" "")
11243 (match_operand 2 "" "")))
11244 (use (match_operand 3 "" ""))]
11247 ix86_expand_call (operands[0], operands[1], operands[2],
11248 operands[3], NULL, true);
11252 (define_insn_and_split "*call_value_vzeroupper"
11253 [(set (match_operand 0 "" "")
11254 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11255 (match_operand 2 "" "")))
11256 (unspec [(match_operand 3 "const_int_operand" "")]
11257 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11258 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11260 "&& reload_completed"
11262 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11263 [(set_attr "type" "callv")])
11265 (define_insn "*call_value"
11266 [(set (match_operand 0 "" "")
11267 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11268 (match_operand 2 "" "")))]
11269 "!SIBLING_CALL_P (insn)"
11270 "* return ix86_output_call_insn (insn, operands[1]);"
11271 [(set_attr "type" "callv")])
11273 (define_insn_and_split "*sibcall_value_vzeroupper"
11274 [(set (match_operand 0 "" "")
11275 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11276 (match_operand 2 "" "")))
11277 (unspec [(match_operand 3 "const_int_operand" "")]
11278 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11279 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11281 "&& reload_completed"
11283 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11284 [(set_attr "type" "callv")])
11286 (define_insn "*sibcall_value"
11287 [(set (match_operand 0 "" "")
11288 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11289 (match_operand 2 "" "")))]
11290 "SIBLING_CALL_P (insn)"
11291 "* return ix86_output_call_insn (insn, operands[1]);"
11292 [(set_attr "type" "callv")])
11294 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11295 [(set (match_operand 0 "" "")
11296 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11297 (match_operand 2 "" "")))
11298 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11299 (clobber (reg:TI XMM6_REG))
11300 (clobber (reg:TI XMM7_REG))
11301 (clobber (reg:TI XMM8_REG))
11302 (clobber (reg:TI XMM9_REG))
11303 (clobber (reg:TI XMM10_REG))
11304 (clobber (reg:TI XMM11_REG))
11305 (clobber (reg:TI XMM12_REG))
11306 (clobber (reg:TI XMM13_REG))
11307 (clobber (reg:TI XMM14_REG))
11308 (clobber (reg:TI XMM15_REG))
11309 (clobber (reg:DI SI_REG))
11310 (clobber (reg:DI DI_REG))
11311 (unspec [(match_operand 3 "const_int_operand" "")]
11312 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11313 "TARGET_VZEROUPPER && TARGET_64BIT && !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_rex64_ms_sysv"
11321 [(set (match_operand 0 "" "")
11322 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11323 (match_operand 2 "" "")))
11324 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11325 (clobber (reg:TI XMM6_REG))
11326 (clobber (reg:TI XMM7_REG))
11327 (clobber (reg:TI XMM8_REG))
11328 (clobber (reg:TI XMM9_REG))
11329 (clobber (reg:TI XMM10_REG))
11330 (clobber (reg:TI XMM11_REG))
11331 (clobber (reg:TI XMM12_REG))
11332 (clobber (reg:TI XMM13_REG))
11333 (clobber (reg:TI XMM14_REG))
11334 (clobber (reg:TI XMM15_REG))
11335 (clobber (reg:DI SI_REG))
11336 (clobber (reg:DI DI_REG))]
11337 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11338 "* return ix86_output_call_insn (insn, operands[1]);"
11339 [(set_attr "type" "callv")])
11341 (define_expand "call_value_pop"
11342 [(parallel [(set (match_operand 0 "" "")
11343 (call (match_operand:QI 1 "" "")
11344 (match_operand:SI 2 "" "")))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 4 "" "")))])]
11350 ix86_expand_call (operands[0], operands[1], operands[2],
11351 operands[3], operands[4], false);
11355 (define_insn_and_split "*call_value_pop_vzeroupper"
11356 [(set (match_operand 0 "" "")
11357 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11358 (match_operand 2 "" "")))
11359 (set (reg:SI SP_REG)
11360 (plus:SI (reg:SI SP_REG)
11361 (match_operand:SI 3 "immediate_operand" "i")))
11362 (unspec [(match_operand 4 "const_int_operand" "")]
11363 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11364 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11366 "&& reload_completed"
11368 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11369 [(set_attr "type" "callv")])
11371 (define_insn "*call_value_pop"
11372 [(set (match_operand 0 "" "")
11373 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11374 (match_operand 2 "" "")))
11375 (set (reg:SI SP_REG)
11376 (plus:SI (reg:SI SP_REG)
11377 (match_operand:SI 3 "immediate_operand" "i")))]
11378 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11379 "* return ix86_output_call_insn (insn, operands[1]);"
11380 [(set_attr "type" "callv")])
11382 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11383 [(set (match_operand 0 "" "")
11384 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11385 (match_operand 2 "" "")))
11386 (set (reg:SI SP_REG)
11387 (plus:SI (reg:SI SP_REG)
11388 (match_operand:SI 3 "immediate_operand" "i")))
11389 (unspec [(match_operand 4 "const_int_operand" "")]
11390 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11391 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11393 "&& reload_completed"
11395 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11396 [(set_attr "type" "callv")])
11398 (define_insn "*sibcall_value_pop"
11399 [(set (match_operand 0 "" "")
11400 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11401 (match_operand 2 "" "")))
11402 (set (reg:SI SP_REG)
11403 (plus:SI (reg:SI SP_REG)
11404 (match_operand:SI 3 "immediate_operand" "i")))]
11405 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11406 "* return ix86_output_call_insn (insn, operands[1]);"
11407 [(set_attr "type" "callv")])
11409 ;; Call subroutine returning any type.
11411 (define_expand "untyped_call"
11412 [(parallel [(call (match_operand 0 "" "")
11414 (match_operand 1 "" "")
11415 (match_operand 2 "" "")])]
11420 /* In order to give reg-stack an easier job in validating two
11421 coprocessor registers as containing a possible return value,
11422 simply pretend the untyped call returns a complex long double
11425 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11426 and should have the default ABI. */
11428 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11429 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11430 operands[0], const0_rtx,
11431 GEN_INT ((TARGET_64BIT
11432 ? (ix86_abi == SYSV_ABI
11433 ? X86_64_SSE_REGPARM_MAX
11434 : X86_64_MS_SSE_REGPARM_MAX)
11435 : X86_32_SSE_REGPARM_MAX)
11439 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11441 rtx set = XVECEXP (operands[2], 0, i);
11442 emit_move_insn (SET_DEST (set), SET_SRC (set));
11445 /* The optimizer does not know that the call sets the function value
11446 registers we stored in the result block. We avoid problems by
11447 claiming that all hard registers are used and clobbered at this
11449 emit_insn (gen_blockage ());
11454 ;; Prologue and epilogue instructions
11456 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11457 ;; all of memory. This blocks insns from being moved across this point.
11459 (define_insn "blockage"
11460 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11463 [(set_attr "length" "0")])
11465 ;; Do not schedule instructions accessing memory across this point.
11467 (define_expand "memory_blockage"
11468 [(set (match_dup 0)
11469 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11472 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11473 MEM_VOLATILE_P (operands[0]) = 1;
11476 (define_insn "*memory_blockage"
11477 [(set (match_operand:BLK 0 "" "")
11478 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11481 [(set_attr "length" "0")])
11483 ;; As USE insns aren't meaningful after reload, this is used instead
11484 ;; to prevent deleting instructions setting registers for PIC code
11485 (define_insn "prologue_use"
11486 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11489 [(set_attr "length" "0")])
11491 ;; Insn emitted into the body of a function to return from a function.
11492 ;; This is only done if the function's epilogue is known to be simple.
11493 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11495 (define_expand "return"
11497 "ix86_can_use_return_insn_p ()"
11499 if (crtl->args.pops_args)
11501 rtx popc = GEN_INT (crtl->args.pops_args);
11502 emit_jump_insn (gen_return_pop_internal (popc));
11507 (define_insn "return_internal"
11511 [(set_attr "length" "1")
11512 (set_attr "atom_unit" "jeu")
11513 (set_attr "length_immediate" "0")
11514 (set_attr "modrm" "0")])
11516 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11517 ;; instruction Athlon and K8 have.
11519 (define_insn "return_internal_long"
11521 (unspec [(const_int 0)] UNSPEC_REP)]
11524 [(set_attr "length" "2")
11525 (set_attr "atom_unit" "jeu")
11526 (set_attr "length_immediate" "0")
11527 (set_attr "prefix_rep" "1")
11528 (set_attr "modrm" "0")])
11530 (define_insn "return_pop_internal"
11532 (use (match_operand:SI 0 "const_int_operand" ""))]
11535 [(set_attr "length" "3")
11536 (set_attr "atom_unit" "jeu")
11537 (set_attr "length_immediate" "2")
11538 (set_attr "modrm" "0")])
11540 (define_insn "return_indirect_internal"
11542 (use (match_operand:SI 0 "register_operand" "r"))]
11545 [(set_attr "type" "ibr")
11546 (set_attr "length_immediate" "0")])
11552 [(set_attr "length" "1")
11553 (set_attr "length_immediate" "0")
11554 (set_attr "modrm" "0")])
11556 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11557 (define_insn "nops"
11558 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11562 int num = INTVAL (operands[0]);
11564 gcc_assert (num >= 1 && num <= 8);
11567 fputs ("\tnop\n", asm_out_file);
11571 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11572 (set_attr "length_immediate" "0")
11573 (set_attr "modrm" "0")])
11575 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11576 ;; branch prediction penalty for the third jump in a 16-byte
11580 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11583 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11584 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11586 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11587 The align insn is used to avoid 3 jump instructions in the row to improve
11588 branch prediction and the benefits hardly outweigh the cost of extra 8
11589 nops on the average inserted by full alignment pseudo operation. */
11593 [(set_attr "length" "16")])
11595 (define_expand "prologue"
11598 "ix86_expand_prologue (); DONE;")
11600 (define_insn "set_got"
11601 [(set (match_operand:SI 0 "register_operand" "=r")
11602 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11603 (clobber (reg:CC FLAGS_REG))]
11605 "* return output_set_got (operands[0], NULL_RTX);"
11606 [(set_attr "type" "multi")
11607 (set_attr "length" "12")])
11609 (define_insn "set_got_labelled"
11610 [(set (match_operand:SI 0 "register_operand" "=r")
11611 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11613 (clobber (reg:CC FLAGS_REG))]
11615 "* return output_set_got (operands[0], operands[1]);"
11616 [(set_attr "type" "multi")
11617 (set_attr "length" "12")])
11619 (define_insn "set_got_rex64"
11620 [(set (match_operand:DI 0 "register_operand" "=r")
11621 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11623 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11624 [(set_attr "type" "lea")
11625 (set_attr "length_address" "4")
11626 (set_attr "mode" "DI")])
11628 (define_insn "set_rip_rex64"
11629 [(set (match_operand:DI 0 "register_operand" "=r")
11630 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11632 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11633 [(set_attr "type" "lea")
11634 (set_attr "length_address" "4")
11635 (set_attr "mode" "DI")])
11637 (define_insn "set_got_offset_rex64"
11638 [(set (match_operand:DI 0 "register_operand" "=r")
11640 [(label_ref (match_operand 1 "" ""))]
11641 UNSPEC_SET_GOT_OFFSET))]
11643 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11644 [(set_attr "type" "imov")
11645 (set_attr "length_immediate" "0")
11646 (set_attr "length_address" "8")
11647 (set_attr "mode" "DI")])
11649 (define_expand "epilogue"
11652 "ix86_expand_epilogue (1); DONE;")
11654 (define_expand "sibcall_epilogue"
11657 "ix86_expand_epilogue (0); DONE;")
11659 (define_expand "eh_return"
11660 [(use (match_operand 0 "register_operand" ""))]
11663 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11665 /* Tricky bit: we write the address of the handler to which we will
11666 be returning into someone else's stack frame, one word below the
11667 stack address we wish to restore. */
11668 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11669 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11670 tmp = gen_rtx_MEM (Pmode, tmp);
11671 emit_move_insn (tmp, ra);
11673 emit_jump_insn (gen_eh_return_internal ());
11678 (define_insn_and_split "eh_return_internal"
11682 "epilogue_completed"
11684 "ix86_expand_epilogue (2); DONE;")
11686 (define_insn "leave"
11687 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11688 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11689 (clobber (mem:BLK (scratch)))]
11692 [(set_attr "type" "leave")])
11694 (define_insn "leave_rex64"
11695 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11696 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11697 (clobber (mem:BLK (scratch)))]
11700 [(set_attr "type" "leave")])
11702 ;; Handle -fsplit-stack.
11704 (define_expand "split_stack_prologue"
11708 ix86_expand_split_stack_prologue ();
11712 ;; In order to support the call/return predictor, we use a return
11713 ;; instruction which the middle-end doesn't see.
11714 (define_insn "split_stack_return"
11715 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11716 UNSPECV_SPLIT_STACK_RETURN)]
11719 if (operands[0] == const0_rtx)
11724 [(set_attr "atom_unit" "jeu")
11725 (set_attr "modrm" "0")
11726 (set (attr "length")
11727 (if_then_else (match_operand:SI 0 "const0_operand" "")
11730 (set (attr "length_immediate")
11731 (if_then_else (match_operand:SI 0 "const0_operand" "")
11735 ;; If there are operand 0 bytes available on the stack, jump to
11738 (define_expand "split_stack_space_check"
11739 [(set (pc) (if_then_else
11740 (ltu (minus (reg SP_REG)
11741 (match_operand 0 "register_operand" ""))
11742 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11743 (label_ref (match_operand 1 "" ""))
11747 rtx reg, size, limit;
11749 reg = gen_reg_rtx (Pmode);
11750 size = force_reg (Pmode, operands[0]);
11751 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11752 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11753 UNSPEC_STACK_CHECK);
11754 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11755 ix86_expand_branch (GEU, reg, limit, operands[1]);
11760 ;; Bit manipulation instructions.
11762 (define_expand "ffs<mode>2"
11763 [(set (match_dup 2) (const_int -1))
11764 (parallel [(set (reg:CCZ FLAGS_REG)
11766 (match_operand:SWI48 1 "nonimmediate_operand" "")
11768 (set (match_operand:SWI48 0 "register_operand" "")
11769 (ctz:SWI48 (match_dup 1)))])
11770 (set (match_dup 0) (if_then_else:SWI48
11771 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11774 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11775 (clobber (reg:CC FLAGS_REG))])]
11778 if (<MODE>mode == SImode && !TARGET_CMOVE)
11780 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11783 operands[2] = gen_reg_rtx (<MODE>mode);
11786 (define_insn_and_split "ffssi2_no_cmove"
11787 [(set (match_operand:SI 0 "register_operand" "=r")
11788 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11789 (clobber (match_scratch:SI 2 "=&q"))
11790 (clobber (reg:CC FLAGS_REG))]
11793 "&& reload_completed"
11794 [(parallel [(set (reg:CCZ FLAGS_REG)
11795 (compare:CCZ (match_dup 1) (const_int 0)))
11796 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11797 (set (strict_low_part (match_dup 3))
11798 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11799 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11800 (clobber (reg:CC FLAGS_REG))])
11801 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11802 (clobber (reg:CC FLAGS_REG))])
11803 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11804 (clobber (reg:CC FLAGS_REG))])]
11806 operands[3] = gen_lowpart (QImode, operands[2]);
11807 ix86_expand_clear (operands[2]);
11810 (define_insn "*ffs<mode>_1"
11811 [(set (reg:CCZ FLAGS_REG)
11812 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11814 (set (match_operand:SWI48 0 "register_operand" "=r")
11815 (ctz:SWI48 (match_dup 1)))]
11817 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11818 [(set_attr "type" "alu1")
11819 (set_attr "prefix_0f" "1")
11820 (set_attr "mode" "<MODE>")])
11822 (define_insn "ctz<mode>2"
11823 [(set (match_operand:SWI248 0 "register_operand" "=r")
11824 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11825 (clobber (reg:CC FLAGS_REG))]
11829 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11831 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11833 [(set_attr "type" "alu1")
11834 (set_attr "prefix_0f" "1")
11835 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11836 (set_attr "mode" "<MODE>")])
11838 (define_expand "clz<mode>2"
11840 [(set (match_operand:SWI248 0 "register_operand" "")
11843 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11844 (clobber (reg:CC FLAGS_REG))])
11846 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11847 (clobber (reg:CC FLAGS_REG))])]
11852 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11855 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11858 (define_insn "clz<mode>2_lzcnt"
11859 [(set (match_operand:SWI248 0 "register_operand" "=r")
11860 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11861 (clobber (reg:CC FLAGS_REG))]
11863 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11864 [(set_attr "prefix_rep" "1")
11865 (set_attr "type" "bitmanip")
11866 (set_attr "mode" "<MODE>")])
11868 ;; BMI instructions.
11869 (define_insn "*bmi_andn_<mode>"
11870 [(set (match_operand:SWI48 0 "register_operand" "=r")
11873 (match_operand:SWI48 1 "register_operand" "r"))
11874 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11875 (clobber (reg:CC FLAGS_REG))]
11877 "andn\t{%2, %1, %0|%0, %1, %2}"
11878 [(set_attr "type" "bitmanip")
11879 (set_attr "mode" "<MODE>")])
11881 (define_insn "bmi_bextr_<mode>"
11882 [(set (match_operand:SWI48 0 "register_operand" "=r")
11883 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11884 (match_operand:SWI48 2 "register_operand" "r")]
11886 (clobber (reg:CC FLAGS_REG))]
11888 "bextr\t{%2, %1, %0|%0, %1, %2}"
11889 [(set_attr "type" "bitmanip")
11890 (set_attr "mode" "<MODE>")])
11892 (define_insn "*bmi_blsi_<mode>"
11893 [(set (match_operand:SWI48 0 "register_operand" "=r")
11896 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11898 (clobber (reg:CC FLAGS_REG))]
11900 "blsi\t{%1, %0|%0, %1}"
11901 [(set_attr "type" "bitmanip")
11902 (set_attr "mode" "<MODE>")])
11904 (define_insn "*bmi_blsmsk_<mode>"
11905 [(set (match_operand:SWI48 0 "register_operand" "=r")
11908 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11911 (clobber (reg:CC FLAGS_REG))]
11913 "blsmsk\t{%1, %0|%0, %1}"
11914 [(set_attr "type" "bitmanip")
11915 (set_attr "mode" "<MODE>")])
11917 (define_insn "*bmi_blsr_<mode>"
11918 [(set (match_operand:SWI48 0 "register_operand" "=r")
11921 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11924 (clobber (reg:CC FLAGS_REG))]
11926 "blsr\t{%1, %0|%0, %1}"
11927 [(set_attr "type" "bitmanip")
11928 (set_attr "mode" "<MODE>")])
11930 ;; TBM instructions.
11931 (define_insn "tbm_bextri_<mode>"
11932 [(set (match_operand:SWI48 0 "register_operand" "=r")
11933 (zero_extract:SWI48
11934 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11935 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11936 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11937 (clobber (reg:CC FLAGS_REG))]
11940 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11941 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11943 [(set_attr "type" "bitmanip")
11944 (set_attr "mode" "<MODE>")])
11946 (define_insn "*tbm_blcfill_<mode>"
11947 [(set (match_operand:SWI48 0 "register_operand" "=r")
11950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11953 (clobber (reg:CC FLAGS_REG))]
11955 "blcfill\t{%1, %0|%0, %1}"
11956 [(set_attr "type" "bitmanip")
11957 (set_attr "mode" "<MODE>")])
11959 (define_insn "*tbm_blci_<mode>"
11960 [(set (match_operand:SWI48 0 "register_operand" "=r")
11964 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11967 (clobber (reg:CC FLAGS_REG))]
11969 "blci\t{%1, %0|%0, %1}"
11970 [(set_attr "type" "bitmanip")
11971 (set_attr "mode" "<MODE>")])
11973 (define_insn "*tbm_blcic_<mode>"
11974 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11981 (clobber (reg:CC FLAGS_REG))]
11983 "blcic\t{%1, %0|%0, %1}"
11984 [(set_attr "type" "bitmanip")
11985 (set_attr "mode" "<MODE>")])
11987 (define_insn "*tbm_blcmsk_<mode>"
11988 [(set (match_operand:SWI48 0 "register_operand" "=r")
11991 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11994 (clobber (reg:CC FLAGS_REG))]
11996 "blcmsk\t{%1, %0|%0, %1}"
11997 [(set_attr "type" "bitmanip")
11998 (set_attr "mode" "<MODE>")])
12000 (define_insn "*tbm_blcs_<mode>"
12001 [(set (match_operand:SWI48 0 "register_operand" "=r")
12004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12007 (clobber (reg:CC FLAGS_REG))]
12009 "blcs\t{%1, %0|%0, %1}"
12010 [(set_attr "type" "bitmanip")
12011 (set_attr "mode" "<MODE>")])
12013 (define_insn "*tbm_blsfill_<mode>"
12014 [(set (match_operand:SWI48 0 "register_operand" "=r")
12017 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020 (clobber (reg:CC FLAGS_REG))]
12022 "blsfill\t{%1, %0|%0, %1}"
12023 [(set_attr "type" "bitmanip")
12024 (set_attr "mode" "<MODE>")])
12026 (define_insn "*tbm_blsic_<mode>"
12027 [(set (match_operand:SWI48 0 "register_operand" "=r")
12030 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12034 (clobber (reg:CC FLAGS_REG))]
12036 "blsic\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "bitmanip")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "*tbm_t1mskc_<mode>"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12048 (clobber (reg:CC FLAGS_REG))]
12050 "t1mskc\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "bitmanip")
12052 (set_attr "mode" "<MODE>")])
12054 (define_insn "*tbm_tzmsk_<mode>"
12055 [(set (match_operand:SWI48 0 "register_operand" "=r")
12058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12062 (clobber (reg:CC FLAGS_REG))]
12064 "tzmsk\t{%1, %0|%0, %1}"
12065 [(set_attr "type" "bitmanip")
12066 (set_attr "mode" "<MODE>")])
12068 (define_insn "bsr_rex64"
12069 [(set (match_operand:DI 0 "register_operand" "=r")
12070 (minus:DI (const_int 63)
12071 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12072 (clobber (reg:CC FLAGS_REG))]
12074 "bsr{q}\t{%1, %0|%0, %1}"
12075 [(set_attr "type" "alu1")
12076 (set_attr "prefix_0f" "1")
12077 (set_attr "mode" "DI")])
12080 [(set (match_operand:SI 0 "register_operand" "=r")
12081 (minus:SI (const_int 31)
12082 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12083 (clobber (reg:CC FLAGS_REG))]
12085 "bsr{l}\t{%1, %0|%0, %1}"
12086 [(set_attr "type" "alu1")
12087 (set_attr "prefix_0f" "1")
12088 (set_attr "mode" "SI")])
12090 (define_insn "*bsrhi"
12091 [(set (match_operand:HI 0 "register_operand" "=r")
12092 (minus:HI (const_int 15)
12093 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12094 (clobber (reg:CC FLAGS_REG))]
12096 "bsr{w}\t{%1, %0|%0, %1}"
12097 [(set_attr "type" "alu1")
12098 (set_attr "prefix_0f" "1")
12099 (set_attr "mode" "HI")])
12101 (define_insn "popcount<mode>2"
12102 [(set (match_operand:SWI248 0 "register_operand" "=r")
12104 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12105 (clobber (reg:CC FLAGS_REG))]
12109 return "popcnt\t{%1, %0|%0, %1}";
12111 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12114 [(set_attr "prefix_rep" "1")
12115 (set_attr "type" "bitmanip")
12116 (set_attr "mode" "<MODE>")])
12118 (define_insn "*popcount<mode>2_cmp"
12119 [(set (reg FLAGS_REG)
12122 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12124 (set (match_operand:SWI248 0 "register_operand" "=r")
12125 (popcount:SWI248 (match_dup 1)))]
12126 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12129 return "popcnt\t{%1, %0|%0, %1}";
12131 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12134 [(set_attr "prefix_rep" "1")
12135 (set_attr "type" "bitmanip")
12136 (set_attr "mode" "<MODE>")])
12138 (define_insn "*popcountsi2_cmp_zext"
12139 [(set (reg FLAGS_REG)
12141 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12143 (set (match_operand:DI 0 "register_operand" "=r")
12144 (zero_extend:DI(popcount:SI (match_dup 1))))]
12145 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12148 return "popcnt\t{%1, %0|%0, %1}";
12150 return "popcnt{l}\t{%1, %0|%0, %1}";
12153 [(set_attr "prefix_rep" "1")
12154 (set_attr "type" "bitmanip")
12155 (set_attr "mode" "SI")])
12157 (define_expand "bswap<mode>2"
12158 [(set (match_operand:SWI48 0 "register_operand" "")
12159 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12162 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12164 rtx x = operands[0];
12166 emit_move_insn (x, operands[1]);
12167 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12168 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12169 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12174 (define_insn "*bswap<mode>2_movbe"
12175 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12176 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12178 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12181 movbe\t{%1, %0|%0, %1}
12182 movbe\t{%1, %0|%0, %1}"
12183 [(set_attr "type" "bitmanip,imov,imov")
12184 (set_attr "modrm" "0,1,1")
12185 (set_attr "prefix_0f" "*,1,1")
12186 (set_attr "prefix_extra" "*,1,1")
12187 (set_attr "mode" "<MODE>")])
12189 (define_insn "*bswap<mode>2_1"
12190 [(set (match_operand:SWI48 0 "register_operand" "=r")
12191 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "modrm" "0")
12196 (set_attr "mode" "<MODE>")])
12198 (define_insn "*bswaphi_lowpart_1"
12199 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12200 (bswap:HI (match_dup 0)))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12204 xchg{b}\t{%h0, %b0|%b0, %h0}
12205 rol{w}\t{$8, %0|%0, 8}"
12206 [(set_attr "length" "2,4")
12207 (set_attr "mode" "QI,HI")])
12209 (define_insn "bswaphi_lowpart"
12210 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12211 (bswap:HI (match_dup 0)))
12212 (clobber (reg:CC FLAGS_REG))]
12214 "rol{w}\t{$8, %0|%0, 8}"
12215 [(set_attr "length" "4")
12216 (set_attr "mode" "HI")])
12218 (define_expand "paritydi2"
12219 [(set (match_operand:DI 0 "register_operand" "")
12220 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12223 rtx scratch = gen_reg_rtx (QImode);
12226 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12227 NULL_RTX, operands[1]));
12229 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12230 gen_rtx_REG (CCmode, FLAGS_REG),
12232 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12235 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12238 rtx tmp = gen_reg_rtx (SImode);
12240 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12241 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12246 (define_expand "paritysi2"
12247 [(set (match_operand:SI 0 "register_operand" "")
12248 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12251 rtx scratch = gen_reg_rtx (QImode);
12254 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12256 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12257 gen_rtx_REG (CCmode, FLAGS_REG),
12259 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12261 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12265 (define_insn_and_split "paritydi2_cmp"
12266 [(set (reg:CC FLAGS_REG)
12267 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12269 (clobber (match_scratch:DI 0 "=r"))
12270 (clobber (match_scratch:SI 1 "=&r"))
12271 (clobber (match_scratch:HI 2 "=Q"))]
12274 "&& reload_completed"
12276 [(set (match_dup 1)
12277 (xor:SI (match_dup 1) (match_dup 4)))
12278 (clobber (reg:CC FLAGS_REG))])
12280 [(set (reg:CC FLAGS_REG)
12281 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12282 (clobber (match_dup 1))
12283 (clobber (match_dup 2))])]
12285 operands[4] = gen_lowpart (SImode, operands[3]);
12289 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12290 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12293 operands[1] = gen_highpart (SImode, operands[3]);
12296 (define_insn_and_split "paritysi2_cmp"
12297 [(set (reg:CC FLAGS_REG)
12298 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12300 (clobber (match_scratch:SI 0 "=r"))
12301 (clobber (match_scratch:HI 1 "=&Q"))]
12304 "&& reload_completed"
12306 [(set (match_dup 1)
12307 (xor:HI (match_dup 1) (match_dup 3)))
12308 (clobber (reg:CC FLAGS_REG))])
12310 [(set (reg:CC FLAGS_REG)
12311 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12312 (clobber (match_dup 1))])]
12314 operands[3] = gen_lowpart (HImode, operands[2]);
12316 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12317 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12320 (define_insn "*parityhi2_cmp"
12321 [(set (reg:CC FLAGS_REG)
12322 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12324 (clobber (match_scratch:HI 0 "=Q"))]
12326 "xor{b}\t{%h0, %b0|%b0, %h0}"
12327 [(set_attr "length" "2")
12328 (set_attr "mode" "HI")])
12330 ;; Thread-local storage patterns for ELF.
12332 ;; Note that these code sequences must appear exactly as shown
12333 ;; in order to allow linker relaxation.
12335 (define_insn "*tls_global_dynamic_32_gnu"
12336 [(set (match_operand:SI 0 "register_operand" "=a")
12338 [(match_operand:SI 1 "register_operand" "b")
12339 (match_operand:SI 2 "tls_symbolic_operand" "")
12340 (match_operand:SI 3 "constant_call_address_operand" "z")]
12342 (clobber (match_scratch:SI 4 "=d"))
12343 (clobber (match_scratch:SI 5 "=c"))
12344 (clobber (reg:CC FLAGS_REG))]
12345 "!TARGET_64BIT && TARGET_GNU_TLS"
12348 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12349 if (TARGET_SUN_TLS)
12350 #ifdef HAVE_AS_IX86_TLSGDPLT
12351 return "call\t%a2@tlsgdplt";
12353 return "call\t%p3@plt";
12355 return "call\t%P3";
12357 [(set_attr "type" "multi")
12358 (set_attr "length" "12")])
12360 (define_expand "tls_global_dynamic_32"
12362 [(set (match_operand:SI 0 "register_operand" "")
12363 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12364 (match_operand:SI 1 "tls_symbolic_operand" "")
12365 (match_operand:SI 3 "constant_call_address_operand" "")]
12367 (clobber (match_scratch:SI 4 ""))
12368 (clobber (match_scratch:SI 5 ""))
12369 (clobber (reg:CC FLAGS_REG))])])
12371 (define_insn "*tls_global_dynamic_64"
12372 [(set (match_operand:DI 0 "register_operand" "=a")
12374 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12375 (match_operand:DI 3 "" "")))
12376 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12381 fputs (ASM_BYTE "0x66\n", asm_out_file);
12383 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12384 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12385 fputs ("\trex64\n", asm_out_file);
12386 if (TARGET_SUN_TLS)
12387 return "call\t%p2@plt";
12388 return "call\t%P2";
12390 [(set_attr "type" "multi")
12391 (set (attr "length")
12392 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12394 (define_expand "tls_global_dynamic_64"
12396 [(set (match_operand:DI 0 "register_operand" "")
12398 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12400 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12403 (define_insn "*tls_local_dynamic_base_32_gnu"
12404 [(set (match_operand:SI 0 "register_operand" "=a")
12406 [(match_operand:SI 1 "register_operand" "b")
12407 (match_operand:SI 2 "constant_call_address_operand" "z")]
12408 UNSPEC_TLS_LD_BASE))
12409 (clobber (match_scratch:SI 3 "=d"))
12410 (clobber (match_scratch:SI 4 "=c"))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "!TARGET_64BIT && TARGET_GNU_TLS"
12415 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12416 if (TARGET_SUN_TLS)
12417 #ifdef HAVE_AS_IX86_TLSLDMPLT
12418 return "call\t%&@tlsldmplt";
12420 return "call\t%p2@plt";
12422 return "call\t%P2";
12424 [(set_attr "type" "multi")
12425 (set_attr "length" "11")])
12427 (define_expand "tls_local_dynamic_base_32"
12429 [(set (match_operand:SI 0 "register_operand" "")
12431 [(match_operand:SI 1 "register_operand" "")
12432 (match_operand:SI 2 "constant_call_address_operand" "")]
12433 UNSPEC_TLS_LD_BASE))
12434 (clobber (match_scratch:SI 3 ""))
12435 (clobber (match_scratch:SI 4 ""))
12436 (clobber (reg:CC FLAGS_REG))])])
12438 (define_insn "*tls_local_dynamic_base_64"
12439 [(set (match_operand:DI 0 "register_operand" "=a")
12441 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12442 (match_operand:DI 2 "" "")))
12443 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12447 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12448 if (TARGET_SUN_TLS)
12449 return "call\t%p1@plt";
12450 return "call\t%P1";
12452 [(set_attr "type" "multi")
12453 (set_attr "length" "12")])
12455 (define_expand "tls_local_dynamic_base_64"
12457 [(set (match_operand:DI 0 "register_operand" "")
12459 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12461 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12463 ;; Local dynamic of a single variable is a lose. Show combine how
12464 ;; to convert that back to global dynamic.
12466 (define_insn_and_split "*tls_local_dynamic_32_once"
12467 [(set (match_operand:SI 0 "register_operand" "=a")
12469 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12470 (match_operand:SI 2 "constant_call_address_operand" "z")]
12471 UNSPEC_TLS_LD_BASE)
12472 (const:SI (unspec:SI
12473 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12475 (clobber (match_scratch:SI 4 "=d"))
12476 (clobber (match_scratch:SI 5 "=c"))
12477 (clobber (reg:CC FLAGS_REG))]
12482 [(set (match_dup 0)
12483 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12485 (clobber (match_dup 4))
12486 (clobber (match_dup 5))
12487 (clobber (reg:CC FLAGS_REG))])])
12489 ;; Segment register for the thread base ptr load
12490 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12492 ;; Load and add the thread base pointer from %<tp_seg>:0.
12493 (define_insn "*load_tp_x32"
12494 [(set (match_operand:SI 0 "register_operand" "=r")
12495 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12497 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12498 [(set_attr "type" "imov")
12499 (set_attr "modrm" "0")
12500 (set_attr "length" "7")
12501 (set_attr "memory" "load")
12502 (set_attr "imm_disp" "false")])
12504 (define_insn "*load_tp_x32_zext"
12505 [(set (match_operand:DI 0 "register_operand" "=r")
12506 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12508 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12509 [(set_attr "type" "imov")
12510 (set_attr "modrm" "0")
12511 (set_attr "length" "7")
12512 (set_attr "memory" "load")
12513 (set_attr "imm_disp" "false")])
12515 (define_insn "*load_tp_<mode>"
12516 [(set (match_operand:P 0 "register_operand" "=r")
12517 (unspec:P [(const_int 0)] UNSPEC_TP))]
12519 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12520 [(set_attr "type" "imov")
12521 (set_attr "modrm" "0")
12522 (set_attr "length" "7")
12523 (set_attr "memory" "load")
12524 (set_attr "imm_disp" "false")])
12526 (define_insn "*add_tp_x32"
12527 [(set (match_operand:SI 0 "register_operand" "=r")
12528 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12529 (match_operand:SI 1 "register_operand" "0")))
12530 (clobber (reg:CC FLAGS_REG))]
12532 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12533 [(set_attr "type" "alu")
12534 (set_attr "modrm" "0")
12535 (set_attr "length" "7")
12536 (set_attr "memory" "load")
12537 (set_attr "imm_disp" "false")])
12539 (define_insn "*add_tp_x32_zext"
12540 [(set (match_operand:DI 0 "register_operand" "=r")
12542 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12543 (match_operand:SI 1 "register_operand" "0"))))
12544 (clobber (reg:CC FLAGS_REG))]
12546 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12547 [(set_attr "type" "alu")
12548 (set_attr "modrm" "0")
12549 (set_attr "length" "7")
12550 (set_attr "memory" "load")
12551 (set_attr "imm_disp" "false")])
12553 (define_insn "*add_tp_<mode>"
12554 [(set (match_operand:P 0 "register_operand" "=r")
12555 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12556 (match_operand:P 1 "register_operand" "0")))
12557 (clobber (reg:CC FLAGS_REG))]
12559 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12560 [(set_attr "type" "alu")
12561 (set_attr "modrm" "0")
12562 (set_attr "length" "7")
12563 (set_attr "memory" "load")
12564 (set_attr "imm_disp" "false")])
12566 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12567 ;; %rax as destination of the initial executable code sequence.
12568 (define_insn "tls_initial_exec_64_sun"
12569 [(set (match_operand:DI 0 "register_operand" "=a")
12571 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12572 UNSPEC_TLS_IE_SUN))
12573 (clobber (reg:CC FLAGS_REG))]
12574 "TARGET_64BIT && TARGET_SUN_TLS"
12577 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12578 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12580 [(set_attr "type" "multi")])
12582 ;; GNU2 TLS patterns can be split.
12584 (define_expand "tls_dynamic_gnu2_32"
12585 [(set (match_dup 3)
12586 (plus:SI (match_operand:SI 2 "register_operand" "")
12588 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12591 [(set (match_operand:SI 0 "register_operand" "")
12592 (unspec:SI [(match_dup 1) (match_dup 3)
12593 (match_dup 2) (reg:SI SP_REG)]
12595 (clobber (reg:CC FLAGS_REG))])]
12596 "!TARGET_64BIT && TARGET_GNU2_TLS"
12598 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12599 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12602 (define_insn "*tls_dynamic_gnu2_lea_32"
12603 [(set (match_operand:SI 0 "register_operand" "=r")
12604 (plus:SI (match_operand:SI 1 "register_operand" "b")
12606 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12607 UNSPEC_TLSDESC))))]
12608 "!TARGET_64BIT && TARGET_GNU2_TLS"
12609 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12610 [(set_attr "type" "lea")
12611 (set_attr "mode" "SI")
12612 (set_attr "length" "6")
12613 (set_attr "length_address" "4")])
12615 (define_insn "*tls_dynamic_gnu2_call_32"
12616 [(set (match_operand:SI 0 "register_operand" "=a")
12617 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12618 (match_operand:SI 2 "register_operand" "0")
12619 ;; we have to make sure %ebx still points to the GOT
12620 (match_operand:SI 3 "register_operand" "b")
12623 (clobber (reg:CC FLAGS_REG))]
12624 "!TARGET_64BIT && TARGET_GNU2_TLS"
12625 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12626 [(set_attr "type" "call")
12627 (set_attr "length" "2")
12628 (set_attr "length_address" "0")])
12630 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12631 [(set (match_operand:SI 0 "register_operand" "=&a")
12633 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12634 (match_operand:SI 4 "" "")
12635 (match_operand:SI 2 "register_operand" "b")
12638 (const:SI (unspec:SI
12639 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12641 (clobber (reg:CC FLAGS_REG))]
12642 "!TARGET_64BIT && TARGET_GNU2_TLS"
12645 [(set (match_dup 0) (match_dup 5))]
12647 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12648 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12651 (define_expand "tls_dynamic_gnu2_64"
12652 [(set (match_dup 2)
12653 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12656 [(set (match_operand:DI 0 "register_operand" "")
12657 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12659 (clobber (reg:CC FLAGS_REG))])]
12660 "TARGET_64BIT && TARGET_GNU2_TLS"
12662 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12663 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12666 (define_insn "*tls_dynamic_gnu2_lea_64"
12667 [(set (match_operand:DI 0 "register_operand" "=r")
12668 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12670 "TARGET_64BIT && TARGET_GNU2_TLS"
12671 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12672 [(set_attr "type" "lea")
12673 (set_attr "mode" "DI")
12674 (set_attr "length" "7")
12675 (set_attr "length_address" "4")])
12677 (define_insn "*tls_dynamic_gnu2_call_64"
12678 [(set (match_operand:DI 0 "register_operand" "=a")
12679 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12680 (match_operand:DI 2 "register_operand" "0")
12683 (clobber (reg:CC FLAGS_REG))]
12684 "TARGET_64BIT && TARGET_GNU2_TLS"
12685 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12686 [(set_attr "type" "call")
12687 (set_attr "length" "2")
12688 (set_attr "length_address" "0")])
12690 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12691 [(set (match_operand:DI 0 "register_operand" "=&a")
12693 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12694 (match_operand:DI 3 "" "")
12697 (const:DI (unspec:DI
12698 [(match_operand 1 "tls_symbolic_operand" "")]
12700 (clobber (reg:CC FLAGS_REG))]
12701 "TARGET_64BIT && TARGET_GNU2_TLS"
12704 [(set (match_dup 0) (match_dup 4))]
12706 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12707 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12710 ;; These patterns match the binary 387 instructions for addM3, subM3,
12711 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12712 ;; SFmode. The first is the normal insn, the second the same insn but
12713 ;; with one operand a conversion, and the third the same insn but with
12714 ;; the other operand a conversion. The conversion may be SFmode or
12715 ;; SImode if the target mode DFmode, but only SImode if the target mode
12718 ;; Gcc is slightly more smart about handling normal two address instructions
12719 ;; so use special patterns for add and mull.
12721 (define_insn "*fop_<mode>_comm_mixed"
12722 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12723 (match_operator:MODEF 3 "binary_fp_operator"
12724 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12725 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12726 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12727 && COMMUTATIVE_ARITH_P (operands[3])
12728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12729 "* return output_387_binary_op (insn, operands);"
12730 [(set (attr "type")
12731 (if_then_else (eq_attr "alternative" "1,2")
12732 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12733 (const_string "ssemul")
12734 (const_string "sseadd"))
12735 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12736 (const_string "fmul")
12737 (const_string "fop"))))
12738 (set_attr "isa" "*,noavx,avx")
12739 (set_attr "prefix" "orig,orig,vex")
12740 (set_attr "mode" "<MODE>")])
12742 (define_insn "*fop_<mode>_comm_sse"
12743 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12744 (match_operator:MODEF 3 "binary_fp_operator"
12745 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12746 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12747 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12748 && COMMUTATIVE_ARITH_P (operands[3])
12749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12750 "* return output_387_binary_op (insn, operands);"
12751 [(set (attr "type")
12752 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12753 (const_string "ssemul")
12754 (const_string "sseadd")))
12755 (set_attr "isa" "noavx,avx")
12756 (set_attr "prefix" "orig,vex")
12757 (set_attr "mode" "<MODE>")])
12759 (define_insn "*fop_<mode>_comm_i387"
12760 [(set (match_operand:MODEF 0 "register_operand" "=f")
12761 (match_operator:MODEF 3 "binary_fp_operator"
12762 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12763 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12764 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12765 && COMMUTATIVE_ARITH_P (operands[3])
12766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12767 "* return output_387_binary_op (insn, operands);"
12768 [(set (attr "type")
12769 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12770 (const_string "fmul")
12771 (const_string "fop")))
12772 (set_attr "mode" "<MODE>")])
12774 (define_insn "*fop_<mode>_1_mixed"
12775 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12776 (match_operator:MODEF 3 "binary_fp_operator"
12777 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12778 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12779 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12780 && !COMMUTATIVE_ARITH_P (operands[3])
12781 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12782 "* return output_387_binary_op (insn, operands);"
12783 [(set (attr "type")
12784 (cond [(and (eq_attr "alternative" "2,3")
12785 (match_operand:MODEF 3 "mult_operator" ""))
12786 (const_string "ssemul")
12787 (and (eq_attr "alternative" "2,3")
12788 (match_operand:MODEF 3 "div_operator" ""))
12789 (const_string "ssediv")
12790 (eq_attr "alternative" "2,3")
12791 (const_string "sseadd")
12792 (match_operand:MODEF 3 "mult_operator" "")
12793 (const_string "fmul")
12794 (match_operand:MODEF 3 "div_operator" "")
12795 (const_string "fdiv")
12797 (const_string "fop")))
12798 (set_attr "isa" "*,*,noavx,avx")
12799 (set_attr "prefix" "orig,orig,orig,vex")
12800 (set_attr "mode" "<MODE>")])
12802 (define_insn "*rcpsf2_sse"
12803 [(set (match_operand:SF 0 "register_operand" "=x")
12804 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12807 "%vrcpss\t{%1, %d0|%d0, %1}"
12808 [(set_attr "type" "sse")
12809 (set_attr "atom_sse_attr" "rcp")
12810 (set_attr "prefix" "maybe_vex")
12811 (set_attr "mode" "SF")])
12813 (define_insn "*fop_<mode>_1_sse"
12814 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12815 (match_operator:MODEF 3 "binary_fp_operator"
12816 [(match_operand:MODEF 1 "register_operand" "0,x")
12817 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12818 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12819 && !COMMUTATIVE_ARITH_P (operands[3])"
12820 "* return output_387_binary_op (insn, operands);"
12821 [(set (attr "type")
12822 (cond [(match_operand:MODEF 3 "mult_operator" "")
12823 (const_string "ssemul")
12824 (match_operand:MODEF 3 "div_operator" "")
12825 (const_string "ssediv")
12827 (const_string "sseadd")))
12828 (set_attr "isa" "noavx,avx")
12829 (set_attr "prefix" "orig,vex")
12830 (set_attr "mode" "<MODE>")])
12832 ;; This pattern is not fully shadowed by the pattern above.
12833 (define_insn "*fop_<mode>_1_i387"
12834 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12835 (match_operator:MODEF 3 "binary_fp_operator"
12836 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12837 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12838 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12839 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12840 && !COMMUTATIVE_ARITH_P (operands[3])
12841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12842 "* return output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:MODEF 3 "mult_operator" "")
12845 (const_string "fmul")
12846 (match_operand:MODEF 3 "div_operator" "")
12847 (const_string "fdiv")
12849 (const_string "fop")))
12850 (set_attr "mode" "<MODE>")])
12852 ;; ??? Add SSE splitters for these!
12853 (define_insn "*fop_<MODEF:mode>_2_i387"
12854 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12855 (match_operator:MODEF 3 "binary_fp_operator"
12857 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12858 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12859 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12860 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12861 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12862 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12863 [(set (attr "type")
12864 (cond [(match_operand:MODEF 3 "mult_operator" "")
12865 (const_string "fmul")
12866 (match_operand:MODEF 3 "div_operator" "")
12867 (const_string "fdiv")
12869 (const_string "fop")))
12870 (set_attr "fp_int_src" "true")
12871 (set_attr "mode" "<SWI24:MODE>")])
12873 (define_insn "*fop_<MODEF:mode>_3_i387"
12874 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12875 (match_operator:MODEF 3 "binary_fp_operator"
12876 [(match_operand:MODEF 1 "register_operand" "0,0")
12878 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12879 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12880 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12881 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12882 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12883 [(set (attr "type")
12884 (cond [(match_operand:MODEF 3 "mult_operator" "")
12885 (const_string "fmul")
12886 (match_operand:MODEF 3 "div_operator" "")
12887 (const_string "fdiv")
12889 (const_string "fop")))
12890 (set_attr "fp_int_src" "true")
12891 (set_attr "mode" "<MODE>")])
12893 (define_insn "*fop_df_4_i387"
12894 [(set (match_operand:DF 0 "register_operand" "=f,f")
12895 (match_operator:DF 3 "binary_fp_operator"
12897 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12898 (match_operand:DF 2 "register_operand" "0,f")]))]
12899 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12900 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12902 "* return output_387_binary_op (insn, operands);"
12903 [(set (attr "type")
12904 (cond [(match_operand:DF 3 "mult_operator" "")
12905 (const_string "fmul")
12906 (match_operand:DF 3 "div_operator" "")
12907 (const_string "fdiv")
12909 (const_string "fop")))
12910 (set_attr "mode" "SF")])
12912 (define_insn "*fop_df_5_i387"
12913 [(set (match_operand:DF 0 "register_operand" "=f,f")
12914 (match_operator:DF 3 "binary_fp_operator"
12915 [(match_operand:DF 1 "register_operand" "0,f")
12917 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12918 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12919 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12920 "* return output_387_binary_op (insn, operands);"
12921 [(set (attr "type")
12922 (cond [(match_operand:DF 3 "mult_operator" "")
12923 (const_string "fmul")
12924 (match_operand:DF 3 "div_operator" "")
12925 (const_string "fdiv")
12927 (const_string "fop")))
12928 (set_attr "mode" "SF")])
12930 (define_insn "*fop_df_6_i387"
12931 [(set (match_operand:DF 0 "register_operand" "=f,f")
12932 (match_operator:DF 3 "binary_fp_operator"
12934 (match_operand:SF 1 "register_operand" "0,f"))
12936 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12937 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12938 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12939 "* return output_387_binary_op (insn, operands);"
12940 [(set (attr "type")
12941 (cond [(match_operand:DF 3 "mult_operator" "")
12942 (const_string "fmul")
12943 (match_operand:DF 3 "div_operator" "")
12944 (const_string "fdiv")
12946 (const_string "fop")))
12947 (set_attr "mode" "SF")])
12949 (define_insn "*fop_xf_comm_i387"
12950 [(set (match_operand:XF 0 "register_operand" "=f")
12951 (match_operator:XF 3 "binary_fp_operator"
12952 [(match_operand:XF 1 "register_operand" "%0")
12953 (match_operand:XF 2 "register_operand" "f")]))]
12955 && COMMUTATIVE_ARITH_P (operands[3])"
12956 "* return output_387_binary_op (insn, operands);"
12957 [(set (attr "type")
12958 (if_then_else (match_operand:XF 3 "mult_operator" "")
12959 (const_string "fmul")
12960 (const_string "fop")))
12961 (set_attr "mode" "XF")])
12963 (define_insn "*fop_xf_1_i387"
12964 [(set (match_operand:XF 0 "register_operand" "=f,f")
12965 (match_operator:XF 3 "binary_fp_operator"
12966 [(match_operand:XF 1 "register_operand" "0,f")
12967 (match_operand:XF 2 "register_operand" "f,0")]))]
12969 && !COMMUTATIVE_ARITH_P (operands[3])"
12970 "* return output_387_binary_op (insn, operands);"
12971 [(set (attr "type")
12972 (cond [(match_operand:XF 3 "mult_operator" "")
12973 (const_string "fmul")
12974 (match_operand:XF 3 "div_operator" "")
12975 (const_string "fdiv")
12977 (const_string "fop")))
12978 (set_attr "mode" "XF")])
12980 (define_insn "*fop_xf_2_i387"
12981 [(set (match_operand:XF 0 "register_operand" "=f,f")
12982 (match_operator:XF 3 "binary_fp_operator"
12984 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12985 (match_operand:XF 2 "register_operand" "0,0")]))]
12986 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12987 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12988 [(set (attr "type")
12989 (cond [(match_operand:XF 3 "mult_operator" "")
12990 (const_string "fmul")
12991 (match_operand:XF 3 "div_operator" "")
12992 (const_string "fdiv")
12994 (const_string "fop")))
12995 (set_attr "fp_int_src" "true")
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_xf_3_i387"
12999 [(set (match_operand:XF 0 "register_operand" "=f,f")
13000 (match_operator:XF 3 "binary_fp_operator"
13001 [(match_operand:XF 1 "register_operand" "0,0")
13003 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13004 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13005 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13006 [(set (attr "type")
13007 (cond [(match_operand:XF 3 "mult_operator" "")
13008 (const_string "fmul")
13009 (match_operand:XF 3 "div_operator" "")
13010 (const_string "fdiv")
13012 (const_string "fop")))
13013 (set_attr "fp_int_src" "true")
13014 (set_attr "mode" "<MODE>")])
13016 (define_insn "*fop_xf_4_i387"
13017 [(set (match_operand:XF 0 "register_operand" "=f,f")
13018 (match_operator:XF 3 "binary_fp_operator"
13020 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13021 (match_operand:XF 2 "register_operand" "0,f")]))]
13023 "* return output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (cond [(match_operand:XF 3 "mult_operator" "")
13026 (const_string "fmul")
13027 (match_operand:XF 3 "div_operator" "")
13028 (const_string "fdiv")
13030 (const_string "fop")))
13031 (set_attr "mode" "<MODE>")])
13033 (define_insn "*fop_xf_5_i387"
13034 [(set (match_operand:XF 0 "register_operand" "=f,f")
13035 (match_operator:XF 3 "binary_fp_operator"
13036 [(match_operand:XF 1 "register_operand" "0,f")
13038 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13040 "* return output_387_binary_op (insn, operands);"
13041 [(set (attr "type")
13042 (cond [(match_operand:XF 3 "mult_operator" "")
13043 (const_string "fmul")
13044 (match_operand:XF 3 "div_operator" "")
13045 (const_string "fdiv")
13047 (const_string "fop")))
13048 (set_attr "mode" "<MODE>")])
13050 (define_insn "*fop_xf_6_i387"
13051 [(set (match_operand:XF 0 "register_operand" "=f,f")
13052 (match_operator:XF 3 "binary_fp_operator"
13054 (match_operand:MODEF 1 "register_operand" "0,f"))
13056 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13058 "* return output_387_binary_op (insn, operands);"
13059 [(set (attr "type")
13060 (cond [(match_operand:XF 3 "mult_operator" "")
13061 (const_string "fmul")
13062 (match_operand:XF 3 "div_operator" "")
13063 (const_string "fdiv")
13065 (const_string "fop")))
13066 (set_attr "mode" "<MODE>")])
13069 [(set (match_operand 0 "register_operand" "")
13070 (match_operator 3 "binary_fp_operator"
13071 [(float (match_operand:SWI24 1 "register_operand" ""))
13072 (match_operand 2 "register_operand" "")]))]
13074 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13075 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13078 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13079 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13080 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13081 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13082 GET_MODE (operands[3]),
13085 ix86_free_from_memory (GET_MODE (operands[1]));
13090 [(set (match_operand 0 "register_operand" "")
13091 (match_operator 3 "binary_fp_operator"
13092 [(match_operand 1 "register_operand" "")
13093 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13095 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13096 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13099 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13100 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13101 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13102 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13103 GET_MODE (operands[3]),
13106 ix86_free_from_memory (GET_MODE (operands[2]));
13110 ;; FPU special functions.
13112 ;; This pattern implements a no-op XFmode truncation for
13113 ;; all fancy i386 XFmode math functions.
13115 (define_insn "truncxf<mode>2_i387_noop_unspec"
13116 [(set (match_operand:MODEF 0 "register_operand" "=f")
13117 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13118 UNSPEC_TRUNC_NOOP))]
13119 "TARGET_USE_FANCY_MATH_387"
13120 "* return output_387_reg_move (insn, operands);"
13121 [(set_attr "type" "fmov")
13122 (set_attr "mode" "<MODE>")])
13124 (define_insn "sqrtxf2"
13125 [(set (match_operand:XF 0 "register_operand" "=f")
13126 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13127 "TARGET_USE_FANCY_MATH_387"
13129 [(set_attr "type" "fpspc")
13130 (set_attr "mode" "XF")
13131 (set_attr "athlon_decode" "direct")
13132 (set_attr "amdfam10_decode" "direct")
13133 (set_attr "bdver1_decode" "direct")])
13135 (define_insn "sqrt_extend<mode>xf2_i387"
13136 [(set (match_operand:XF 0 "register_operand" "=f")
13139 (match_operand:MODEF 1 "register_operand" "0"))))]
13140 "TARGET_USE_FANCY_MATH_387"
13142 [(set_attr "type" "fpspc")
13143 (set_attr "mode" "XF")
13144 (set_attr "athlon_decode" "direct")
13145 (set_attr "amdfam10_decode" "direct")
13146 (set_attr "bdver1_decode" "direct")])
13148 (define_insn "*rsqrtsf2_sse"
13149 [(set (match_operand:SF 0 "register_operand" "=x")
13150 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13153 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13154 [(set_attr "type" "sse")
13155 (set_attr "atom_sse_attr" "rcp")
13156 (set_attr "prefix" "maybe_vex")
13157 (set_attr "mode" "SF")])
13159 (define_expand "rsqrtsf2"
13160 [(set (match_operand:SF 0 "register_operand" "")
13161 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13165 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13169 (define_insn "*sqrt<mode>2_sse"
13170 [(set (match_operand:MODEF 0 "register_operand" "=x")
13172 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13173 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13174 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13175 [(set_attr "type" "sse")
13176 (set_attr "atom_sse_attr" "sqrt")
13177 (set_attr "prefix" "maybe_vex")
13178 (set_attr "mode" "<MODE>")
13179 (set_attr "athlon_decode" "*")
13180 (set_attr "amdfam10_decode" "*")
13181 (set_attr "bdver1_decode" "*")])
13183 (define_expand "sqrt<mode>2"
13184 [(set (match_operand:MODEF 0 "register_operand" "")
13186 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13187 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13188 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13190 if (<MODE>mode == SFmode
13191 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13192 && flag_finite_math_only && !flag_trapping_math
13193 && flag_unsafe_math_optimizations)
13195 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13199 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13201 rtx op0 = gen_reg_rtx (XFmode);
13202 rtx op1 = force_reg (<MODE>mode, operands[1]);
13204 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13205 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13210 (define_insn "fpremxf4_i387"
13211 [(set (match_operand:XF 0 "register_operand" "=f")
13212 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13213 (match_operand:XF 3 "register_operand" "1")]
13215 (set (match_operand:XF 1 "register_operand" "=u")
13216 (unspec:XF [(match_dup 2) (match_dup 3)]
13218 (set (reg:CCFP FPSR_REG)
13219 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13221 "TARGET_USE_FANCY_MATH_387"
13223 [(set_attr "type" "fpspc")
13224 (set_attr "mode" "XF")])
13226 (define_expand "fmodxf3"
13227 [(use (match_operand:XF 0 "register_operand" ""))
13228 (use (match_operand:XF 1 "general_operand" ""))
13229 (use (match_operand:XF 2 "general_operand" ""))]
13230 "TARGET_USE_FANCY_MATH_387"
13232 rtx label = gen_label_rtx ();
13234 rtx op1 = gen_reg_rtx (XFmode);
13235 rtx op2 = gen_reg_rtx (XFmode);
13237 emit_move_insn (op2, operands[2]);
13238 emit_move_insn (op1, operands[1]);
13240 emit_label (label);
13241 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13242 ix86_emit_fp_unordered_jump (label);
13243 LABEL_NUSES (label) = 1;
13245 emit_move_insn (operands[0], op1);
13249 (define_expand "fmod<mode>3"
13250 [(use (match_operand:MODEF 0 "register_operand" ""))
13251 (use (match_operand:MODEF 1 "general_operand" ""))
13252 (use (match_operand:MODEF 2 "general_operand" ""))]
13253 "TARGET_USE_FANCY_MATH_387"
13255 rtx (*gen_truncxf) (rtx, rtx);
13257 rtx label = gen_label_rtx ();
13259 rtx op1 = gen_reg_rtx (XFmode);
13260 rtx op2 = gen_reg_rtx (XFmode);
13262 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13263 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13265 emit_label (label);
13266 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13267 ix86_emit_fp_unordered_jump (label);
13268 LABEL_NUSES (label) = 1;
13270 /* Truncate the result properly for strict SSE math. */
13271 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13272 && !TARGET_MIX_SSE_I387)
13273 gen_truncxf = gen_truncxf<mode>2;
13275 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13277 emit_insn (gen_truncxf (operands[0], op1));
13281 (define_insn "fprem1xf4_i387"
13282 [(set (match_operand:XF 0 "register_operand" "=f")
13283 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13284 (match_operand:XF 3 "register_operand" "1")]
13286 (set (match_operand:XF 1 "register_operand" "=u")
13287 (unspec:XF [(match_dup 2) (match_dup 3)]
13289 (set (reg:CCFP FPSR_REG)
13290 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13292 "TARGET_USE_FANCY_MATH_387"
13294 [(set_attr "type" "fpspc")
13295 (set_attr "mode" "XF")])
13297 (define_expand "remainderxf3"
13298 [(use (match_operand:XF 0 "register_operand" ""))
13299 (use (match_operand:XF 1 "general_operand" ""))
13300 (use (match_operand:XF 2 "general_operand" ""))]
13301 "TARGET_USE_FANCY_MATH_387"
13303 rtx label = gen_label_rtx ();
13305 rtx op1 = gen_reg_rtx (XFmode);
13306 rtx op2 = gen_reg_rtx (XFmode);
13308 emit_move_insn (op2, operands[2]);
13309 emit_move_insn (op1, operands[1]);
13311 emit_label (label);
13312 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13313 ix86_emit_fp_unordered_jump (label);
13314 LABEL_NUSES (label) = 1;
13316 emit_move_insn (operands[0], op1);
13320 (define_expand "remainder<mode>3"
13321 [(use (match_operand:MODEF 0 "register_operand" ""))
13322 (use (match_operand:MODEF 1 "general_operand" ""))
13323 (use (match_operand:MODEF 2 "general_operand" ""))]
13324 "TARGET_USE_FANCY_MATH_387"
13326 rtx (*gen_truncxf) (rtx, rtx);
13328 rtx label = gen_label_rtx ();
13330 rtx op1 = gen_reg_rtx (XFmode);
13331 rtx op2 = gen_reg_rtx (XFmode);
13333 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13334 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13336 emit_label (label);
13338 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13339 ix86_emit_fp_unordered_jump (label);
13340 LABEL_NUSES (label) = 1;
13342 /* Truncate the result properly for strict SSE math. */
13343 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13344 && !TARGET_MIX_SSE_I387)
13345 gen_truncxf = gen_truncxf<mode>2;
13347 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13349 emit_insn (gen_truncxf (operands[0], op1));
13353 (define_insn "*sinxf2_i387"
13354 [(set (match_operand:XF 0 "register_operand" "=f")
13355 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13356 "TARGET_USE_FANCY_MATH_387
13357 && flag_unsafe_math_optimizations"
13359 [(set_attr "type" "fpspc")
13360 (set_attr "mode" "XF")])
13362 (define_insn "*sin_extend<mode>xf2_i387"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (unspec:XF [(float_extend:XF
13365 (match_operand:MODEF 1 "register_operand" "0"))]
13367 "TARGET_USE_FANCY_MATH_387
13368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13369 || TARGET_MIX_SSE_I387)
13370 && flag_unsafe_math_optimizations"
13372 [(set_attr "type" "fpspc")
13373 (set_attr "mode" "XF")])
13375 (define_insn "*cosxf2_i387"
13376 [(set (match_operand:XF 0 "register_operand" "=f")
13377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13378 "TARGET_USE_FANCY_MATH_387
13379 && flag_unsafe_math_optimizations"
13381 [(set_attr "type" "fpspc")
13382 (set_attr "mode" "XF")])
13384 (define_insn "*cos_extend<mode>xf2_i387"
13385 [(set (match_operand:XF 0 "register_operand" "=f")
13386 (unspec:XF [(float_extend:XF
13387 (match_operand:MODEF 1 "register_operand" "0"))]
13389 "TARGET_USE_FANCY_MATH_387
13390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13391 || TARGET_MIX_SSE_I387)
13392 && flag_unsafe_math_optimizations"
13394 [(set_attr "type" "fpspc")
13395 (set_attr "mode" "XF")])
13397 ;; When sincos pattern is defined, sin and cos builtin functions will be
13398 ;; expanded to sincos pattern with one of its outputs left unused.
13399 ;; CSE pass will figure out if two sincos patterns can be combined,
13400 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13401 ;; depending on the unused output.
13403 (define_insn "sincosxf3"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13406 UNSPEC_SINCOS_COS))
13407 (set (match_operand:XF 1 "register_operand" "=u")
13408 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13409 "TARGET_USE_FANCY_MATH_387
13410 && flag_unsafe_math_optimizations"
13412 [(set_attr "type" "fpspc")
13413 (set_attr "mode" "XF")])
13416 [(set (match_operand:XF 0 "register_operand" "")
13417 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13418 UNSPEC_SINCOS_COS))
13419 (set (match_operand:XF 1 "register_operand" "")
13420 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13421 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13422 && can_create_pseudo_p ()"
13423 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13426 [(set (match_operand:XF 0 "register_operand" "")
13427 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13428 UNSPEC_SINCOS_COS))
13429 (set (match_operand:XF 1 "register_operand" "")
13430 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13431 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13432 && can_create_pseudo_p ()"
13433 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13435 (define_insn "sincos_extend<mode>xf3_i387"
13436 [(set (match_operand:XF 0 "register_operand" "=f")
13437 (unspec:XF [(float_extend:XF
13438 (match_operand:MODEF 2 "register_operand" "0"))]
13439 UNSPEC_SINCOS_COS))
13440 (set (match_operand:XF 1 "register_operand" "=u")
13441 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13442 "TARGET_USE_FANCY_MATH_387
13443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13444 || TARGET_MIX_SSE_I387)
13445 && flag_unsafe_math_optimizations"
13447 [(set_attr "type" "fpspc")
13448 (set_attr "mode" "XF")])
13451 [(set (match_operand:XF 0 "register_operand" "")
13452 (unspec:XF [(float_extend:XF
13453 (match_operand:MODEF 2 "register_operand" ""))]
13454 UNSPEC_SINCOS_COS))
13455 (set (match_operand:XF 1 "register_operand" "")
13456 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13457 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13458 && can_create_pseudo_p ()"
13459 [(set (match_dup 1)
13460 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13463 [(set (match_operand:XF 0 "register_operand" "")
13464 (unspec:XF [(float_extend:XF
13465 (match_operand:MODEF 2 "register_operand" ""))]
13466 UNSPEC_SINCOS_COS))
13467 (set (match_operand:XF 1 "register_operand" "")
13468 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13469 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13470 && can_create_pseudo_p ()"
13471 [(set (match_dup 0)
13472 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13474 (define_expand "sincos<mode>3"
13475 [(use (match_operand:MODEF 0 "register_operand" ""))
13476 (use (match_operand:MODEF 1 "register_operand" ""))
13477 (use (match_operand:MODEF 2 "register_operand" ""))]
13478 "TARGET_USE_FANCY_MATH_387
13479 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13480 || TARGET_MIX_SSE_I387)
13481 && flag_unsafe_math_optimizations"
13483 rtx op0 = gen_reg_rtx (XFmode);
13484 rtx op1 = gen_reg_rtx (XFmode);
13486 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13488 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13492 (define_insn "fptanxf4_i387"
13493 [(set (match_operand:XF 0 "register_operand" "=f")
13494 (match_operand:XF 3 "const_double_operand" "F"))
13495 (set (match_operand:XF 1 "register_operand" "=u")
13496 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13498 "TARGET_USE_FANCY_MATH_387
13499 && flag_unsafe_math_optimizations
13500 && standard_80387_constant_p (operands[3]) == 2"
13502 [(set_attr "type" "fpspc")
13503 (set_attr "mode" "XF")])
13505 (define_insn "fptan_extend<mode>xf4_i387"
13506 [(set (match_operand:MODEF 0 "register_operand" "=f")
13507 (match_operand:MODEF 3 "const_double_operand" "F"))
13508 (set (match_operand:XF 1 "register_operand" "=u")
13509 (unspec:XF [(float_extend:XF
13510 (match_operand:MODEF 2 "register_operand" "0"))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
13515 && flag_unsafe_math_optimizations
13516 && standard_80387_constant_p (operands[3]) == 2"
13518 [(set_attr "type" "fpspc")
13519 (set_attr "mode" "XF")])
13521 (define_expand "tanxf2"
13522 [(use (match_operand:XF 0 "register_operand" ""))
13523 (use (match_operand:XF 1 "register_operand" ""))]
13524 "TARGET_USE_FANCY_MATH_387
13525 && flag_unsafe_math_optimizations"
13527 rtx one = gen_reg_rtx (XFmode);
13528 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13530 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13534 (define_expand "tan<mode>2"
13535 [(use (match_operand:MODEF 0 "register_operand" ""))
13536 (use (match_operand:MODEF 1 "register_operand" ""))]
13537 "TARGET_USE_FANCY_MATH_387
13538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13539 || TARGET_MIX_SSE_I387)
13540 && flag_unsafe_math_optimizations"
13542 rtx op0 = gen_reg_rtx (XFmode);
13544 rtx one = gen_reg_rtx (<MODE>mode);
13545 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13547 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13548 operands[1], op2));
13549 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13553 (define_insn "*fpatanxf3_i387"
13554 [(set (match_operand:XF 0 "register_operand" "=f")
13555 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13556 (match_operand:XF 2 "register_operand" "u")]
13558 (clobber (match_scratch:XF 3 "=2"))]
13559 "TARGET_USE_FANCY_MATH_387
13560 && flag_unsafe_math_optimizations"
13562 [(set_attr "type" "fpspc")
13563 (set_attr "mode" "XF")])
13565 (define_insn "fpatan_extend<mode>xf3_i387"
13566 [(set (match_operand:XF 0 "register_operand" "=f")
13567 (unspec:XF [(float_extend:XF
13568 (match_operand:MODEF 1 "register_operand" "0"))
13570 (match_operand:MODEF 2 "register_operand" "u"))]
13572 (clobber (match_scratch:XF 3 "=2"))]
13573 "TARGET_USE_FANCY_MATH_387
13574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13575 || TARGET_MIX_SSE_I387)
13576 && flag_unsafe_math_optimizations"
13578 [(set_attr "type" "fpspc")
13579 (set_attr "mode" "XF")])
13581 (define_expand "atan2xf3"
13582 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13583 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13584 (match_operand:XF 1 "register_operand" "")]
13586 (clobber (match_scratch:XF 3 ""))])]
13587 "TARGET_USE_FANCY_MATH_387
13588 && flag_unsafe_math_optimizations")
13590 (define_expand "atan2<mode>3"
13591 [(use (match_operand:MODEF 0 "register_operand" ""))
13592 (use (match_operand:MODEF 1 "register_operand" ""))
13593 (use (match_operand:MODEF 2 "register_operand" ""))]
13594 "TARGET_USE_FANCY_MATH_387
13595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13596 || TARGET_MIX_SSE_I387)
13597 && flag_unsafe_math_optimizations"
13599 rtx op0 = gen_reg_rtx (XFmode);
13601 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13606 (define_expand "atanxf2"
13607 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13608 (unspec:XF [(match_dup 2)
13609 (match_operand:XF 1 "register_operand" "")]
13611 (clobber (match_scratch:XF 3 ""))])]
13612 "TARGET_USE_FANCY_MATH_387
13613 && flag_unsafe_math_optimizations"
13615 operands[2] = gen_reg_rtx (XFmode);
13616 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13619 (define_expand "atan<mode>2"
13620 [(use (match_operand:MODEF 0 "register_operand" ""))
13621 (use (match_operand:MODEF 1 "register_operand" ""))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13624 || TARGET_MIX_SSE_I387)
13625 && flag_unsafe_math_optimizations"
13627 rtx op0 = gen_reg_rtx (XFmode);
13629 rtx op2 = gen_reg_rtx (<MODE>mode);
13630 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13632 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13633 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13637 (define_expand "asinxf2"
13638 [(set (match_dup 2)
13639 (mult:XF (match_operand:XF 1 "register_operand" "")
13641 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13642 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13643 (parallel [(set (match_operand:XF 0 "register_operand" "")
13644 (unspec:XF [(match_dup 5) (match_dup 1)]
13646 (clobber (match_scratch:XF 6 ""))])]
13647 "TARGET_USE_FANCY_MATH_387
13648 && flag_unsafe_math_optimizations"
13652 if (optimize_insn_for_size_p ())
13655 for (i = 2; i < 6; i++)
13656 operands[i] = gen_reg_rtx (XFmode);
13658 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13661 (define_expand "asin<mode>2"
13662 [(use (match_operand:MODEF 0 "register_operand" ""))
13663 (use (match_operand:MODEF 1 "general_operand" ""))]
13664 "TARGET_USE_FANCY_MATH_387
13665 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13666 || TARGET_MIX_SSE_I387)
13667 && flag_unsafe_math_optimizations"
13669 rtx op0 = gen_reg_rtx (XFmode);
13670 rtx op1 = gen_reg_rtx (XFmode);
13672 if (optimize_insn_for_size_p ())
13675 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13676 emit_insn (gen_asinxf2 (op0, op1));
13677 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13681 (define_expand "acosxf2"
13682 [(set (match_dup 2)
13683 (mult:XF (match_operand:XF 1 "register_operand" "")
13685 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13686 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13687 (parallel [(set (match_operand:XF 0 "register_operand" "")
13688 (unspec:XF [(match_dup 1) (match_dup 5)]
13690 (clobber (match_scratch:XF 6 ""))])]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations"
13696 if (optimize_insn_for_size_p ())
13699 for (i = 2; i < 6; i++)
13700 operands[i] = gen_reg_rtx (XFmode);
13702 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13705 (define_expand "acos<mode>2"
13706 [(use (match_operand:MODEF 0 "register_operand" ""))
13707 (use (match_operand:MODEF 1 "general_operand" ""))]
13708 "TARGET_USE_FANCY_MATH_387
13709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13710 || TARGET_MIX_SSE_I387)
13711 && flag_unsafe_math_optimizations"
13713 rtx op0 = gen_reg_rtx (XFmode);
13714 rtx op1 = gen_reg_rtx (XFmode);
13716 if (optimize_insn_for_size_p ())
13719 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13720 emit_insn (gen_acosxf2 (op0, op1));
13721 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13725 (define_insn "fyl2xxf3_i387"
13726 [(set (match_operand:XF 0 "register_operand" "=f")
13727 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13728 (match_operand:XF 2 "register_operand" "u")]
13730 (clobber (match_scratch:XF 3 "=2"))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && flag_unsafe_math_optimizations"
13734 [(set_attr "type" "fpspc")
13735 (set_attr "mode" "XF")])
13737 (define_insn "fyl2x_extend<mode>xf3_i387"
13738 [(set (match_operand:XF 0 "register_operand" "=f")
13739 (unspec:XF [(float_extend:XF
13740 (match_operand:MODEF 1 "register_operand" "0"))
13741 (match_operand:XF 2 "register_operand" "u")]
13743 (clobber (match_scratch:XF 3 "=2"))]
13744 "TARGET_USE_FANCY_MATH_387
13745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13746 || TARGET_MIX_SSE_I387)
13747 && flag_unsafe_math_optimizations"
13749 [(set_attr "type" "fpspc")
13750 (set_attr "mode" "XF")])
13752 (define_expand "logxf2"
13753 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13754 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13755 (match_dup 2)] UNSPEC_FYL2X))
13756 (clobber (match_scratch:XF 3 ""))])]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations"
13760 operands[2] = gen_reg_rtx (XFmode);
13761 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13764 (define_expand "log<mode>2"
13765 [(use (match_operand:MODEF 0 "register_operand" ""))
13766 (use (match_operand:MODEF 1 "register_operand" ""))]
13767 "TARGET_USE_FANCY_MATH_387
13768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13769 || TARGET_MIX_SSE_I387)
13770 && flag_unsafe_math_optimizations"
13772 rtx op0 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13775 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13777 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13778 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13782 (define_expand "log10xf2"
13783 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13784 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13785 (match_dup 2)] UNSPEC_FYL2X))
13786 (clobber (match_scratch:XF 3 ""))])]
13787 "TARGET_USE_FANCY_MATH_387
13788 && flag_unsafe_math_optimizations"
13790 operands[2] = gen_reg_rtx (XFmode);
13791 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13794 (define_expand "log10<mode>2"
13795 [(use (match_operand:MODEF 0 "register_operand" ""))
13796 (use (match_operand:MODEF 1 "register_operand" ""))]
13797 "TARGET_USE_FANCY_MATH_387
13798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13799 || TARGET_MIX_SSE_I387)
13800 && flag_unsafe_math_optimizations"
13802 rtx op0 = gen_reg_rtx (XFmode);
13804 rtx op2 = gen_reg_rtx (XFmode);
13805 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13807 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13812 (define_expand "log2xf2"
13813 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13814 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13815 (match_dup 2)] UNSPEC_FYL2X))
13816 (clobber (match_scratch:XF 3 ""))])]
13817 "TARGET_USE_FANCY_MATH_387
13818 && flag_unsafe_math_optimizations"
13820 operands[2] = gen_reg_rtx (XFmode);
13821 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13824 (define_expand "log2<mode>2"
13825 [(use (match_operand:MODEF 0 "register_operand" ""))
13826 (use (match_operand:MODEF 1 "register_operand" ""))]
13827 "TARGET_USE_FANCY_MATH_387
13828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13829 || TARGET_MIX_SSE_I387)
13830 && flag_unsafe_math_optimizations"
13832 rtx op0 = gen_reg_rtx (XFmode);
13834 rtx op2 = gen_reg_rtx (XFmode);
13835 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13837 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13842 (define_insn "fyl2xp1xf3_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f")
13844 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13845 (match_operand:XF 2 "register_operand" "u")]
13847 (clobber (match_scratch:XF 3 "=2"))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations"
13851 [(set_attr "type" "fpspc")
13852 (set_attr "mode" "XF")])
13854 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13855 [(set (match_operand:XF 0 "register_operand" "=f")
13856 (unspec:XF [(float_extend:XF
13857 (match_operand:MODEF 1 "register_operand" "0"))
13858 (match_operand:XF 2 "register_operand" "u")]
13860 (clobber (match_scratch:XF 3 "=2"))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863 || TARGET_MIX_SSE_I387)
13864 && flag_unsafe_math_optimizations"
13866 [(set_attr "type" "fpspc")
13867 (set_attr "mode" "XF")])
13869 (define_expand "log1pxf2"
13870 [(use (match_operand:XF 0 "register_operand" ""))
13871 (use (match_operand:XF 1 "register_operand" ""))]
13872 "TARGET_USE_FANCY_MATH_387
13873 && flag_unsafe_math_optimizations"
13875 if (optimize_insn_for_size_p ())
13878 ix86_emit_i387_log1p (operands[0], operands[1]);
13882 (define_expand "log1p<mode>2"
13883 [(use (match_operand:MODEF 0 "register_operand" ""))
13884 (use (match_operand:MODEF 1 "register_operand" ""))]
13885 "TARGET_USE_FANCY_MATH_387
13886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13887 || TARGET_MIX_SSE_I387)
13888 && flag_unsafe_math_optimizations"
13892 if (optimize_insn_for_size_p ())
13895 op0 = gen_reg_rtx (XFmode);
13897 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13899 ix86_emit_i387_log1p (op0, operands[1]);
13900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13904 (define_insn "fxtractxf3_i387"
13905 [(set (match_operand:XF 0 "register_operand" "=f")
13906 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13907 UNSPEC_XTRACT_FRACT))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13916 (define_insn "fxtract_extend<mode>xf3_i387"
13917 [(set (match_operand:XF 0 "register_operand" "=f")
13918 (unspec:XF [(float_extend:XF
13919 (match_operand:MODEF 2 "register_operand" "0"))]
13920 UNSPEC_XTRACT_FRACT))
13921 (set (match_operand:XF 1 "register_operand" "=u")
13922 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13928 [(set_attr "type" "fpspc")
13929 (set_attr "mode" "XF")])
13931 (define_expand "logbxf2"
13932 [(parallel [(set (match_dup 2)
13933 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13934 UNSPEC_XTRACT_FRACT))
13935 (set (match_operand:XF 0 "register_operand" "")
13936 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13939 "operands[2] = gen_reg_rtx (XFmode);")
13941 (define_expand "logb<mode>2"
13942 [(use (match_operand:MODEF 0 "register_operand" ""))
13943 (use (match_operand:MODEF 1 "register_operand" ""))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13949 rtx op0 = gen_reg_rtx (XFmode);
13950 rtx op1 = gen_reg_rtx (XFmode);
13952 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13953 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13957 (define_expand "ilogbxf2"
13958 [(use (match_operand:SI 0 "register_operand" ""))
13959 (use (match_operand:XF 1 "register_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && flag_unsafe_math_optimizations"
13965 if (optimize_insn_for_size_p ())
13968 op0 = gen_reg_rtx (XFmode);
13969 op1 = gen_reg_rtx (XFmode);
13971 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13972 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13976 (define_expand "ilogb<mode>2"
13977 [(use (match_operand:SI 0 "register_operand" ""))
13978 (use (match_operand:MODEF 1 "register_operand" ""))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13986 if (optimize_insn_for_size_p ())
13989 op0 = gen_reg_rtx (XFmode);
13990 op1 = gen_reg_rtx (XFmode);
13992 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13993 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13997 (define_insn "*f2xm1xf2_i387"
13998 [(set (match_operand:XF 0 "register_operand" "=f")
13999 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations"
14004 [(set_attr "type" "fpspc")
14005 (set_attr "mode" "XF")])
14007 (define_insn "*fscalexf4_i387"
14008 [(set (match_operand:XF 0 "register_operand" "=f")
14009 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14010 (match_operand:XF 3 "register_operand" "1")]
14011 UNSPEC_FSCALE_FRACT))
14012 (set (match_operand:XF 1 "register_operand" "=u")
14013 (unspec:XF [(match_dup 2) (match_dup 3)]
14014 UNSPEC_FSCALE_EXP))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14018 [(set_attr "type" "fpspc")
14019 (set_attr "mode" "XF")])
14021 (define_expand "expNcorexf3"
14022 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14023 (match_operand:XF 2 "register_operand" "")))
14024 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14025 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14026 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14027 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14028 (parallel [(set (match_operand:XF 0 "register_operand" "")
14029 (unspec:XF [(match_dup 8) (match_dup 4)]
14030 UNSPEC_FSCALE_FRACT))
14032 (unspec:XF [(match_dup 8) (match_dup 4)]
14033 UNSPEC_FSCALE_EXP))])]
14034 "TARGET_USE_FANCY_MATH_387
14035 && flag_unsafe_math_optimizations"
14039 if (optimize_insn_for_size_p ())
14042 for (i = 3; i < 10; i++)
14043 operands[i] = gen_reg_rtx (XFmode);
14045 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14048 (define_expand "expxf2"
14049 [(use (match_operand:XF 0 "register_operand" ""))
14050 (use (match_operand:XF 1 "register_operand" ""))]
14051 "TARGET_USE_FANCY_MATH_387
14052 && flag_unsafe_math_optimizations"
14056 if (optimize_insn_for_size_p ())
14059 op2 = gen_reg_rtx (XFmode);
14060 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14062 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14066 (define_expand "exp<mode>2"
14067 [(use (match_operand:MODEF 0 "register_operand" ""))
14068 (use (match_operand:MODEF 1 "general_operand" ""))]
14069 "TARGET_USE_FANCY_MATH_387
14070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14071 || TARGET_MIX_SSE_I387)
14072 && flag_unsafe_math_optimizations"
14076 if (optimize_insn_for_size_p ())
14079 op0 = gen_reg_rtx (XFmode);
14080 op1 = gen_reg_rtx (XFmode);
14082 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14083 emit_insn (gen_expxf2 (op0, op1));
14084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14088 (define_expand "exp10xf2"
14089 [(use (match_operand:XF 0 "register_operand" ""))
14090 (use (match_operand:XF 1 "register_operand" ""))]
14091 "TARGET_USE_FANCY_MATH_387
14092 && flag_unsafe_math_optimizations"
14096 if (optimize_insn_for_size_p ())
14099 op2 = gen_reg_rtx (XFmode);
14100 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14102 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14106 (define_expand "exp10<mode>2"
14107 [(use (match_operand:MODEF 0 "register_operand" ""))
14108 (use (match_operand:MODEF 1 "general_operand" ""))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111 || TARGET_MIX_SSE_I387)
14112 && flag_unsafe_math_optimizations"
14116 if (optimize_insn_for_size_p ())
14119 op0 = gen_reg_rtx (XFmode);
14120 op1 = gen_reg_rtx (XFmode);
14122 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14123 emit_insn (gen_exp10xf2 (op0, op1));
14124 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14128 (define_expand "exp2xf2"
14129 [(use (match_operand:XF 0 "register_operand" ""))
14130 (use (match_operand:XF 1 "register_operand" ""))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_unsafe_math_optimizations"
14136 if (optimize_insn_for_size_p ())
14139 op2 = gen_reg_rtx (XFmode);
14140 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14142 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14146 (define_expand "exp2<mode>2"
14147 [(use (match_operand:MODEF 0 "register_operand" ""))
14148 (use (match_operand:MODEF 1 "general_operand" ""))]
14149 "TARGET_USE_FANCY_MATH_387
14150 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14151 || TARGET_MIX_SSE_I387)
14152 && flag_unsafe_math_optimizations"
14156 if (optimize_insn_for_size_p ())
14159 op0 = gen_reg_rtx (XFmode);
14160 op1 = gen_reg_rtx (XFmode);
14162 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14163 emit_insn (gen_exp2xf2 (op0, op1));
14164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14168 (define_expand "expm1xf2"
14169 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14171 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14172 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14173 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14174 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14175 (parallel [(set (match_dup 7)
14176 (unspec:XF [(match_dup 6) (match_dup 4)]
14177 UNSPEC_FSCALE_FRACT))
14179 (unspec:XF [(match_dup 6) (match_dup 4)]
14180 UNSPEC_FSCALE_EXP))])
14181 (parallel [(set (match_dup 10)
14182 (unspec:XF [(match_dup 9) (match_dup 8)]
14183 UNSPEC_FSCALE_FRACT))
14184 (set (match_dup 11)
14185 (unspec:XF [(match_dup 9) (match_dup 8)]
14186 UNSPEC_FSCALE_EXP))])
14187 (set (match_dup 12) (minus:XF (match_dup 10)
14188 (float_extend:XF (match_dup 13))))
14189 (set (match_operand:XF 0 "register_operand" "")
14190 (plus:XF (match_dup 12) (match_dup 7)))]
14191 "TARGET_USE_FANCY_MATH_387
14192 && flag_unsafe_math_optimizations"
14196 if (optimize_insn_for_size_p ())
14199 for (i = 2; i < 13; i++)
14200 operands[i] = gen_reg_rtx (XFmode);
14203 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14205 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14208 (define_expand "expm1<mode>2"
14209 [(use (match_operand:MODEF 0 "register_operand" ""))
14210 (use (match_operand:MODEF 1 "general_operand" ""))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14218 if (optimize_insn_for_size_p ())
14221 op0 = gen_reg_rtx (XFmode);
14222 op1 = gen_reg_rtx (XFmode);
14224 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14225 emit_insn (gen_expm1xf2 (op0, op1));
14226 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14230 (define_expand "ldexpxf3"
14231 [(set (match_dup 3)
14232 (float:XF (match_operand:SI 2 "register_operand" "")))
14233 (parallel [(set (match_operand:XF 0 " register_operand" "")
14234 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14236 UNSPEC_FSCALE_FRACT))
14238 (unspec:XF [(match_dup 1) (match_dup 3)]
14239 UNSPEC_FSCALE_EXP))])]
14240 "TARGET_USE_FANCY_MATH_387
14241 && flag_unsafe_math_optimizations"
14243 if (optimize_insn_for_size_p ())
14246 operands[3] = gen_reg_rtx (XFmode);
14247 operands[4] = gen_reg_rtx (XFmode);
14250 (define_expand "ldexp<mode>3"
14251 [(use (match_operand:MODEF 0 "register_operand" ""))
14252 (use (match_operand:MODEF 1 "general_operand" ""))
14253 (use (match_operand:SI 2 "register_operand" ""))]
14254 "TARGET_USE_FANCY_MATH_387
14255 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14256 || TARGET_MIX_SSE_I387)
14257 && flag_unsafe_math_optimizations"
14261 if (optimize_insn_for_size_p ())
14264 op0 = gen_reg_rtx (XFmode);
14265 op1 = gen_reg_rtx (XFmode);
14267 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14268 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14269 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14273 (define_expand "scalbxf3"
14274 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14275 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14276 (match_operand:XF 2 "register_operand" "")]
14277 UNSPEC_FSCALE_FRACT))
14279 (unspec:XF [(match_dup 1) (match_dup 2)]
14280 UNSPEC_FSCALE_EXP))])]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14284 if (optimize_insn_for_size_p ())
14287 operands[3] = gen_reg_rtx (XFmode);
14290 (define_expand "scalb<mode>3"
14291 [(use (match_operand:MODEF 0 "register_operand" ""))
14292 (use (match_operand:MODEF 1 "general_operand" ""))
14293 (use (match_operand:MODEF 2 "general_operand" ""))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14301 if (optimize_insn_for_size_p ())
14304 op0 = gen_reg_rtx (XFmode);
14305 op1 = gen_reg_rtx (XFmode);
14306 op2 = gen_reg_rtx (XFmode);
14308 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14309 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14310 emit_insn (gen_scalbxf3 (op0, op1, op2));
14311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14315 (define_expand "significandxf2"
14316 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14317 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14318 UNSPEC_XTRACT_FRACT))
14320 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14321 "TARGET_USE_FANCY_MATH_387
14322 && flag_unsafe_math_optimizations"
14323 "operands[2] = gen_reg_rtx (XFmode);")
14325 (define_expand "significand<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand" ""))
14327 (use (match_operand:MODEF 1 "register_operand" ""))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14333 rtx op0 = gen_reg_rtx (XFmode);
14334 rtx op1 = gen_reg_rtx (XFmode);
14336 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342 (define_insn "sse4_1_round<mode>2"
14343 [(set (match_operand:MODEF 0 "register_operand" "=x")
14344 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14345 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14348 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14349 [(set_attr "type" "ssecvt")
14350 (set_attr "prefix_extra" "1")
14351 (set_attr "prefix" "maybe_vex")
14352 (set_attr "mode" "<MODE>")])
14354 (define_insn "rintxf2"
14355 [(set (match_operand:XF 0 "register_operand" "=f")
14356 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14358 "TARGET_USE_FANCY_MATH_387
14359 && flag_unsafe_math_optimizations"
14361 [(set_attr "type" "fpspc")
14362 (set_attr "mode" "XF")])
14364 (define_expand "rint<mode>2"
14365 [(use (match_operand:MODEF 0 "register_operand" ""))
14366 (use (match_operand:MODEF 1 "register_operand" ""))]
14367 "(TARGET_USE_FANCY_MATH_387
14368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369 || TARGET_MIX_SSE_I387)
14370 && flag_unsafe_math_optimizations)
14371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14372 && !flag_trapping_math)"
14374 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14375 && !flag_trapping_math)
14377 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14380 emit_insn (gen_sse4_1_round<mode>2
14381 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14383 ix86_expand_rint (operand0, operand1);
14387 rtx op0 = gen_reg_rtx (XFmode);
14388 rtx op1 = gen_reg_rtx (XFmode);
14390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14391 emit_insn (gen_rintxf2 (op0, op1));
14393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14398 (define_expand "round<mode>2"
14399 [(match_operand:X87MODEF 0 "register_operand" "")
14400 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14401 "(TARGET_USE_FANCY_MATH_387
14402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403 || TARGET_MIX_SSE_I387)
14404 && flag_unsafe_math_optimizations)
14405 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14406 && !flag_trapping_math && !flag_rounding_math)"
14408 if (optimize_insn_for_size_p ())
14411 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14412 && !flag_trapping_math && !flag_rounding_math)
14414 if (TARGET_64BIT || (<MODE>mode != DFmode))
14415 ix86_expand_round (operands[0], operands[1]);
14417 ix86_expand_rounddf_32 (operands[0], operands[1]);
14421 operands[1] = force_reg (<MODE>mode, operands[1]);
14422 ix86_emit_i387_round (operands[0], operands[1]);
14427 (define_insn_and_split "*fistdi2_1"
14428 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14429 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14431 "TARGET_USE_FANCY_MATH_387
14432 && can_create_pseudo_p ()"
14437 if (memory_operand (operands[0], VOIDmode))
14438 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14441 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14442 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14447 [(set_attr "type" "fpspc")
14448 (set_attr "mode" "DI")])
14450 (define_insn "fistdi2"
14451 [(set (match_operand:DI 0 "memory_operand" "=m")
14452 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14454 (clobber (match_scratch:XF 2 "=&1f"))]
14455 "TARGET_USE_FANCY_MATH_387"
14456 "* return output_fix_trunc (insn, operands, false);"
14457 [(set_attr "type" "fpspc")
14458 (set_attr "mode" "DI")])
14460 (define_insn "fistdi2_with_temp"
14461 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14462 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14464 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14465 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14466 "TARGET_USE_FANCY_MATH_387"
14468 [(set_attr "type" "fpspc")
14469 (set_attr "mode" "DI")])
14472 [(set (match_operand:DI 0 "register_operand" "")
14473 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14475 (clobber (match_operand:DI 2 "memory_operand" ""))
14476 (clobber (match_scratch 3 ""))]
14478 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14479 (clobber (match_dup 3))])
14480 (set (match_dup 0) (match_dup 2))])
14483 [(set (match_operand:DI 0 "memory_operand" "")
14484 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14486 (clobber (match_operand:DI 2 "memory_operand" ""))
14487 (clobber (match_scratch 3 ""))]
14489 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14490 (clobber (match_dup 3))])])
14492 (define_insn_and_split "*fist<mode>2_1"
14493 [(set (match_operand:SWI24 0 "register_operand" "")
14494 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14496 "TARGET_USE_FANCY_MATH_387
14497 && can_create_pseudo_p ()"
14502 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14503 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14507 [(set_attr "type" "fpspc")
14508 (set_attr "mode" "<MODE>")])
14510 (define_insn "fist<mode>2"
14511 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14512 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14514 "TARGET_USE_FANCY_MATH_387"
14515 "* return output_fix_trunc (insn, operands, false);"
14516 [(set_attr "type" "fpspc")
14517 (set_attr "mode" "<MODE>")])
14519 (define_insn "fist<mode>2_with_temp"
14520 [(set (match_operand:SWI24 0 "register_operand" "=r")
14521 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14523 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14524 "TARGET_USE_FANCY_MATH_387"
14526 [(set_attr "type" "fpspc")
14527 (set_attr "mode" "<MODE>")])
14530 [(set (match_operand:SWI24 0 "register_operand" "")
14531 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14533 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14535 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14536 (set (match_dup 0) (match_dup 2))])
14539 [(set (match_operand:SWI24 0 "memory_operand" "")
14540 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14542 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14544 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14546 (define_expand "lrintxf<mode>2"
14547 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14548 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14550 "TARGET_USE_FANCY_MATH_387")
14552 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14553 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14554 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14555 UNSPEC_FIX_NOTRUNC))]
14556 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14557 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14559 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14560 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14561 (match_operand:X87MODEF 1 "register_operand" "")]
14562 "(TARGET_USE_FANCY_MATH_387
14563 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14564 || TARGET_MIX_SSE_I387)
14565 && flag_unsafe_math_optimizations)
14566 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14567 && <SWI248x:MODE>mode != HImode
14568 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14569 && !flag_trapping_math && !flag_rounding_math)"
14571 if (optimize_insn_for_size_p ())
14574 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14575 && <SWI248x:MODE>mode != HImode
14576 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14577 && !flag_trapping_math && !flag_rounding_math)
14578 ix86_expand_lround (operand0, operand1);
14580 ix86_emit_i387_round (operands[0], operands[1]);
14584 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14585 (define_insn_and_split "frndintxf2_floor"
14586 [(set (match_operand:XF 0 "register_operand" "")
14587 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14588 UNSPEC_FRNDINT_FLOOR))
14589 (clobber (reg:CC FLAGS_REG))]
14590 "TARGET_USE_FANCY_MATH_387
14591 && flag_unsafe_math_optimizations
14592 && can_create_pseudo_p ()"
14597 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14599 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14600 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14602 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14603 operands[2], operands[3]));
14606 [(set_attr "type" "frndint")
14607 (set_attr "i387_cw" "floor")
14608 (set_attr "mode" "XF")])
14610 (define_insn "frndintxf2_floor_i387"
14611 [(set (match_operand:XF 0 "register_operand" "=f")
14612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14613 UNSPEC_FRNDINT_FLOOR))
14614 (use (match_operand:HI 2 "memory_operand" "m"))
14615 (use (match_operand:HI 3 "memory_operand" "m"))]
14616 "TARGET_USE_FANCY_MATH_387
14617 && flag_unsafe_math_optimizations"
14618 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14619 [(set_attr "type" "frndint")
14620 (set_attr "i387_cw" "floor")
14621 (set_attr "mode" "XF")])
14623 (define_expand "floorxf2"
14624 [(use (match_operand:XF 0 "register_operand" ""))
14625 (use (match_operand:XF 1 "register_operand" ""))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && flag_unsafe_math_optimizations"
14629 if (optimize_insn_for_size_p ())
14631 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14635 (define_expand "floor<mode>2"
14636 [(use (match_operand:MODEF 0 "register_operand" ""))
14637 (use (match_operand:MODEF 1 "register_operand" ""))]
14638 "(TARGET_USE_FANCY_MATH_387
14639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14640 || TARGET_MIX_SSE_I387)
14641 && flag_unsafe_math_optimizations)
14642 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14643 && !flag_trapping_math)"
14645 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14646 && !flag_trapping_math
14647 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14649 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14652 emit_insn (gen_sse4_1_round<mode>2
14653 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14654 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14655 ix86_expand_floorceil (operand0, operand1, true);
14657 ix86_expand_floorceildf_32 (operand0, operand1, true);
14663 if (optimize_insn_for_size_p ())
14666 op0 = gen_reg_rtx (XFmode);
14667 op1 = gen_reg_rtx (XFmode);
14668 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14669 emit_insn (gen_frndintxf2_floor (op0, op1));
14671 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14676 (define_insn_and_split "*fist<mode>2_floor_1"
14677 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14678 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14679 UNSPEC_FIST_FLOOR))
14680 (clobber (reg:CC FLAGS_REG))]
14681 "TARGET_USE_FANCY_MATH_387
14682 && flag_unsafe_math_optimizations
14683 && can_create_pseudo_p ()"
14688 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14690 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14691 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14692 if (memory_operand (operands[0], VOIDmode))
14693 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14694 operands[2], operands[3]));
14697 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14698 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14699 operands[2], operands[3],
14704 [(set_attr "type" "fistp")
14705 (set_attr "i387_cw" "floor")
14706 (set_attr "mode" "<MODE>")])
14708 (define_insn "fistdi2_floor"
14709 [(set (match_operand:DI 0 "memory_operand" "=m")
14710 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14711 UNSPEC_FIST_FLOOR))
14712 (use (match_operand:HI 2 "memory_operand" "m"))
14713 (use (match_operand:HI 3 "memory_operand" "m"))
14714 (clobber (match_scratch:XF 4 "=&1f"))]
14715 "TARGET_USE_FANCY_MATH_387
14716 && flag_unsafe_math_optimizations"
14717 "* return output_fix_trunc (insn, operands, false);"
14718 [(set_attr "type" "fistp")
14719 (set_attr "i387_cw" "floor")
14720 (set_attr "mode" "DI")])
14722 (define_insn "fistdi2_floor_with_temp"
14723 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14725 UNSPEC_FIST_FLOOR))
14726 (use (match_operand:HI 2 "memory_operand" "m,m"))
14727 (use (match_operand:HI 3 "memory_operand" "m,m"))
14728 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14729 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && flag_unsafe_math_optimizations"
14733 [(set_attr "type" "fistp")
14734 (set_attr "i387_cw" "floor")
14735 (set_attr "mode" "DI")])
14738 [(set (match_operand:DI 0 "register_operand" "")
14739 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14740 UNSPEC_FIST_FLOOR))
14741 (use (match_operand:HI 2 "memory_operand" ""))
14742 (use (match_operand:HI 3 "memory_operand" ""))
14743 (clobber (match_operand:DI 4 "memory_operand" ""))
14744 (clobber (match_scratch 5 ""))]
14746 [(parallel [(set (match_dup 4)
14747 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14748 (use (match_dup 2))
14749 (use (match_dup 3))
14750 (clobber (match_dup 5))])
14751 (set (match_dup 0) (match_dup 4))])
14754 [(set (match_operand:DI 0 "memory_operand" "")
14755 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14756 UNSPEC_FIST_FLOOR))
14757 (use (match_operand:HI 2 "memory_operand" ""))
14758 (use (match_operand:HI 3 "memory_operand" ""))
14759 (clobber (match_operand:DI 4 "memory_operand" ""))
14760 (clobber (match_scratch 5 ""))]
14762 [(parallel [(set (match_dup 0)
14763 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14764 (use (match_dup 2))
14765 (use (match_dup 3))
14766 (clobber (match_dup 5))])])
14768 (define_insn "fist<mode>2_floor"
14769 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14771 UNSPEC_FIST_FLOOR))
14772 (use (match_operand:HI 2 "memory_operand" "m"))
14773 (use (match_operand:HI 3 "memory_operand" "m"))]
14774 "TARGET_USE_FANCY_MATH_387
14775 && flag_unsafe_math_optimizations"
14776 "* return output_fix_trunc (insn, operands, false);"
14777 [(set_attr "type" "fistp")
14778 (set_attr "i387_cw" "floor")
14779 (set_attr "mode" "<MODE>")])
14781 (define_insn "fist<mode>2_floor_with_temp"
14782 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14783 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14784 UNSPEC_FIST_FLOOR))
14785 (use (match_operand:HI 2 "memory_operand" "m,m"))
14786 (use (match_operand:HI 3 "memory_operand" "m,m"))
14787 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations"
14791 [(set_attr "type" "fistp")
14792 (set_attr "i387_cw" "floor")
14793 (set_attr "mode" "<MODE>")])
14796 [(set (match_operand:SWI24 0 "register_operand" "")
14797 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14798 UNSPEC_FIST_FLOOR))
14799 (use (match_operand:HI 2 "memory_operand" ""))
14800 (use (match_operand:HI 3 "memory_operand" ""))
14801 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14803 [(parallel [(set (match_dup 4)
14804 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14805 (use (match_dup 2))
14806 (use (match_dup 3))])
14807 (set (match_dup 0) (match_dup 4))])
14810 [(set (match_operand:SWI24 0 "memory_operand" "")
14811 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14812 UNSPEC_FIST_FLOOR))
14813 (use (match_operand:HI 2 "memory_operand" ""))
14814 (use (match_operand:HI 3 "memory_operand" ""))
14815 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14817 [(parallel [(set (match_dup 0)
14818 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14819 (use (match_dup 2))
14820 (use (match_dup 3))])])
14822 (define_expand "lfloorxf<mode>2"
14823 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14824 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14825 UNSPEC_FIST_FLOOR))
14826 (clobber (reg:CC FLAGS_REG))])]
14827 "TARGET_USE_FANCY_MATH_387
14828 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14829 && flag_unsafe_math_optimizations")
14831 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14832 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14833 (match_operand:MODEF 1 "register_operand" "")]
14834 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14835 && !flag_trapping_math"
14837 if (TARGET_64BIT && optimize_insn_for_size_p ())
14839 ix86_expand_lfloorceil (operand0, operand1, true);
14843 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14844 (define_insn_and_split "frndintxf2_ceil"
14845 [(set (match_operand:XF 0 "register_operand" "")
14846 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14847 UNSPEC_FRNDINT_CEIL))
14848 (clobber (reg:CC FLAGS_REG))]
14849 "TARGET_USE_FANCY_MATH_387
14850 && flag_unsafe_math_optimizations
14851 && can_create_pseudo_p ()"
14856 ix86_optimize_mode_switching[I387_CEIL] = 1;
14858 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14859 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14861 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14862 operands[2], operands[3]));
14865 [(set_attr "type" "frndint")
14866 (set_attr "i387_cw" "ceil")
14867 (set_attr "mode" "XF")])
14869 (define_insn "frndintxf2_ceil_i387"
14870 [(set (match_operand:XF 0 "register_operand" "=f")
14871 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14872 UNSPEC_FRNDINT_CEIL))
14873 (use (match_operand:HI 2 "memory_operand" "m"))
14874 (use (match_operand:HI 3 "memory_operand" "m"))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14877 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14878 [(set_attr "type" "frndint")
14879 (set_attr "i387_cw" "ceil")
14880 (set_attr "mode" "XF")])
14882 (define_expand "ceilxf2"
14883 [(use (match_operand:XF 0 "register_operand" ""))
14884 (use (match_operand:XF 1 "register_operand" ""))]
14885 "TARGET_USE_FANCY_MATH_387
14886 && flag_unsafe_math_optimizations"
14888 if (optimize_insn_for_size_p ())
14890 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14894 (define_expand "ceil<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand" ""))
14896 (use (match_operand:MODEF 1 "register_operand" ""))]
14897 "(TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations)
14901 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14902 && !flag_trapping_math)"
14904 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && !flag_trapping_math
14906 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14909 emit_insn (gen_sse4_1_round<mode>2
14910 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14911 else if (optimize_insn_for_size_p ())
14913 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14914 ix86_expand_floorceil (operand0, operand1, false);
14916 ix86_expand_floorceildf_32 (operand0, operand1, false);
14922 if (optimize_insn_for_size_p ())
14925 op0 = gen_reg_rtx (XFmode);
14926 op1 = gen_reg_rtx (XFmode);
14927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14928 emit_insn (gen_frndintxf2_ceil (op0, op1));
14930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14935 (define_insn_and_split "*fist<mode>2_ceil_1"
14936 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14937 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14939 (clobber (reg:CC FLAGS_REG))]
14940 "TARGET_USE_FANCY_MATH_387
14941 && flag_unsafe_math_optimizations
14942 && can_create_pseudo_p ()"
14947 ix86_optimize_mode_switching[I387_CEIL] = 1;
14949 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14950 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14951 if (memory_operand (operands[0], VOIDmode))
14952 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14953 operands[2], operands[3]));
14956 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14957 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14958 operands[2], operands[3],
14963 [(set_attr "type" "fistp")
14964 (set_attr "i387_cw" "ceil")
14965 (set_attr "mode" "<MODE>")])
14967 (define_insn "fistdi2_ceil"
14968 [(set (match_operand:DI 0 "memory_operand" "=m")
14969 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14971 (use (match_operand:HI 2 "memory_operand" "m"))
14972 (use (match_operand:HI 3 "memory_operand" "m"))
14973 (clobber (match_scratch:XF 4 "=&1f"))]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations"
14976 "* return output_fix_trunc (insn, operands, false);"
14977 [(set_attr "type" "fistp")
14978 (set_attr "i387_cw" "ceil")
14979 (set_attr "mode" "DI")])
14981 (define_insn "fistdi2_ceil_with_temp"
14982 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14983 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14985 (use (match_operand:HI 2 "memory_operand" "m,m"))
14986 (use (match_operand:HI 3 "memory_operand" "m,m"))
14987 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14988 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14989 "TARGET_USE_FANCY_MATH_387
14990 && flag_unsafe_math_optimizations"
14992 [(set_attr "type" "fistp")
14993 (set_attr "i387_cw" "ceil")
14994 (set_attr "mode" "DI")])
14997 [(set (match_operand:DI 0 "register_operand" "")
14998 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15000 (use (match_operand:HI 2 "memory_operand" ""))
15001 (use (match_operand:HI 3 "memory_operand" ""))
15002 (clobber (match_operand:DI 4 "memory_operand" ""))
15003 (clobber (match_scratch 5 ""))]
15005 [(parallel [(set (match_dup 4)
15006 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15007 (use (match_dup 2))
15008 (use (match_dup 3))
15009 (clobber (match_dup 5))])
15010 (set (match_dup 0) (match_dup 4))])
15013 [(set (match_operand:DI 0 "memory_operand" "")
15014 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15016 (use (match_operand:HI 2 "memory_operand" ""))
15017 (use (match_operand:HI 3 "memory_operand" ""))
15018 (clobber (match_operand:DI 4 "memory_operand" ""))
15019 (clobber (match_scratch 5 ""))]
15021 [(parallel [(set (match_dup 0)
15022 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15023 (use (match_dup 2))
15024 (use (match_dup 3))
15025 (clobber (match_dup 5))])])
15027 (define_insn "fist<mode>2_ceil"
15028 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15031 (use (match_operand:HI 2 "memory_operand" "m"))
15032 (use (match_operand:HI 3 "memory_operand" "m"))]
15033 "TARGET_USE_FANCY_MATH_387
15034 && flag_unsafe_math_optimizations"
15035 "* return output_fix_trunc (insn, operands, false);"
15036 [(set_attr "type" "fistp")
15037 (set_attr "i387_cw" "ceil")
15038 (set_attr "mode" "<MODE>")])
15040 (define_insn "fist<mode>2_ceil_with_temp"
15041 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15042 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15044 (use (match_operand:HI 2 "memory_operand" "m,m"))
15045 (use (match_operand:HI 3 "memory_operand" "m,m"))
15046 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations"
15050 [(set_attr "type" "fistp")
15051 (set_attr "i387_cw" "ceil")
15052 (set_attr "mode" "<MODE>")])
15055 [(set (match_operand:SWI24 0 "register_operand" "")
15056 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15058 (use (match_operand:HI 2 "memory_operand" ""))
15059 (use (match_operand:HI 3 "memory_operand" ""))
15060 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15062 [(parallel [(set (match_dup 4)
15063 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15064 (use (match_dup 2))
15065 (use (match_dup 3))])
15066 (set (match_dup 0) (match_dup 4))])
15069 [(set (match_operand:SWI24 0 "memory_operand" "")
15070 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15072 (use (match_operand:HI 2 "memory_operand" ""))
15073 (use (match_operand:HI 3 "memory_operand" ""))
15074 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15076 [(parallel [(set (match_dup 0)
15077 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15078 (use (match_dup 2))
15079 (use (match_dup 3))])])
15081 (define_expand "lceilxf<mode>2"
15082 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15083 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15085 (clobber (reg:CC FLAGS_REG))])]
15086 "TARGET_USE_FANCY_MATH_387
15087 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15088 && flag_unsafe_math_optimizations")
15090 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15091 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15092 (match_operand:MODEF 1 "register_operand" "")]
15093 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15094 && !flag_trapping_math"
15096 ix86_expand_lfloorceil (operand0, operand1, false);
15100 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15101 (define_insn_and_split "frndintxf2_trunc"
15102 [(set (match_operand:XF 0 "register_operand" "")
15103 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15104 UNSPEC_FRNDINT_TRUNC))
15105 (clobber (reg:CC FLAGS_REG))]
15106 "TARGET_USE_FANCY_MATH_387
15107 && flag_unsafe_math_optimizations
15108 && can_create_pseudo_p ()"
15113 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15115 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15116 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15118 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15119 operands[2], operands[3]));
15122 [(set_attr "type" "frndint")
15123 (set_attr "i387_cw" "trunc")
15124 (set_attr "mode" "XF")])
15126 (define_insn "frndintxf2_trunc_i387"
15127 [(set (match_operand:XF 0 "register_operand" "=f")
15128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15129 UNSPEC_FRNDINT_TRUNC))
15130 (use (match_operand:HI 2 "memory_operand" "m"))
15131 (use (match_operand:HI 3 "memory_operand" "m"))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15134 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15135 [(set_attr "type" "frndint")
15136 (set_attr "i387_cw" "trunc")
15137 (set_attr "mode" "XF")])
15139 (define_expand "btruncxf2"
15140 [(use (match_operand:XF 0 "register_operand" ""))
15141 (use (match_operand:XF 1 "register_operand" ""))]
15142 "TARGET_USE_FANCY_MATH_387
15143 && flag_unsafe_math_optimizations"
15145 if (optimize_insn_for_size_p ())
15147 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15151 (define_expand "btrunc<mode>2"
15152 [(use (match_operand:MODEF 0 "register_operand" ""))
15153 (use (match_operand:MODEF 1 "register_operand" ""))]
15154 "(TARGET_USE_FANCY_MATH_387
15155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156 || TARGET_MIX_SSE_I387)
15157 && flag_unsafe_math_optimizations)
15158 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15159 && !flag_trapping_math)"
15161 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15162 && !flag_trapping_math
15163 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15166 emit_insn (gen_sse4_1_round<mode>2
15167 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15168 else if (optimize_insn_for_size_p ())
15170 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15171 ix86_expand_trunc (operand0, operand1);
15173 ix86_expand_truncdf_32 (operand0, operand1);
15179 if (optimize_insn_for_size_p ())
15182 op0 = gen_reg_rtx (XFmode);
15183 op1 = gen_reg_rtx (XFmode);
15184 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15185 emit_insn (gen_frndintxf2_trunc (op0, op1));
15187 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15192 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15193 (define_insn_and_split "frndintxf2_mask_pm"
15194 [(set (match_operand:XF 0 "register_operand" "")
15195 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15196 UNSPEC_FRNDINT_MASK_PM))
15197 (clobber (reg:CC FLAGS_REG))]
15198 "TARGET_USE_FANCY_MATH_387
15199 && flag_unsafe_math_optimizations
15200 && can_create_pseudo_p ()"
15205 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15207 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15208 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15210 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15211 operands[2], operands[3]));
15214 [(set_attr "type" "frndint")
15215 (set_attr "i387_cw" "mask_pm")
15216 (set_attr "mode" "XF")])
15218 (define_insn "frndintxf2_mask_pm_i387"
15219 [(set (match_operand:XF 0 "register_operand" "=f")
15220 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15221 UNSPEC_FRNDINT_MASK_PM))
15222 (use (match_operand:HI 2 "memory_operand" "m"))
15223 (use (match_operand:HI 3 "memory_operand" "m"))]
15224 "TARGET_USE_FANCY_MATH_387
15225 && flag_unsafe_math_optimizations"
15226 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15227 [(set_attr "type" "frndint")
15228 (set_attr "i387_cw" "mask_pm")
15229 (set_attr "mode" "XF")])
15231 (define_expand "nearbyintxf2"
15232 [(use (match_operand:XF 0 "register_operand" ""))
15233 (use (match_operand:XF 1 "register_operand" ""))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15237 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15241 (define_expand "nearbyint<mode>2"
15242 [(use (match_operand:MODEF 0 "register_operand" ""))
15243 (use (match_operand:MODEF 1 "register_operand" ""))]
15244 "TARGET_USE_FANCY_MATH_387
15245 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15246 || TARGET_MIX_SSE_I387)
15247 && flag_unsafe_math_optimizations"
15249 rtx op0 = gen_reg_rtx (XFmode);
15250 rtx op1 = gen_reg_rtx (XFmode);
15252 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15253 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15255 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15259 (define_insn "fxam<mode>2_i387"
15260 [(set (match_operand:HI 0 "register_operand" "=a")
15262 [(match_operand:X87MODEF 1 "register_operand" "f")]
15264 "TARGET_USE_FANCY_MATH_387"
15265 "fxam\n\tfnstsw\t%0"
15266 [(set_attr "type" "multi")
15267 (set_attr "length" "4")
15268 (set_attr "unit" "i387")
15269 (set_attr "mode" "<MODE>")])
15271 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15272 [(set (match_operand:HI 0 "register_operand" "")
15274 [(match_operand:MODEF 1 "memory_operand" "")]
15276 "TARGET_USE_FANCY_MATH_387
15277 && can_create_pseudo_p ()"
15280 [(set (match_dup 2)(match_dup 1))
15282 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15284 operands[2] = gen_reg_rtx (<MODE>mode);
15286 MEM_VOLATILE_P (operands[1]) = 1;
15288 [(set_attr "type" "multi")
15289 (set_attr "unit" "i387")
15290 (set_attr "mode" "<MODE>")])
15292 (define_expand "isinfxf2"
15293 [(use (match_operand:SI 0 "register_operand" ""))
15294 (use (match_operand:XF 1 "register_operand" ""))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && TARGET_C99_FUNCTIONS"
15298 rtx mask = GEN_INT (0x45);
15299 rtx val = GEN_INT (0x05);
15303 rtx scratch = gen_reg_rtx (HImode);
15304 rtx res = gen_reg_rtx (QImode);
15306 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15308 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15309 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15310 cond = gen_rtx_fmt_ee (EQ, QImode,
15311 gen_rtx_REG (CCmode, FLAGS_REG),
15313 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15314 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15318 (define_expand "isinf<mode>2"
15319 [(use (match_operand:SI 0 "register_operand" ""))
15320 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && TARGET_C99_FUNCTIONS
15323 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15325 rtx mask = GEN_INT (0x45);
15326 rtx val = GEN_INT (0x05);
15330 rtx scratch = gen_reg_rtx (HImode);
15331 rtx res = gen_reg_rtx (QImode);
15333 /* Remove excess precision by forcing value through memory. */
15334 if (memory_operand (operands[1], VOIDmode))
15335 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15338 enum ix86_stack_slot slot = (virtuals_instantiated
15341 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15343 emit_move_insn (temp, operands[1]);
15344 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15347 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15348 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15349 cond = gen_rtx_fmt_ee (EQ, QImode,
15350 gen_rtx_REG (CCmode, FLAGS_REG),
15352 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15353 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15357 (define_expand "signbitxf2"
15358 [(use (match_operand:SI 0 "register_operand" ""))
15359 (use (match_operand:XF 1 "register_operand" ""))]
15360 "TARGET_USE_FANCY_MATH_387"
15362 rtx scratch = gen_reg_rtx (HImode);
15364 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15365 emit_insn (gen_andsi3 (operands[0],
15366 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15370 (define_insn "movmsk_df"
15371 [(set (match_operand:SI 0 "register_operand" "=r")
15373 [(match_operand:DF 1 "register_operand" "x")]
15375 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15376 "%vmovmskpd\t{%1, %0|%0, %1}"
15377 [(set_attr "type" "ssemov")
15378 (set_attr "prefix" "maybe_vex")
15379 (set_attr "mode" "DF")])
15381 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15382 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15383 (define_expand "signbitdf2"
15384 [(use (match_operand:SI 0 "register_operand" ""))
15385 (use (match_operand:DF 1 "register_operand" ""))]
15386 "TARGET_USE_FANCY_MATH_387
15387 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15389 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15391 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15392 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15396 rtx scratch = gen_reg_rtx (HImode);
15398 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15399 emit_insn (gen_andsi3 (operands[0],
15400 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15405 (define_expand "signbitsf2"
15406 [(use (match_operand:SI 0 "register_operand" ""))
15407 (use (match_operand:SF 1 "register_operand" ""))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15411 rtx scratch = gen_reg_rtx (HImode);
15413 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15414 emit_insn (gen_andsi3 (operands[0],
15415 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15419 ;; Block operation instructions
15422 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15425 [(set_attr "length" "1")
15426 (set_attr "length_immediate" "0")
15427 (set_attr "modrm" "0")])
15429 (define_expand "movmem<mode>"
15430 [(use (match_operand:BLK 0 "memory_operand" ""))
15431 (use (match_operand:BLK 1 "memory_operand" ""))
15432 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15433 (use (match_operand:SWI48 3 "const_int_operand" ""))
15434 (use (match_operand:SI 4 "const_int_operand" ""))
15435 (use (match_operand:SI 5 "const_int_operand" ""))]
15438 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15439 operands[4], operands[5]))
15445 ;; Most CPUs don't like single string operations
15446 ;; Handle this case here to simplify previous expander.
15448 (define_expand "strmov"
15449 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15450 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15451 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15452 (clobber (reg:CC FLAGS_REG))])
15453 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15454 (clobber (reg:CC FLAGS_REG))])]
15457 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15459 /* If .md ever supports :P for Pmode, these can be directly
15460 in the pattern above. */
15461 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15462 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15464 /* Can't use this if the user has appropriated esi or edi. */
15465 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15466 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15468 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15469 operands[2], operands[3],
15470 operands[5], operands[6]));
15474 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15477 (define_expand "strmov_singleop"
15478 [(parallel [(set (match_operand 1 "memory_operand" "")
15479 (match_operand 3 "memory_operand" ""))
15480 (set (match_operand 0 "register_operand" "")
15481 (match_operand 4 "" ""))
15482 (set (match_operand 2 "register_operand" "")
15483 (match_operand 5 "" ""))])]
15485 "ix86_current_function_needs_cld = 1;")
15487 (define_insn "*strmovdi_rex_1"
15488 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15489 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (match_dup 2)
15493 (set (match_operand:DI 1 "register_operand" "=S")
15494 (plus:DI (match_dup 3)
15497 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15499 [(set_attr "type" "str")
15500 (set_attr "memory" "both")
15501 (set_attr "mode" "DI")])
15503 (define_insn "*strmovsi_1"
15504 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15505 (mem:SI (match_operand:P 3 "register_operand" "1")))
15506 (set (match_operand:P 0 "register_operand" "=D")
15507 (plus:P (match_dup 2)
15509 (set (match_operand:P 1 "register_operand" "=S")
15510 (plus:P (match_dup 3)
15512 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15514 [(set_attr "type" "str")
15515 (set_attr "memory" "both")
15516 (set_attr "mode" "SI")])
15518 (define_insn "*strmovhi_1"
15519 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15520 (mem:HI (match_operand:P 3 "register_operand" "1")))
15521 (set (match_operand:P 0 "register_operand" "=D")
15522 (plus:P (match_dup 2)
15524 (set (match_operand:P 1 "register_operand" "=S")
15525 (plus:P (match_dup 3)
15527 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15529 [(set_attr "type" "str")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "HI")])
15533 (define_insn "*strmovqi_1"
15534 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15535 (mem:QI (match_operand:P 3 "register_operand" "1")))
15536 (set (match_operand:P 0 "register_operand" "=D")
15537 (plus:P (match_dup 2)
15539 (set (match_operand:P 1 "register_operand" "=S")
15540 (plus:P (match_dup 3)
15542 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15544 [(set_attr "type" "str")
15545 (set_attr "memory" "both")
15546 (set (attr "prefix_rex")
15548 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15550 (const_string "*")))
15551 (set_attr "mode" "QI")])
15553 (define_expand "rep_mov"
15554 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15555 (set (match_operand 0 "register_operand" "")
15556 (match_operand 5 "" ""))
15557 (set (match_operand 2 "register_operand" "")
15558 (match_operand 6 "" ""))
15559 (set (match_operand 1 "memory_operand" "")
15560 (match_operand 3 "memory_operand" ""))
15561 (use (match_dup 4))])]
15563 "ix86_current_function_needs_cld = 1;")
15565 (define_insn "*rep_movdi_rex64"
15566 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15567 (set (match_operand:DI 0 "register_operand" "=D")
15568 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15570 (match_operand:DI 3 "register_operand" "0")))
15571 (set (match_operand:DI 1 "register_operand" "=S")
15572 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15573 (match_operand:DI 4 "register_operand" "1")))
15574 (set (mem:BLK (match_dup 3))
15575 (mem:BLK (match_dup 4)))
15576 (use (match_dup 5))]
15578 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15580 [(set_attr "type" "str")
15581 (set_attr "prefix_rep" "1")
15582 (set_attr "memory" "both")
15583 (set_attr "mode" "DI")])
15585 (define_insn "*rep_movsi"
15586 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15587 (set (match_operand:P 0 "register_operand" "=D")
15588 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15590 (match_operand:P 3 "register_operand" "0")))
15591 (set (match_operand:P 1 "register_operand" "=S")
15592 (plus:P (ashift:P (match_dup 5) (const_int 2))
15593 (match_operand:P 4 "register_operand" "1")))
15594 (set (mem:BLK (match_dup 3))
15595 (mem:BLK (match_dup 4)))
15596 (use (match_dup 5))]
15597 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15598 "rep{%;} movs{l|d}"
15599 [(set_attr "type" "str")
15600 (set_attr "prefix_rep" "1")
15601 (set_attr "memory" "both")
15602 (set_attr "mode" "SI")])
15604 (define_insn "*rep_movqi"
15605 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15606 (set (match_operand:P 0 "register_operand" "=D")
15607 (plus:P (match_operand:P 3 "register_operand" "0")
15608 (match_operand:P 5 "register_operand" "2")))
15609 (set (match_operand:P 1 "register_operand" "=S")
15610 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15611 (set (mem:BLK (match_dup 3))
15612 (mem:BLK (match_dup 4)))
15613 (use (match_dup 5))]
15614 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15616 [(set_attr "type" "str")
15617 (set_attr "prefix_rep" "1")
15618 (set_attr "memory" "both")
15619 (set_attr "mode" "QI")])
15621 (define_expand "setmem<mode>"
15622 [(use (match_operand:BLK 0 "memory_operand" ""))
15623 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15624 (use (match_operand:QI 2 "nonmemory_operand" ""))
15625 (use (match_operand 3 "const_int_operand" ""))
15626 (use (match_operand:SI 4 "const_int_operand" ""))
15627 (use (match_operand:SI 5 "const_int_operand" ""))]
15630 if (ix86_expand_setmem (operands[0], operands[1],
15631 operands[2], operands[3],
15632 operands[4], operands[5]))
15638 ;; Most CPUs don't like single string operations
15639 ;; Handle this case here to simplify previous expander.
15641 (define_expand "strset"
15642 [(set (match_operand 1 "memory_operand" "")
15643 (match_operand 2 "register_operand" ""))
15644 (parallel [(set (match_operand 0 "register_operand" "")
15646 (clobber (reg:CC FLAGS_REG))])]
15649 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15650 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15652 /* If .md ever supports :P for Pmode, this can be directly
15653 in the pattern above. */
15654 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15655 GEN_INT (GET_MODE_SIZE (GET_MODE
15657 /* Can't use this if the user has appropriated eax or edi. */
15658 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15659 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15661 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15667 (define_expand "strset_singleop"
15668 [(parallel [(set (match_operand 1 "memory_operand" "")
15669 (match_operand 2 "register_operand" ""))
15670 (set (match_operand 0 "register_operand" "")
15671 (match_operand 3 "" ""))])]
15673 "ix86_current_function_needs_cld = 1;")
15675 (define_insn "*strsetdi_rex_1"
15676 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15677 (match_operand:DI 2 "register_operand" "a"))
15678 (set (match_operand:DI 0 "register_operand" "=D")
15679 (plus:DI (match_dup 1)
15682 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15684 [(set_attr "type" "str")
15685 (set_attr "memory" "store")
15686 (set_attr "mode" "DI")])
15688 (define_insn "*strsetsi_1"
15689 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15690 (match_operand:SI 2 "register_operand" "a"))
15691 (set (match_operand:P 0 "register_operand" "=D")
15692 (plus:P (match_dup 1)
15694 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15696 [(set_attr "type" "str")
15697 (set_attr "memory" "store")
15698 (set_attr "mode" "SI")])
15700 (define_insn "*strsethi_1"
15701 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15702 (match_operand:HI 2 "register_operand" "a"))
15703 (set (match_operand:P 0 "register_operand" "=D")
15704 (plus:P (match_dup 1)
15706 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15708 [(set_attr "type" "str")
15709 (set_attr "memory" "store")
15710 (set_attr "mode" "HI")])
15712 (define_insn "*strsetqi_1"
15713 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15714 (match_operand:QI 2 "register_operand" "a"))
15715 (set (match_operand:P 0 "register_operand" "=D")
15716 (plus:P (match_dup 1)
15718 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15720 [(set_attr "type" "str")
15721 (set_attr "memory" "store")
15722 (set (attr "prefix_rex")
15724 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15726 (const_string "*")))
15727 (set_attr "mode" "QI")])
15729 (define_expand "rep_stos"
15730 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15731 (set (match_operand 0 "register_operand" "")
15732 (match_operand 4 "" ""))
15733 (set (match_operand 2 "memory_operand" "") (const_int 0))
15734 (use (match_operand 3 "register_operand" ""))
15735 (use (match_dup 1))])]
15737 "ix86_current_function_needs_cld = 1;")
15739 (define_insn "*rep_stosdi_rex64"
15740 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15741 (set (match_operand:DI 0 "register_operand" "=D")
15742 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15744 (match_operand:DI 3 "register_operand" "0")))
15745 (set (mem:BLK (match_dup 3))
15747 (use (match_operand:DI 2 "register_operand" "a"))
15748 (use (match_dup 4))]
15750 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15752 [(set_attr "type" "str")
15753 (set_attr "prefix_rep" "1")
15754 (set_attr "memory" "store")
15755 (set_attr "mode" "DI")])
15757 (define_insn "*rep_stossi"
15758 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15759 (set (match_operand:P 0 "register_operand" "=D")
15760 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15762 (match_operand:P 3 "register_operand" "0")))
15763 (set (mem:BLK (match_dup 3))
15765 (use (match_operand:SI 2 "register_operand" "a"))
15766 (use (match_dup 4))]
15767 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15768 "rep{%;} stos{l|d}"
15769 [(set_attr "type" "str")
15770 (set_attr "prefix_rep" "1")
15771 (set_attr "memory" "store")
15772 (set_attr "mode" "SI")])
15774 (define_insn "*rep_stosqi"
15775 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_operand:P 3 "register_operand" "0")
15778 (match_operand:P 4 "register_operand" "1")))
15779 (set (mem:BLK (match_dup 3))
15781 (use (match_operand:QI 2 "register_operand" "a"))
15782 (use (match_dup 4))]
15783 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15785 [(set_attr "type" "str")
15786 (set_attr "prefix_rep" "1")
15787 (set_attr "memory" "store")
15788 (set (attr "prefix_rex")
15790 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15792 (const_string "*")))
15793 (set_attr "mode" "QI")])
15795 (define_expand "cmpstrnsi"
15796 [(set (match_operand:SI 0 "register_operand" "")
15797 (compare:SI (match_operand:BLK 1 "general_operand" "")
15798 (match_operand:BLK 2 "general_operand" "")))
15799 (use (match_operand 3 "general_operand" ""))
15800 (use (match_operand 4 "immediate_operand" ""))]
15803 rtx addr1, addr2, out, outlow, count, countreg, align;
15805 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15808 /* Can't use this if the user has appropriated ecx, esi or edi. */
15809 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15814 out = gen_reg_rtx (SImode);
15816 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15817 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15818 if (addr1 != XEXP (operands[1], 0))
15819 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15820 if (addr2 != XEXP (operands[2], 0))
15821 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15823 count = operands[3];
15824 countreg = ix86_zero_extend_to_Pmode (count);
15826 /* %%% Iff we are testing strict equality, we can use known alignment
15827 to good advantage. This may be possible with combine, particularly
15828 once cc0 is dead. */
15829 align = operands[4];
15831 if (CONST_INT_P (count))
15833 if (INTVAL (count) == 0)
15835 emit_move_insn (operands[0], const0_rtx);
15838 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15839 operands[1], operands[2]));
15843 rtx (*gen_cmp) (rtx, rtx);
15845 gen_cmp = (TARGET_64BIT
15846 ? gen_cmpdi_1 : gen_cmpsi_1);
15848 emit_insn (gen_cmp (countreg, countreg));
15849 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15850 operands[1], operands[2]));
15853 outlow = gen_lowpart (QImode, out);
15854 emit_insn (gen_cmpintqi (outlow));
15855 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15857 if (operands[0] != out)
15858 emit_move_insn (operands[0], out);
15863 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15865 (define_expand "cmpintqi"
15866 [(set (match_dup 1)
15867 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15869 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15870 (parallel [(set (match_operand:QI 0 "register_operand" "")
15871 (minus:QI (match_dup 1)
15873 (clobber (reg:CC FLAGS_REG))])]
15876 operands[1] = gen_reg_rtx (QImode);
15877 operands[2] = gen_reg_rtx (QImode);
15880 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15881 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15883 (define_expand "cmpstrnqi_nz_1"
15884 [(parallel [(set (reg:CC FLAGS_REG)
15885 (compare:CC (match_operand 4 "memory_operand" "")
15886 (match_operand 5 "memory_operand" "")))
15887 (use (match_operand 2 "register_operand" ""))
15888 (use (match_operand:SI 3 "immediate_operand" ""))
15889 (clobber (match_operand 0 "register_operand" ""))
15890 (clobber (match_operand 1 "register_operand" ""))
15891 (clobber (match_dup 2))])]
15893 "ix86_current_function_needs_cld = 1;")
15895 (define_insn "*cmpstrnqi_nz_1"
15896 [(set (reg:CC FLAGS_REG)
15897 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15898 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15899 (use (match_operand:P 6 "register_operand" "2"))
15900 (use (match_operand:SI 3 "immediate_operand" "i"))
15901 (clobber (match_operand:P 0 "register_operand" "=S"))
15902 (clobber (match_operand:P 1 "register_operand" "=D"))
15903 (clobber (match_operand:P 2 "register_operand" "=c"))]
15904 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15906 [(set_attr "type" "str")
15907 (set_attr "mode" "QI")
15908 (set (attr "prefix_rex")
15910 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15912 (const_string "*")))
15913 (set_attr "prefix_rep" "1")])
15915 ;; The same, but the count is not known to not be zero.
15917 (define_expand "cmpstrnqi_1"
15918 [(parallel [(set (reg:CC FLAGS_REG)
15919 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15921 (compare:CC (match_operand 4 "memory_operand" "")
15922 (match_operand 5 "memory_operand" ""))
15924 (use (match_operand:SI 3 "immediate_operand" ""))
15925 (use (reg:CC FLAGS_REG))
15926 (clobber (match_operand 0 "register_operand" ""))
15927 (clobber (match_operand 1 "register_operand" ""))
15928 (clobber (match_dup 2))])]
15930 "ix86_current_function_needs_cld = 1;")
15932 (define_insn "*cmpstrnqi_1"
15933 [(set (reg:CC FLAGS_REG)
15934 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15936 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15937 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15939 (use (match_operand:SI 3 "immediate_operand" "i"))
15940 (use (reg:CC FLAGS_REG))
15941 (clobber (match_operand:P 0 "register_operand" "=S"))
15942 (clobber (match_operand:P 1 "register_operand" "=D"))
15943 (clobber (match_operand:P 2 "register_operand" "=c"))]
15944 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15946 [(set_attr "type" "str")
15947 (set_attr "mode" "QI")
15948 (set (attr "prefix_rex")
15950 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15952 (const_string "*")))
15953 (set_attr "prefix_rep" "1")])
15955 (define_expand "strlen<mode>"
15956 [(set (match_operand:P 0 "register_operand" "")
15957 (unspec:P [(match_operand:BLK 1 "general_operand" "")
15958 (match_operand:QI 2 "immediate_operand" "")
15959 (match_operand 3 "immediate_operand" "")]
15963 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15969 (define_expand "strlenqi_1"
15970 [(parallel [(set (match_operand 0 "register_operand" "")
15971 (match_operand 2 "" ""))
15972 (clobber (match_operand 1 "register_operand" ""))
15973 (clobber (reg:CC FLAGS_REG))])]
15975 "ix86_current_function_needs_cld = 1;")
15977 (define_insn "*strlenqi_1"
15978 [(set (match_operand:P 0 "register_operand" "=&c")
15979 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15980 (match_operand:QI 2 "register_operand" "a")
15981 (match_operand:P 3 "immediate_operand" "i")
15982 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15983 (clobber (match_operand:P 1 "register_operand" "=D"))
15984 (clobber (reg:CC FLAGS_REG))]
15985 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15987 [(set_attr "type" "str")
15988 (set_attr "mode" "QI")
15989 (set (attr "prefix_rex")
15991 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15993 (const_string "*")))
15994 (set_attr "prefix_rep" "1")])
15996 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15997 ;; handled in combine, but it is not currently up to the task.
15998 ;; When used for their truth value, the cmpstrn* expanders generate
16007 ;; The intermediate three instructions are unnecessary.
16009 ;; This one handles cmpstrn*_nz_1...
16012 (set (reg:CC FLAGS_REG)
16013 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16014 (mem:BLK (match_operand 5 "register_operand" ""))))
16015 (use (match_operand 6 "register_operand" ""))
16016 (use (match_operand:SI 3 "immediate_operand" ""))
16017 (clobber (match_operand 0 "register_operand" ""))
16018 (clobber (match_operand 1 "register_operand" ""))
16019 (clobber (match_operand 2 "register_operand" ""))])
16020 (set (match_operand:QI 7 "register_operand" "")
16021 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16022 (set (match_operand:QI 8 "register_operand" "")
16023 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16024 (set (reg FLAGS_REG)
16025 (compare (match_dup 7) (match_dup 8)))
16027 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16029 (set (reg:CC FLAGS_REG)
16030 (compare:CC (mem:BLK (match_dup 4))
16031 (mem:BLK (match_dup 5))))
16032 (use (match_dup 6))
16033 (use (match_dup 3))
16034 (clobber (match_dup 0))
16035 (clobber (match_dup 1))
16036 (clobber (match_dup 2))])])
16038 ;; ...and this one handles cmpstrn*_1.
16041 (set (reg:CC FLAGS_REG)
16042 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16044 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16045 (mem:BLK (match_operand 5 "register_operand" "")))
16047 (use (match_operand:SI 3 "immediate_operand" ""))
16048 (use (reg:CC FLAGS_REG))
16049 (clobber (match_operand 0 "register_operand" ""))
16050 (clobber (match_operand 1 "register_operand" ""))
16051 (clobber (match_operand 2 "register_operand" ""))])
16052 (set (match_operand:QI 7 "register_operand" "")
16053 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16054 (set (match_operand:QI 8 "register_operand" "")
16055 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16056 (set (reg FLAGS_REG)
16057 (compare (match_dup 7) (match_dup 8)))
16059 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16061 (set (reg:CC FLAGS_REG)
16062 (if_then_else:CC (ne (match_dup 6)
16064 (compare:CC (mem:BLK (match_dup 4))
16065 (mem:BLK (match_dup 5)))
16067 (use (match_dup 3))
16068 (use (reg:CC FLAGS_REG))
16069 (clobber (match_dup 0))
16070 (clobber (match_dup 1))
16071 (clobber (match_dup 2))])])
16073 ;; Conditional move instructions.
16075 (define_expand "mov<mode>cc"
16076 [(set (match_operand:SWIM 0 "register_operand" "")
16077 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16078 (match_operand:SWIM 2 "<general_operand>" "")
16079 (match_operand:SWIM 3 "<general_operand>" "")))]
16081 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16083 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16084 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16085 ;; So just document what we're doing explicitly.
16087 (define_expand "x86_mov<mode>cc_0_m1"
16089 [(set (match_operand:SWI48 0 "register_operand" "")
16090 (if_then_else:SWI48
16091 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16092 [(match_operand 1 "flags_reg_operand" "")
16096 (clobber (reg:CC FLAGS_REG))])])
16098 (define_insn "*x86_mov<mode>cc_0_m1"
16099 [(set (match_operand:SWI48 0 "register_operand" "=r")
16100 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16101 [(reg FLAGS_REG) (const_int 0)])
16104 (clobber (reg:CC FLAGS_REG))]
16106 "sbb{<imodesuffix>}\t%0, %0"
16107 ; Since we don't have the proper number of operands for an alu insn,
16108 ; fill in all the blanks.
16109 [(set_attr "type" "alu")
16110 (set_attr "use_carry" "1")
16111 (set_attr "pent_pair" "pu")
16112 (set_attr "memory" "none")
16113 (set_attr "imm_disp" "false")
16114 (set_attr "mode" "<MODE>")
16115 (set_attr "length_immediate" "0")])
16117 (define_insn "*x86_mov<mode>cc_0_m1_se"
16118 [(set (match_operand:SWI48 0 "register_operand" "=r")
16119 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16120 [(reg FLAGS_REG) (const_int 0)])
16123 (clobber (reg:CC FLAGS_REG))]
16125 "sbb{<imodesuffix>}\t%0, %0"
16126 [(set_attr "type" "alu")
16127 (set_attr "use_carry" "1")
16128 (set_attr "pent_pair" "pu")
16129 (set_attr "memory" "none")
16130 (set_attr "imm_disp" "false")
16131 (set_attr "mode" "<MODE>")
16132 (set_attr "length_immediate" "0")])
16134 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16135 [(set (match_operand:SWI48 0 "register_operand" "=r")
16136 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16137 [(reg FLAGS_REG) (const_int 0)])))]
16139 "sbb{<imodesuffix>}\t%0, %0"
16140 [(set_attr "type" "alu")
16141 (set_attr "use_carry" "1")
16142 (set_attr "pent_pair" "pu")
16143 (set_attr "memory" "none")
16144 (set_attr "imm_disp" "false")
16145 (set_attr "mode" "<MODE>")
16146 (set_attr "length_immediate" "0")])
16148 (define_insn "*mov<mode>cc_noc"
16149 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16150 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16151 [(reg FLAGS_REG) (const_int 0)])
16152 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16153 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16154 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16156 cmov%O2%C1\t{%2, %0|%0, %2}
16157 cmov%O2%c1\t{%3, %0|%0, %3}"
16158 [(set_attr "type" "icmov")
16159 (set_attr "mode" "<MODE>")])
16161 (define_insn_and_split "*movqicc_noc"
16162 [(set (match_operand:QI 0 "register_operand" "=r,r")
16163 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16164 [(match_operand 4 "flags_reg_operand" "")
16166 (match_operand:QI 2 "register_operand" "r,0")
16167 (match_operand:QI 3 "register_operand" "0,r")))]
16168 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16170 "&& reload_completed"
16171 [(set (match_dup 0)
16172 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16175 "operands[0] = gen_lowpart (SImode, operands[0]);
16176 operands[2] = gen_lowpart (SImode, operands[2]);
16177 operands[3] = gen_lowpart (SImode, operands[3]);"
16178 [(set_attr "type" "icmov")
16179 (set_attr "mode" "SI")])
16181 (define_expand "mov<mode>cc"
16182 [(set (match_operand:X87MODEF 0 "register_operand" "")
16183 (if_then_else:X87MODEF
16184 (match_operand 1 "ix86_fp_comparison_operator" "")
16185 (match_operand:X87MODEF 2 "register_operand" "")
16186 (match_operand:X87MODEF 3 "register_operand" "")))]
16187 "(TARGET_80387 && TARGET_CMOVE)
16188 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16189 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16191 (define_insn "*movxfcc_1"
16192 [(set (match_operand:XF 0 "register_operand" "=f,f")
16193 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16194 [(reg FLAGS_REG) (const_int 0)])
16195 (match_operand:XF 2 "register_operand" "f,0")
16196 (match_operand:XF 3 "register_operand" "0,f")))]
16197 "TARGET_80387 && TARGET_CMOVE"
16199 fcmov%F1\t{%2, %0|%0, %2}
16200 fcmov%f1\t{%3, %0|%0, %3}"
16201 [(set_attr "type" "fcmov")
16202 (set_attr "mode" "XF")])
16204 (define_insn "*movdfcc_1_rex64"
16205 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16206 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16207 [(reg FLAGS_REG) (const_int 0)])
16208 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16209 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16210 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16211 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16213 fcmov%F1\t{%2, %0|%0, %2}
16214 fcmov%f1\t{%3, %0|%0, %3}
16215 cmov%O2%C1\t{%2, %0|%0, %2}
16216 cmov%O2%c1\t{%3, %0|%0, %3}"
16217 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16218 (set_attr "mode" "DF,DF,DI,DI")])
16220 (define_insn "*movdfcc_1"
16221 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16222 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16223 [(reg FLAGS_REG) (const_int 0)])
16224 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16225 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16226 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16227 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16229 fcmov%F1\t{%2, %0|%0, %2}
16230 fcmov%f1\t{%3, %0|%0, %3}
16233 [(set_attr "type" "fcmov,fcmov,multi,multi")
16234 (set_attr "mode" "DF,DF,DI,DI")])
16237 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16238 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16239 [(match_operand 4 "flags_reg_operand" "")
16241 (match_operand:DF 2 "nonimmediate_operand" "")
16242 (match_operand:DF 3 "nonimmediate_operand" "")))]
16243 "!TARGET_64BIT && reload_completed"
16244 [(set (match_dup 2)
16245 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16249 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16253 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16254 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16257 (define_insn "*movsfcc_1_387"
16258 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16259 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16260 [(reg FLAGS_REG) (const_int 0)])
16261 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16262 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16263 "TARGET_80387 && TARGET_CMOVE
16264 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16266 fcmov%F1\t{%2, %0|%0, %2}
16267 fcmov%f1\t{%3, %0|%0, %3}
16268 cmov%O2%C1\t{%2, %0|%0, %2}
16269 cmov%O2%c1\t{%3, %0|%0, %3}"
16270 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16271 (set_attr "mode" "SF,SF,SI,SI")])
16273 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16274 ;; the scalar versions to have only XMM registers as operands.
16276 ;; XOP conditional move
16277 (define_insn "*xop_pcmov_<mode>"
16278 [(set (match_operand:MODEF 0 "register_operand" "=x")
16279 (if_then_else:MODEF
16280 (match_operand:MODEF 1 "register_operand" "x")
16281 (match_operand:MODEF 2 "register_operand" "x")
16282 (match_operand:MODEF 3 "register_operand" "x")))]
16284 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16285 [(set_attr "type" "sse4arg")])
16287 ;; These versions of the min/max patterns are intentionally ignorant of
16288 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16289 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16290 ;; are undefined in this condition, we're certain this is correct.
16292 (define_insn "<code><mode>3"
16293 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16295 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16296 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16297 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16299 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16300 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16301 [(set_attr "isa" "noavx,avx")
16302 (set_attr "prefix" "orig,vex")
16303 (set_attr "type" "sseadd")
16304 (set_attr "mode" "<MODE>")])
16306 ;; These versions of the min/max patterns implement exactly the operations
16307 ;; min = (op1 < op2 ? op1 : op2)
16308 ;; max = (!(op1 < op2) ? op1 : op2)
16309 ;; Their operands are not commutative, and thus they may be used in the
16310 ;; presence of -0.0 and NaN.
16312 (define_insn "*ieee_smin<mode>3"
16313 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16315 [(match_operand:MODEF 1 "register_operand" "0,x")
16316 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16318 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16320 min<ssemodesuffix>\t{%2, %0|%0, %2}
16321 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16322 [(set_attr "isa" "noavx,avx")
16323 (set_attr "prefix" "orig,vex")
16324 (set_attr "type" "sseadd")
16325 (set_attr "mode" "<MODE>")])
16327 (define_insn "*ieee_smax<mode>3"
16328 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16330 [(match_operand:MODEF 1 "register_operand" "0,x")
16331 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16333 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16335 max<ssemodesuffix>\t{%2, %0|%0, %2}
16336 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16337 [(set_attr "isa" "noavx,avx")
16338 (set_attr "prefix" "orig,vex")
16339 (set_attr "type" "sseadd")
16340 (set_attr "mode" "<MODE>")])
16342 ;; Make two stack loads independent:
16344 ;; fld %st(0) -> fld bb
16345 ;; fmul bb fmul %st(1), %st
16347 ;; Actually we only match the last two instructions for simplicity.
16349 [(set (match_operand 0 "fp_register_operand" "")
16350 (match_operand 1 "fp_register_operand" ""))
16352 (match_operator 2 "binary_fp_operator"
16354 (match_operand 3 "memory_operand" "")]))]
16355 "REGNO (operands[0]) != REGNO (operands[1])"
16356 [(set (match_dup 0) (match_dup 3))
16357 (set (match_dup 0) (match_dup 4))]
16359 ;; The % modifier is not operational anymore in peephole2's, so we have to
16360 ;; swap the operands manually in the case of addition and multiplication.
16361 "if (COMMUTATIVE_ARITH_P (operands[2]))
16362 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16363 GET_MODE (operands[2]),
16364 operands[0], operands[1]);
16366 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16367 GET_MODE (operands[2]),
16368 operands[1], operands[0]);")
16370 ;; Conditional addition patterns
16371 (define_expand "add<mode>cc"
16372 [(match_operand:SWI 0 "register_operand" "")
16373 (match_operand 1 "ordered_comparison_operator" "")
16374 (match_operand:SWI 2 "register_operand" "")
16375 (match_operand:SWI 3 "const_int_operand" "")]
16377 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16379 ;; Misc patterns (?)
16381 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16382 ;; Otherwise there will be nothing to keep
16384 ;; [(set (reg ebp) (reg esp))]
16385 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16386 ;; (clobber (eflags)]
16387 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16389 ;; in proper program order.
16391 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16392 [(set (match_operand:P 0 "register_operand" "=r,r")
16393 (plus:P (match_operand:P 1 "register_operand" "0,r")
16394 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16395 (clobber (reg:CC FLAGS_REG))
16396 (clobber (mem:BLK (scratch)))]
16399 switch (get_attr_type (insn))
16402 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16405 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16406 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16407 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16409 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16412 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16413 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16416 [(set (attr "type")
16417 (cond [(and (eq_attr "alternative" "0")
16418 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16419 (const_string "alu")
16420 (match_operand:<MODE> 2 "const0_operand" "")
16421 (const_string "imov")
16423 (const_string "lea")))
16424 (set (attr "length_immediate")
16425 (cond [(eq_attr "type" "imov")
16427 (and (eq_attr "type" "alu")
16428 (match_operand 2 "const128_operand" ""))
16431 (const_string "*")))
16432 (set_attr "mode" "<MODE>")])
16434 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16435 [(set (match_operand:P 0 "register_operand" "=r")
16436 (minus:P (match_operand:P 1 "register_operand" "0")
16437 (match_operand:P 2 "register_operand" "r")))
16438 (clobber (reg:CC FLAGS_REG))
16439 (clobber (mem:BLK (scratch)))]
16441 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16442 [(set_attr "type" "alu")
16443 (set_attr "mode" "<MODE>")])
16445 (define_insn "allocate_stack_worker_probe_<mode>"
16446 [(set (match_operand:P 0 "register_operand" "=a")
16447 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16448 UNSPECV_STACK_PROBE))
16449 (clobber (reg:CC FLAGS_REG))]
16450 "ix86_target_stack_probe ()"
16451 "call\t___chkstk_ms"
16452 [(set_attr "type" "multi")
16453 (set_attr "length" "5")])
16455 (define_expand "allocate_stack"
16456 [(match_operand 0 "register_operand" "")
16457 (match_operand 1 "general_operand" "")]
16458 "ix86_target_stack_probe ()"
16462 #ifndef CHECK_STACK_LIMIT
16463 #define CHECK_STACK_LIMIT 0
16466 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16467 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16469 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16470 stack_pointer_rtx, 0, OPTAB_DIRECT);
16471 if (x != stack_pointer_rtx)
16472 emit_move_insn (stack_pointer_rtx, x);
16476 x = copy_to_mode_reg (Pmode, operands[1]);
16478 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16480 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16481 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16482 stack_pointer_rtx, 0, OPTAB_DIRECT);
16483 if (x != stack_pointer_rtx)
16484 emit_move_insn (stack_pointer_rtx, x);
16487 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16491 ;; Use IOR for stack probes, this is shorter.
16492 (define_expand "probe_stack"
16493 [(match_operand 0 "memory_operand" "")]
16496 rtx (*gen_ior3) (rtx, rtx, rtx);
16498 gen_ior3 = (GET_MODE (operands[0]) == DImode
16499 ? gen_iordi3 : gen_iorsi3);
16501 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16505 (define_insn "adjust_stack_and_probe<mode>"
16506 [(set (match_operand:P 0 "register_operand" "=r")
16507 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16508 UNSPECV_PROBE_STACK_RANGE))
16509 (set (reg:P SP_REG)
16510 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16511 (clobber (reg:CC FLAGS_REG))
16512 (clobber (mem:BLK (scratch)))]
16514 "* return output_adjust_stack_and_probe (operands[0]);"
16515 [(set_attr "type" "multi")])
16517 (define_insn "probe_stack_range<mode>"
16518 [(set (match_operand:P 0 "register_operand" "=r")
16519 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16520 (match_operand:P 2 "const_int_operand" "n")]
16521 UNSPECV_PROBE_STACK_RANGE))
16522 (clobber (reg:CC FLAGS_REG))]
16524 "* return output_probe_stack_range (operands[0], operands[2]);"
16525 [(set_attr "type" "multi")])
16527 (define_expand "builtin_setjmp_receiver"
16528 [(label_ref (match_operand 0 "" ""))]
16529 "!TARGET_64BIT && flag_pic"
16535 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16536 rtx label_rtx = gen_label_rtx ();
16537 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16538 xops[0] = xops[1] = picreg;
16539 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16540 ix86_expand_binary_operator (MINUS, SImode, xops);
16544 emit_insn (gen_set_got (pic_offset_table_rtx));
16548 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16551 [(set (match_operand 0 "register_operand" "")
16552 (match_operator 3 "promotable_binary_operator"
16553 [(match_operand 1 "register_operand" "")
16554 (match_operand 2 "aligned_operand" "")]))
16555 (clobber (reg:CC FLAGS_REG))]
16556 "! TARGET_PARTIAL_REG_STALL && reload_completed
16557 && ((GET_MODE (operands[0]) == HImode
16558 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16559 /* ??? next two lines just !satisfies_constraint_K (...) */
16560 || !CONST_INT_P (operands[2])
16561 || satisfies_constraint_K (operands[2])))
16562 || (GET_MODE (operands[0]) == QImode
16563 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16564 [(parallel [(set (match_dup 0)
16565 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16566 (clobber (reg:CC FLAGS_REG))])]
16567 "operands[0] = gen_lowpart (SImode, operands[0]);
16568 operands[1] = gen_lowpart (SImode, operands[1]);
16569 if (GET_CODE (operands[3]) != ASHIFT)
16570 operands[2] = gen_lowpart (SImode, operands[2]);
16571 PUT_MODE (operands[3], SImode);")
16573 ; Promote the QImode tests, as i386 has encoding of the AND
16574 ; instruction with 32-bit sign-extended immediate and thus the
16575 ; instruction size is unchanged, except in the %eax case for
16576 ; which it is increased by one byte, hence the ! optimize_size.
16578 [(set (match_operand 0 "flags_reg_operand" "")
16579 (match_operator 2 "compare_operator"
16580 [(and (match_operand 3 "aligned_operand" "")
16581 (match_operand 4 "const_int_operand" ""))
16583 (set (match_operand 1 "register_operand" "")
16584 (and (match_dup 3) (match_dup 4)))]
16585 "! TARGET_PARTIAL_REG_STALL && reload_completed
16586 && optimize_insn_for_speed_p ()
16587 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16588 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16589 /* Ensure that the operand will remain sign-extended immediate. */
16590 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16591 [(parallel [(set (match_dup 0)
16592 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16595 (and:SI (match_dup 3) (match_dup 4)))])]
16598 = gen_int_mode (INTVAL (operands[4])
16599 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16600 operands[1] = gen_lowpart (SImode, operands[1]);
16601 operands[3] = gen_lowpart (SImode, operands[3]);
16604 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16605 ; the TEST instruction with 32-bit sign-extended immediate and thus
16606 ; the instruction size would at least double, which is not what we
16607 ; want even with ! optimize_size.
16609 [(set (match_operand 0 "flags_reg_operand" "")
16610 (match_operator 1 "compare_operator"
16611 [(and (match_operand:HI 2 "aligned_operand" "")
16612 (match_operand:HI 3 "const_int_operand" ""))
16614 "! TARGET_PARTIAL_REG_STALL && reload_completed
16615 && ! TARGET_FAST_PREFIX
16616 && optimize_insn_for_speed_p ()
16617 /* Ensure that the operand will remain sign-extended immediate. */
16618 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16619 [(set (match_dup 0)
16620 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16624 = gen_int_mode (INTVAL (operands[3])
16625 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16626 operands[2] = gen_lowpart (SImode, operands[2]);
16630 [(set (match_operand 0 "register_operand" "")
16631 (neg (match_operand 1 "register_operand" "")))
16632 (clobber (reg:CC FLAGS_REG))]
16633 "! TARGET_PARTIAL_REG_STALL && reload_completed
16634 && (GET_MODE (operands[0]) == HImode
16635 || (GET_MODE (operands[0]) == QImode
16636 && (TARGET_PROMOTE_QImode
16637 || optimize_insn_for_size_p ())))"
16638 [(parallel [(set (match_dup 0)
16639 (neg:SI (match_dup 1)))
16640 (clobber (reg:CC FLAGS_REG))])]
16641 "operands[0] = gen_lowpart (SImode, operands[0]);
16642 operands[1] = gen_lowpart (SImode, operands[1]);")
16645 [(set (match_operand 0 "register_operand" "")
16646 (not (match_operand 1 "register_operand" "")))]
16647 "! TARGET_PARTIAL_REG_STALL && reload_completed
16648 && (GET_MODE (operands[0]) == HImode
16649 || (GET_MODE (operands[0]) == QImode
16650 && (TARGET_PROMOTE_QImode
16651 || optimize_insn_for_size_p ())))"
16652 [(set (match_dup 0)
16653 (not:SI (match_dup 1)))]
16654 "operands[0] = gen_lowpart (SImode, operands[0]);
16655 operands[1] = gen_lowpart (SImode, operands[1]);")
16658 [(set (match_operand 0 "register_operand" "")
16659 (if_then_else (match_operator 1 "ordered_comparison_operator"
16660 [(reg FLAGS_REG) (const_int 0)])
16661 (match_operand 2 "register_operand" "")
16662 (match_operand 3 "register_operand" "")))]
16663 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16664 && (GET_MODE (operands[0]) == HImode
16665 || (GET_MODE (operands[0]) == QImode
16666 && (TARGET_PROMOTE_QImode
16667 || optimize_insn_for_size_p ())))"
16668 [(set (match_dup 0)
16669 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16670 "operands[0] = gen_lowpart (SImode, operands[0]);
16671 operands[2] = gen_lowpart (SImode, operands[2]);
16672 operands[3] = gen_lowpart (SImode, operands[3]);")
16674 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16675 ;; transform a complex memory operation into two memory to register operations.
16677 ;; Don't push memory operands
16679 [(set (match_operand:SWI 0 "push_operand" "")
16680 (match_operand:SWI 1 "memory_operand" ""))
16681 (match_scratch:SWI 2 "<r>")]
16682 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16683 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16684 [(set (match_dup 2) (match_dup 1))
16685 (set (match_dup 0) (match_dup 2))])
16687 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16690 [(set (match_operand:SF 0 "push_operand" "")
16691 (match_operand:SF 1 "memory_operand" ""))
16692 (match_scratch:SF 2 "r")]
16693 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16694 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16695 [(set (match_dup 2) (match_dup 1))
16696 (set (match_dup 0) (match_dup 2))])
16698 ;; Don't move an immediate directly to memory when the instruction
16701 [(match_scratch:SWI124 1 "<r>")
16702 (set (match_operand:SWI124 0 "memory_operand" "")
16704 "optimize_insn_for_speed_p ()
16705 && !TARGET_USE_MOV0
16706 && TARGET_SPLIT_LONG_MOVES
16707 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16708 && peep2_regno_dead_p (0, FLAGS_REG)"
16709 [(parallel [(set (match_dup 2) (const_int 0))
16710 (clobber (reg:CC FLAGS_REG))])
16711 (set (match_dup 0) (match_dup 1))]
16712 "operands[2] = gen_lowpart (SImode, operands[1]);")
16715 [(match_scratch:SWI124 2 "<r>")
16716 (set (match_operand:SWI124 0 "memory_operand" "")
16717 (match_operand:SWI124 1 "immediate_operand" ""))]
16718 "optimize_insn_for_speed_p ()
16719 && TARGET_SPLIT_LONG_MOVES
16720 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16721 [(set (match_dup 2) (match_dup 1))
16722 (set (match_dup 0) (match_dup 2))])
16724 ;; Don't compare memory with zero, load and use a test instead.
16726 [(set (match_operand 0 "flags_reg_operand" "")
16727 (match_operator 1 "compare_operator"
16728 [(match_operand:SI 2 "memory_operand" "")
16730 (match_scratch:SI 3 "r")]
16731 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16732 [(set (match_dup 3) (match_dup 2))
16733 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16735 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16736 ;; Don't split NOTs with a displacement operand, because resulting XOR
16737 ;; will not be pairable anyway.
16739 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16740 ;; represented using a modRM byte. The XOR replacement is long decoded,
16741 ;; so this split helps here as well.
16743 ;; Note: Can't do this as a regular split because we can't get proper
16744 ;; lifetime information then.
16747 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16748 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16749 "optimize_insn_for_speed_p ()
16750 && ((TARGET_NOT_UNPAIRABLE
16751 && (!MEM_P (operands[0])
16752 || !memory_displacement_operand (operands[0], <MODE>mode)))
16753 || (TARGET_NOT_VECTORMODE
16754 && long_memory_operand (operands[0], <MODE>mode)))
16755 && peep2_regno_dead_p (0, FLAGS_REG)"
16756 [(parallel [(set (match_dup 0)
16757 (xor:SWI124 (match_dup 1) (const_int -1)))
16758 (clobber (reg:CC FLAGS_REG))])])
16760 ;; Non pairable "test imm, reg" instructions can be translated to
16761 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16762 ;; byte opcode instead of two, have a short form for byte operands),
16763 ;; so do it for other CPUs as well. Given that the value was dead,
16764 ;; this should not create any new dependencies. Pass on the sub-word
16765 ;; versions if we're concerned about partial register stalls.
16768 [(set (match_operand 0 "flags_reg_operand" "")
16769 (match_operator 1 "compare_operator"
16770 [(and:SI (match_operand:SI 2 "register_operand" "")
16771 (match_operand:SI 3 "immediate_operand" ""))
16773 "ix86_match_ccmode (insn, CCNOmode)
16774 && (true_regnum (operands[2]) != AX_REG
16775 || satisfies_constraint_K (operands[3]))
16776 && peep2_reg_dead_p (1, operands[2])"
16778 [(set (match_dup 0)
16779 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16782 (and:SI (match_dup 2) (match_dup 3)))])])
16784 ;; We don't need to handle HImode case, because it will be promoted to SImode
16785 ;; on ! TARGET_PARTIAL_REG_STALL
16788 [(set (match_operand 0 "flags_reg_operand" "")
16789 (match_operator 1 "compare_operator"
16790 [(and:QI (match_operand:QI 2 "register_operand" "")
16791 (match_operand:QI 3 "immediate_operand" ""))
16793 "! TARGET_PARTIAL_REG_STALL
16794 && ix86_match_ccmode (insn, CCNOmode)
16795 && true_regnum (operands[2]) != AX_REG
16796 && peep2_reg_dead_p (1, operands[2])"
16798 [(set (match_dup 0)
16799 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16802 (and:QI (match_dup 2) (match_dup 3)))])])
16805 [(set (match_operand 0 "flags_reg_operand" "")
16806 (match_operator 1 "compare_operator"
16809 (match_operand 2 "ext_register_operand" "")
16812 (match_operand 3 "const_int_operand" ""))
16814 "! TARGET_PARTIAL_REG_STALL
16815 && ix86_match_ccmode (insn, CCNOmode)
16816 && true_regnum (operands[2]) != AX_REG
16817 && peep2_reg_dead_p (1, operands[2])"
16818 [(parallel [(set (match_dup 0)
16827 (set (zero_extract:SI (match_dup 2)
16835 (match_dup 3)))])])
16837 ;; Don't do logical operations with memory inputs.
16839 [(match_scratch:SI 2 "r")
16840 (parallel [(set (match_operand:SI 0 "register_operand" "")
16841 (match_operator:SI 3 "arith_or_logical_operator"
16843 (match_operand:SI 1 "memory_operand" "")]))
16844 (clobber (reg:CC FLAGS_REG))])]
16845 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16846 [(set (match_dup 2) (match_dup 1))
16847 (parallel [(set (match_dup 0)
16848 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16849 (clobber (reg:CC FLAGS_REG))])])
16852 [(match_scratch:SI 2 "r")
16853 (parallel [(set (match_operand:SI 0 "register_operand" "")
16854 (match_operator:SI 3 "arith_or_logical_operator"
16855 [(match_operand:SI 1 "memory_operand" "")
16857 (clobber (reg:CC FLAGS_REG))])]
16858 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16859 [(set (match_dup 2) (match_dup 1))
16860 (parallel [(set (match_dup 0)
16861 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16862 (clobber (reg:CC FLAGS_REG))])])
16864 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16865 ;; refers to the destination of the load!
16868 [(set (match_operand:SI 0 "register_operand" "")
16869 (match_operand:SI 1 "register_operand" ""))
16870 (parallel [(set (match_dup 0)
16871 (match_operator:SI 3 "commutative_operator"
16873 (match_operand:SI 2 "memory_operand" "")]))
16874 (clobber (reg:CC FLAGS_REG))])]
16875 "REGNO (operands[0]) != REGNO (operands[1])
16876 && GENERAL_REGNO_P (REGNO (operands[0]))
16877 && GENERAL_REGNO_P (REGNO (operands[1]))"
16878 [(set (match_dup 0) (match_dup 4))
16879 (parallel [(set (match_dup 0)
16880 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16881 (clobber (reg:CC FLAGS_REG))])]
16882 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16885 [(set (match_operand 0 "register_operand" "")
16886 (match_operand 1 "register_operand" ""))
16888 (match_operator 3 "commutative_operator"
16890 (match_operand 2 "memory_operand" "")]))]
16891 "REGNO (operands[0]) != REGNO (operands[1])
16892 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16893 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16894 [(set (match_dup 0) (match_dup 2))
16896 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16898 ; Don't do logical operations with memory outputs
16900 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16901 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16902 ; the same decoder scheduling characteristics as the original.
16905 [(match_scratch:SI 2 "r")
16906 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16907 (match_operator:SI 3 "arith_or_logical_operator"
16909 (match_operand:SI 1 "nonmemory_operand" "")]))
16910 (clobber (reg:CC FLAGS_REG))])]
16911 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16912 /* Do not split stack checking probes. */
16913 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16914 [(set (match_dup 2) (match_dup 0))
16915 (parallel [(set (match_dup 2)
16916 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16917 (clobber (reg:CC FLAGS_REG))])
16918 (set (match_dup 0) (match_dup 2))])
16921 [(match_scratch:SI 2 "r")
16922 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16923 (match_operator:SI 3 "arith_or_logical_operator"
16924 [(match_operand:SI 1 "nonmemory_operand" "")
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16928 /* Do not split stack checking probes. */
16929 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16930 [(set (match_dup 2) (match_dup 0))
16931 (parallel [(set (match_dup 2)
16932 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16933 (clobber (reg:CC FLAGS_REG))])
16934 (set (match_dup 0) (match_dup 2))])
16936 ;; Attempt to use arith or logical operations with memory outputs with
16937 ;; setting of flags.
16939 [(set (match_operand:SWI 0 "register_operand" "")
16940 (match_operand:SWI 1 "memory_operand" ""))
16941 (parallel [(set (match_dup 0)
16942 (match_operator:SWI 3 "plusminuslogic_operator"
16944 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16945 (clobber (reg:CC FLAGS_REG))])
16946 (set (match_dup 1) (match_dup 0))
16947 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16948 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16949 && peep2_reg_dead_p (4, operands[0])
16950 && !reg_overlap_mentioned_p (operands[0], operands[1])
16951 && ix86_match_ccmode (peep2_next_insn (3),
16952 (GET_CODE (operands[3]) == PLUS
16953 || GET_CODE (operands[3]) == MINUS)
16954 ? CCGOCmode : CCNOmode)"
16955 [(parallel [(set (match_dup 4) (match_dup 5))
16956 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16957 (match_dup 2)]))])]
16958 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16959 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16960 copy_rtx (operands[1]),
16961 copy_rtx (operands[2]));
16962 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16963 operands[5], const0_rtx);")
16966 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16967 (match_operator:SWI 2 "plusminuslogic_operator"
16969 (match_operand:SWI 1 "memory_operand" "")]))
16970 (clobber (reg:CC FLAGS_REG))])
16971 (set (match_dup 1) (match_dup 0))
16972 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16973 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16974 && GET_CODE (operands[2]) != MINUS
16975 && peep2_reg_dead_p (3, operands[0])
16976 && !reg_overlap_mentioned_p (operands[0], operands[1])
16977 && ix86_match_ccmode (peep2_next_insn (2),
16978 GET_CODE (operands[2]) == PLUS
16979 ? CCGOCmode : CCNOmode)"
16980 [(parallel [(set (match_dup 3) (match_dup 4))
16981 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16982 (match_dup 0)]))])]
16983 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16984 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16985 copy_rtx (operands[1]),
16986 copy_rtx (operands[0]));
16987 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16988 operands[4], const0_rtx);")
16991 [(set (match_operand:SWI12 0 "register_operand" "")
16992 (match_operand:SWI12 1 "memory_operand" ""))
16993 (parallel [(set (match_operand:SI 4 "register_operand" "")
16994 (match_operator:SI 3 "plusminuslogic_operator"
16996 (match_operand:SI 2 "nonmemory_operand" "")]))
16997 (clobber (reg:CC FLAGS_REG))])
16998 (set (match_dup 1) (match_dup 0))
16999 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17000 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17001 && REG_P (operands[0]) && REG_P (operands[4])
17002 && REGNO (operands[0]) == REGNO (operands[4])
17003 && peep2_reg_dead_p (4, operands[0])
17004 && !reg_overlap_mentioned_p (operands[0], operands[1])
17005 && ix86_match_ccmode (peep2_next_insn (3),
17006 (GET_CODE (operands[3]) == PLUS
17007 || GET_CODE (operands[3]) == MINUS)
17008 ? CCGOCmode : CCNOmode)"
17009 [(parallel [(set (match_dup 4) (match_dup 5))
17010 (set (match_dup 1) (match_dup 6))])]
17011 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17012 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17013 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17014 copy_rtx (operands[1]), operands[2]);
17015 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17016 operands[5], const0_rtx);
17017 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17018 copy_rtx (operands[1]),
17019 copy_rtx (operands[2]));")
17021 ;; Attempt to always use XOR for zeroing registers.
17023 [(set (match_operand 0 "register_operand" "")
17024 (match_operand 1 "const0_operand" ""))]
17025 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17026 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17027 && GENERAL_REG_P (operands[0])
17028 && peep2_regno_dead_p (0, FLAGS_REG)"
17029 [(parallel [(set (match_dup 0) (const_int 0))
17030 (clobber (reg:CC FLAGS_REG))])]
17031 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17034 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17036 "(GET_MODE (operands[0]) == QImode
17037 || GET_MODE (operands[0]) == HImode)
17038 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17039 && peep2_regno_dead_p (0, FLAGS_REG)"
17040 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17041 (clobber (reg:CC FLAGS_REG))])])
17043 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17045 [(set (match_operand:SWI248 0 "register_operand" "")
17047 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17048 && peep2_regno_dead_p (0, FLAGS_REG)"
17049 [(parallel [(set (match_dup 0) (const_int -1))
17050 (clobber (reg:CC FLAGS_REG))])]
17052 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17053 operands[0] = gen_lowpart (SImode, operands[0]);
17056 ;; Attempt to convert simple lea to add/shift.
17057 ;; These can be created by move expanders.
17060 [(set (match_operand:SWI48 0 "register_operand" "")
17061 (plus:SWI48 (match_dup 0)
17062 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17063 "peep2_regno_dead_p (0, FLAGS_REG)"
17064 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17065 (clobber (reg:CC FLAGS_REG))])])
17068 [(set (match_operand:SI 0 "register_operand" "")
17069 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17070 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17072 && peep2_regno_dead_p (0, FLAGS_REG)
17073 && REGNO (operands[0]) == REGNO (operands[1])"
17074 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17075 (clobber (reg:CC FLAGS_REG))])]
17076 "operands[2] = gen_lowpart (SImode, operands[2]);")
17079 [(set (match_operand:SWI48 0 "register_operand" "")
17080 (mult:SWI48 (match_dup 0)
17081 (match_operand:SWI48 1 "const_int_operand" "")))]
17082 "exact_log2 (INTVAL (operands[1])) >= 0
17083 && peep2_regno_dead_p (0, FLAGS_REG)"
17084 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17085 (clobber (reg:CC FLAGS_REG))])]
17086 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17089 [(set (match_operand:SI 0 "register_operand" "")
17090 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17091 (match_operand:DI 2 "const_int_operand" "")) 0))]
17093 && exact_log2 (INTVAL (operands[2])) >= 0
17094 && REGNO (operands[0]) == REGNO (operands[1])
17095 && peep2_regno_dead_p (0, FLAGS_REG)"
17096 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17100 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17101 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17102 ;; On many CPUs it is also faster, since special hardware to avoid esp
17103 ;; dependencies is present.
17105 ;; While some of these conversions may be done using splitters, we use
17106 ;; peepholes in order to allow combine_stack_adjustments pass to see
17107 ;; nonobfuscated RTL.
17109 ;; Convert prologue esp subtractions to push.
17110 ;; We need register to push. In order to keep verify_flow_info happy we have
17112 ;; - use scratch and clobber it in order to avoid dependencies
17113 ;; - use already live register
17114 ;; We can't use the second way right now, since there is no reliable way how to
17115 ;; verify that given register is live. First choice will also most likely in
17116 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17117 ;; call clobbered registers are dead. We may want to use base pointer as an
17118 ;; alternative when no register is available later.
17121 [(match_scratch:P 1 "r")
17122 (parallel [(set (reg:P SP_REG)
17123 (plus:P (reg:P SP_REG)
17124 (match_operand:P 0 "const_int_operand" "")))
17125 (clobber (reg:CC FLAGS_REG))
17126 (clobber (mem:BLK (scratch)))])]
17127 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17128 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17129 [(clobber (match_dup 1))
17130 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17131 (clobber (mem:BLK (scratch)))])])
17134 [(match_scratch:P 1 "r")
17135 (parallel [(set (reg:P SP_REG)
17136 (plus:P (reg:P SP_REG)
17137 (match_operand:P 0 "const_int_operand" "")))
17138 (clobber (reg:CC FLAGS_REG))
17139 (clobber (mem:BLK (scratch)))])]
17140 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17141 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17142 [(clobber (match_dup 1))
17143 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17144 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17145 (clobber (mem:BLK (scratch)))])])
17147 ;; Convert esp subtractions to push.
17149 [(match_scratch:P 1 "r")
17150 (parallel [(set (reg:P SP_REG)
17151 (plus:P (reg:P SP_REG)
17152 (match_operand:P 0 "const_int_operand" "")))
17153 (clobber (reg:CC FLAGS_REG))])]
17154 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17155 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17156 [(clobber (match_dup 1))
17157 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17160 [(match_scratch:P 1 "r")
17161 (parallel [(set (reg:P SP_REG)
17162 (plus:P (reg:P SP_REG)
17163 (match_operand:P 0 "const_int_operand" "")))
17164 (clobber (reg:CC FLAGS_REG))])]
17165 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17166 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17167 [(clobber (match_dup 1))
17168 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17169 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17171 ;; Convert epilogue deallocator to pop.
17173 [(match_scratch:P 1 "r")
17174 (parallel [(set (reg:P SP_REG)
17175 (plus:P (reg:P SP_REG)
17176 (match_operand:P 0 "const_int_operand" "")))
17177 (clobber (reg:CC FLAGS_REG))
17178 (clobber (mem:BLK (scratch)))])]
17179 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17180 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17181 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17182 (clobber (mem:BLK (scratch)))])])
17184 ;; Two pops case is tricky, since pop causes dependency
17185 ;; on destination register. We use two registers if available.
17187 [(match_scratch:P 1 "r")
17188 (match_scratch:P 2 "r")
17189 (parallel [(set (reg:P SP_REG)
17190 (plus:P (reg:P SP_REG)
17191 (match_operand:P 0 "const_int_operand" "")))
17192 (clobber (reg:CC FLAGS_REG))
17193 (clobber (mem:BLK (scratch)))])]
17194 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17195 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17196 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17197 (clobber (mem:BLK (scratch)))])
17198 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17201 [(match_scratch:P 1 "r")
17202 (parallel [(set (reg:P SP_REG)
17203 (plus:P (reg:P SP_REG)
17204 (match_operand:P 0 "const_int_operand" "")))
17205 (clobber (reg:CC FLAGS_REG))
17206 (clobber (mem:BLK (scratch)))])]
17207 "optimize_insn_for_size_p ()
17208 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17209 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17210 (clobber (mem:BLK (scratch)))])
17211 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17213 ;; Convert esp additions to pop.
17215 [(match_scratch:P 1 "r")
17216 (parallel [(set (reg:P SP_REG)
17217 (plus:P (reg:P SP_REG)
17218 (match_operand:P 0 "const_int_operand" "")))
17219 (clobber (reg:CC FLAGS_REG))])]
17220 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17221 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17223 ;; Two pops case is tricky, since pop causes dependency
17224 ;; on destination register. We use two registers if available.
17226 [(match_scratch:P 1 "r")
17227 (match_scratch:P 2 "r")
17228 (parallel [(set (reg:P SP_REG)
17229 (plus:P (reg:P SP_REG)
17230 (match_operand:P 0 "const_int_operand" "")))
17231 (clobber (reg:CC FLAGS_REG))])]
17232 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17233 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17234 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17237 [(match_scratch:P 1 "r")
17238 (parallel [(set (reg:P SP_REG)
17239 (plus:P (reg:P SP_REG)
17240 (match_operand:P 0 "const_int_operand" "")))
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "optimize_insn_for_size_p ()
17243 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17244 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17245 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17247 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17248 ;; required and register dies. Similarly for 128 to -128.
17250 [(set (match_operand 0 "flags_reg_operand" "")
17251 (match_operator 1 "compare_operator"
17252 [(match_operand 2 "register_operand" "")
17253 (match_operand 3 "const_int_operand" "")]))]
17254 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17255 && incdec_operand (operands[3], GET_MODE (operands[3])))
17256 || (!TARGET_FUSE_CMP_AND_BRANCH
17257 && INTVAL (operands[3]) == 128))
17258 && ix86_match_ccmode (insn, CCGCmode)
17259 && peep2_reg_dead_p (1, operands[2])"
17260 [(parallel [(set (match_dup 0)
17261 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17262 (clobber (match_dup 2))])])
17264 ;; Convert imul by three, five and nine into lea
17267 [(set (match_operand:SWI48 0 "register_operand" "")
17268 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17269 (match_operand:SWI48 2 "const359_operand" "")))
17270 (clobber (reg:CC FLAGS_REG))])]
17271 "!TARGET_PARTIAL_REG_STALL
17272 || <MODE>mode == SImode
17273 || optimize_function_for_size_p (cfun)"
17274 [(set (match_dup 0)
17275 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17277 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17281 [(set (match_operand:SWI48 0 "register_operand" "")
17282 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17283 (match_operand:SWI48 2 "const359_operand" "")))
17284 (clobber (reg:CC FLAGS_REG))])]
17285 "optimize_insn_for_speed_p ()
17286 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17287 [(set (match_dup 0) (match_dup 1))
17289 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17291 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17293 ;; imul $32bit_imm, mem, reg is vector decoded, while
17294 ;; imul $32bit_imm, reg, reg is direct decoded.
17296 [(match_scratch:SWI48 3 "r")
17297 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17298 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17299 (match_operand:SWI48 2 "immediate_operand" "")))
17300 (clobber (reg:CC FLAGS_REG))])]
17301 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17302 && !satisfies_constraint_K (operands[2])"
17303 [(set (match_dup 3) (match_dup 1))
17304 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17305 (clobber (reg:CC FLAGS_REG))])])
17308 [(match_scratch:SI 3 "r")
17309 (parallel [(set (match_operand:DI 0 "register_operand" "")
17311 (mult:SI (match_operand:SI 1 "memory_operand" "")
17312 (match_operand:SI 2 "immediate_operand" ""))))
17313 (clobber (reg:CC FLAGS_REG))])]
17315 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17316 && !satisfies_constraint_K (operands[2])"
17317 [(set (match_dup 3) (match_dup 1))
17318 (parallel [(set (match_dup 0)
17319 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17320 (clobber (reg:CC FLAGS_REG))])])
17322 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17323 ;; Convert it into imul reg, reg
17324 ;; It would be better to force assembler to encode instruction using long
17325 ;; immediate, but there is apparently no way to do so.
17327 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17329 (match_operand:SWI248 1 "nonimmediate_operand" "")
17330 (match_operand:SWI248 2 "const_int_operand" "")))
17331 (clobber (reg:CC FLAGS_REG))])
17332 (match_scratch:SWI248 3 "r")]
17333 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17334 && satisfies_constraint_K (operands[2])"
17335 [(set (match_dup 3) (match_dup 2))
17336 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17337 (clobber (reg:CC FLAGS_REG))])]
17339 if (!rtx_equal_p (operands[0], operands[1]))
17340 emit_move_insn (operands[0], operands[1]);
17343 ;; After splitting up read-modify operations, array accesses with memory
17344 ;; operands might end up in form:
17346 ;; movl 4(%esp), %edx
17348 ;; instead of pre-splitting:
17350 ;; addl 4(%esp), %eax
17352 ;; movl 4(%esp), %edx
17353 ;; leal (%edx,%eax,4), %eax
17356 [(match_scratch:P 5 "r")
17357 (parallel [(set (match_operand 0 "register_operand" "")
17358 (ashift (match_operand 1 "register_operand" "")
17359 (match_operand 2 "const_int_operand" "")))
17360 (clobber (reg:CC FLAGS_REG))])
17361 (parallel [(set (match_operand 3 "register_operand" "")
17362 (plus (match_dup 0)
17363 (match_operand 4 "x86_64_general_operand" "")))
17364 (clobber (reg:CC FLAGS_REG))])]
17365 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17366 /* Validate MODE for lea. */
17367 && ((!TARGET_PARTIAL_REG_STALL
17368 && (GET_MODE (operands[0]) == QImode
17369 || GET_MODE (operands[0]) == HImode))
17370 || GET_MODE (operands[0]) == SImode
17371 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17372 && (rtx_equal_p (operands[0], operands[3])
17373 || peep2_reg_dead_p (2, operands[0]))
17374 /* We reorder load and the shift. */
17375 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17376 [(set (match_dup 5) (match_dup 4))
17377 (set (match_dup 0) (match_dup 1))]
17379 enum machine_mode op1mode = GET_MODE (operands[1]);
17380 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17381 int scale = 1 << INTVAL (operands[2]);
17382 rtx index = gen_lowpart (Pmode, operands[1]);
17383 rtx base = gen_lowpart (Pmode, operands[5]);
17384 rtx dest = gen_lowpart (mode, operands[3]);
17386 operands[1] = gen_rtx_PLUS (Pmode, base,
17387 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17388 operands[5] = base;
17390 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17391 if (op1mode != Pmode)
17392 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17393 operands[0] = dest;
17396 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17397 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17398 ;; caught for use by garbage collectors and the like. Using an insn that
17399 ;; maps to SIGILL makes it more likely the program will rightfully die.
17400 ;; Keeping with tradition, "6" is in honor of #UD.
17401 (define_insn "trap"
17402 [(trap_if (const_int 1) (const_int 6))]
17404 { return ASM_SHORT "0x0b0f"; }
17405 [(set_attr "length" "2")])
17407 (define_expand "prefetch"
17408 [(prefetch (match_operand 0 "address_operand" "")
17409 (match_operand:SI 1 "const_int_operand" "")
17410 (match_operand:SI 2 "const_int_operand" ""))]
17411 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17413 int rw = INTVAL (operands[1]);
17414 int locality = INTVAL (operands[2]);
17416 gcc_assert (rw == 0 || rw == 1);
17417 gcc_assert (locality >= 0 && locality <= 3);
17418 gcc_assert (GET_MODE (operands[0]) == Pmode
17419 || GET_MODE (operands[0]) == VOIDmode);
17421 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17422 supported by SSE counterpart or the SSE prefetch is not available
17423 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17425 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17426 operands[2] = GEN_INT (3);
17428 operands[1] = const0_rtx;
17431 (define_insn "*prefetch_sse_<mode>"
17432 [(prefetch (match_operand:P 0 "address_operand" "p")
17434 (match_operand:SI 1 "const_int_operand" ""))]
17435 "TARGET_PREFETCH_SSE"
17437 static const char * const patterns[4] = {
17438 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17441 int locality = INTVAL (operands[1]);
17442 gcc_assert (locality >= 0 && locality <= 3);
17444 return patterns[locality];
17446 [(set_attr "type" "sse")
17447 (set_attr "atom_sse_attr" "prefetch")
17448 (set (attr "length_address")
17449 (symbol_ref "memory_address_length (operands[0])"))
17450 (set_attr "memory" "none")])
17452 (define_insn "*prefetch_3dnow_<mode>"
17453 [(prefetch (match_operand:P 0 "address_operand" "p")
17454 (match_operand:SI 1 "const_int_operand" "n")
17458 if (INTVAL (operands[1]) == 0)
17459 return "prefetch\t%a0";
17461 return "prefetchw\t%a0";
17463 [(set_attr "type" "mmx")
17464 (set (attr "length_address")
17465 (symbol_ref "memory_address_length (operands[0])"))
17466 (set_attr "memory" "none")])
17468 (define_expand "stack_protect_set"
17469 [(match_operand 0 "memory_operand" "")
17470 (match_operand 1 "memory_operand" "")]
17473 rtx (*insn)(rtx, rtx);
17475 #ifdef TARGET_THREAD_SSP_OFFSET
17476 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17477 insn = (TARGET_LP64
17478 ? gen_stack_tls_protect_set_di
17479 : gen_stack_tls_protect_set_si);
17481 insn = (TARGET_LP64
17482 ? gen_stack_protect_set_di
17483 : gen_stack_protect_set_si);
17486 emit_insn (insn (operands[0], operands[1]));
17490 (define_insn "stack_protect_set_<mode>"
17491 [(set (match_operand:PTR 0 "memory_operand" "=m")
17492 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17494 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17495 (clobber (reg:CC FLAGS_REG))]
17497 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17498 [(set_attr "type" "multi")])
17500 (define_insn "stack_tls_protect_set_<mode>"
17501 [(set (match_operand:PTR 0 "memory_operand" "=m")
17502 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17503 UNSPEC_SP_TLS_SET))
17504 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17505 (clobber (reg:CC FLAGS_REG))]
17507 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17508 [(set_attr "type" "multi")])
17510 (define_expand "stack_protect_test"
17511 [(match_operand 0 "memory_operand" "")
17512 (match_operand 1 "memory_operand" "")
17513 (match_operand 2 "" "")]
17516 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17518 rtx (*insn)(rtx, rtx, rtx);
17520 #ifdef TARGET_THREAD_SSP_OFFSET
17521 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17522 insn = (TARGET_LP64
17523 ? gen_stack_tls_protect_test_di
17524 : gen_stack_tls_protect_test_si);
17526 insn = (TARGET_LP64
17527 ? gen_stack_protect_test_di
17528 : gen_stack_protect_test_si);
17531 emit_insn (insn (flags, operands[0], operands[1]));
17533 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17534 flags, const0_rtx, operands[2]));
17538 (define_insn "stack_protect_test_<mode>"
17539 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17540 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17541 (match_operand:PTR 2 "memory_operand" "m")]
17543 (clobber (match_scratch:PTR 3 "=&r"))]
17545 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17546 [(set_attr "type" "multi")])
17548 (define_insn "stack_tls_protect_test_<mode>"
17549 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17550 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17551 (match_operand:PTR 2 "const_int_operand" "i")]
17552 UNSPEC_SP_TLS_TEST))
17553 (clobber (match_scratch:PTR 3 "=r"))]
17555 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17556 [(set_attr "type" "multi")])
17558 (define_insn "sse4_2_crc32<mode>"
17559 [(set (match_operand:SI 0 "register_operand" "=r")
17561 [(match_operand:SI 1 "register_operand" "0")
17562 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17564 "TARGET_SSE4_2 || TARGET_CRC32"
17565 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17566 [(set_attr "type" "sselog1")
17567 (set_attr "prefix_rep" "1")
17568 (set_attr "prefix_extra" "1")
17569 (set (attr "prefix_data16")
17570 (if_then_else (match_operand:HI 2 "" "")
17572 (const_string "*")))
17573 (set (attr "prefix_rex")
17574 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17576 (const_string "*")))
17577 (set_attr "mode" "SI")])
17579 (define_insn "sse4_2_crc32di"
17580 [(set (match_operand:DI 0 "register_operand" "=r")
17582 [(match_operand:DI 1 "register_operand" "0")
17583 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17585 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17586 "crc32{q}\t{%2, %0|%0, %2}"
17587 [(set_attr "type" "sselog1")
17588 (set_attr "prefix_rep" "1")
17589 (set_attr "prefix_extra" "1")
17590 (set_attr "mode" "DI")])
17592 (define_expand "rdpmc"
17593 [(match_operand:DI 0 "register_operand" "")
17594 (match_operand:SI 1 "register_operand" "")]
17597 rtx reg = gen_reg_rtx (DImode);
17600 /* Force operand 1 into ECX. */
17601 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17602 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17603 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17608 rtvec vec = rtvec_alloc (2);
17609 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17610 rtx upper = gen_reg_rtx (DImode);
17611 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17612 gen_rtvec (1, const0_rtx),
17614 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17615 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17617 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17618 NULL, 1, OPTAB_DIRECT);
17619 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17623 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17624 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17628 (define_insn "*rdpmc"
17629 [(set (match_operand:DI 0 "register_operand" "=A")
17630 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17634 [(set_attr "type" "other")
17635 (set_attr "length" "2")])
17637 (define_insn "*rdpmc_rex64"
17638 [(set (match_operand:DI 0 "register_operand" "=a")
17639 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17641 (set (match_operand:DI 1 "register_operand" "=d")
17642 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17645 [(set_attr "type" "other")
17646 (set_attr "length" "2")])
17648 (define_expand "rdtsc"
17649 [(set (match_operand:DI 0 "register_operand" "")
17650 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17655 rtvec vec = rtvec_alloc (2);
17656 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17657 rtx upper = gen_reg_rtx (DImode);
17658 rtx lower = gen_reg_rtx (DImode);
17659 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17660 gen_rtvec (1, const0_rtx),
17662 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17663 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17665 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17666 NULL, 1, OPTAB_DIRECT);
17667 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17674 (define_insn "*rdtsc"
17675 [(set (match_operand:DI 0 "register_operand" "=A")
17676 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17679 [(set_attr "type" "other")
17680 (set_attr "length" "2")])
17682 (define_insn "*rdtsc_rex64"
17683 [(set (match_operand:DI 0 "register_operand" "=a")
17684 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17685 (set (match_operand:DI 1 "register_operand" "=d")
17686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17689 [(set_attr "type" "other")
17690 (set_attr "length" "2")])
17692 (define_expand "rdtscp"
17693 [(match_operand:DI 0 "register_operand" "")
17694 (match_operand:SI 1 "memory_operand" "")]
17697 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17698 gen_rtvec (1, const0_rtx),
17700 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17701 gen_rtvec (1, const0_rtx),
17703 rtx reg = gen_reg_rtx (DImode);
17704 rtx tmp = gen_reg_rtx (SImode);
17708 rtvec vec = rtvec_alloc (3);
17709 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17710 rtx upper = gen_reg_rtx (DImode);
17711 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17712 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17713 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17715 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17716 NULL, 1, OPTAB_DIRECT);
17717 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17722 rtvec vec = rtvec_alloc (2);
17723 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17724 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17725 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17728 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17729 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17733 (define_insn "*rdtscp"
17734 [(set (match_operand:DI 0 "register_operand" "=A")
17735 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17736 (set (match_operand:SI 1 "register_operand" "=c")
17737 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17740 [(set_attr "type" "other")
17741 (set_attr "length" "3")])
17743 (define_insn "*rdtscp_rex64"
17744 [(set (match_operand:DI 0 "register_operand" "=a")
17745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17746 (set (match_operand:DI 1 "register_operand" "=d")
17747 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17748 (set (match_operand:SI 2 "register_operand" "=c")
17749 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17752 [(set_attr "type" "other")
17753 (set_attr "length" "3")])
17755 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17757 ;; LWP instructions
17759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17761 (define_expand "lwp_llwpcb"
17762 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17763 UNSPECV_LLWP_INTRINSIC)]
17766 (define_insn "*lwp_llwpcb<mode>1"
17767 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17768 UNSPECV_LLWP_INTRINSIC)]
17771 [(set_attr "type" "lwp")
17772 (set_attr "mode" "<MODE>")
17773 (set_attr "length" "5")])
17775 (define_expand "lwp_slwpcb"
17776 [(set (match_operand 0 "register_operand" "=r")
17777 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17782 insn = (TARGET_64BIT
17784 : gen_lwp_slwpcbsi);
17786 emit_insn (insn (operands[0]));
17790 (define_insn "lwp_slwpcb<mode>"
17791 [(set (match_operand:P 0 "register_operand" "=r")
17792 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17795 [(set_attr "type" "lwp")
17796 (set_attr "mode" "<MODE>")
17797 (set_attr "length" "5")])
17799 (define_expand "lwp_lwpval<mode>3"
17800 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17801 (match_operand:SI 2 "nonimmediate_operand" "rm")
17802 (match_operand:SI 3 "const_int_operand" "i")]
17803 UNSPECV_LWPVAL_INTRINSIC)]
17805 "/* Avoid unused variable warning. */
17808 (define_insn "*lwp_lwpval<mode>3_1"
17809 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17810 (match_operand:SI 1 "nonimmediate_operand" "rm")
17811 (match_operand:SI 2 "const_int_operand" "i")]
17812 UNSPECV_LWPVAL_INTRINSIC)]
17814 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17815 [(set_attr "type" "lwp")
17816 (set_attr "mode" "<MODE>")
17817 (set (attr "length")
17818 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17820 (define_expand "lwp_lwpins<mode>3"
17821 [(set (reg:CCC FLAGS_REG)
17822 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17823 (match_operand:SI 2 "nonimmediate_operand" "rm")
17824 (match_operand:SI 3 "const_int_operand" "i")]
17825 UNSPECV_LWPINS_INTRINSIC))
17826 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17827 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17830 (define_insn "*lwp_lwpins<mode>3_1"
17831 [(set (reg:CCC FLAGS_REG)
17832 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17833 (match_operand:SI 1 "nonimmediate_operand" "rm")
17834 (match_operand:SI 2 "const_int_operand" "i")]
17835 UNSPECV_LWPINS_INTRINSIC))]
17837 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17838 [(set_attr "type" "lwp")
17839 (set_attr "mode" "<MODE>")
17840 (set (attr "length")
17841 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17843 (define_insn "rdfsbase<mode>"
17844 [(set (match_operand:SWI48 0 "register_operand" "=r")
17845 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17846 "TARGET_64BIT && TARGET_FSGSBASE"
17848 [(set_attr "type" "other")
17849 (set_attr "prefix_extra" "2")])
17851 (define_insn "rdgsbase<mode>"
17852 [(set (match_operand:SWI48 0 "register_operand" "=r")
17853 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17854 "TARGET_64BIT && TARGET_FSGSBASE"
17856 [(set_attr "type" "other")
17857 (set_attr "prefix_extra" "2")])
17859 (define_insn "wrfsbase<mode>"
17860 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17862 "TARGET_64BIT && TARGET_FSGSBASE"
17864 [(set_attr "type" "other")
17865 (set_attr "prefix_extra" "2")])
17867 (define_insn "wrgsbase<mode>"
17868 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17870 "TARGET_64BIT && TARGET_FSGSBASE"
17872 [(set_attr "type" "other")
17873 (set_attr "prefix_extra" "2")])
17875 (define_insn "rdrand<mode>_1"
17876 [(set (match_operand:SWI248 0 "register_operand" "=r")
17877 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17878 (set (reg:CCC FLAGS_REG)
17879 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17882 [(set_attr "type" "other")
17883 (set_attr "prefix_extra" "1")])
17885 (define_expand "pause"
17886 [(set (match_dup 0)
17887 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17890 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17891 MEM_VOLATILE_P (operands[0]) = 1;
17894 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17895 ;; They have the same encoding.
17896 (define_insn "*pause"
17897 [(set (match_operand:BLK 0 "" "")
17898 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17901 [(set_attr "length" "2")
17902 (set_attr "memory" "unknown")])
17906 (include "sync.md")