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 "i") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (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 "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 "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 "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 "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")
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
955 ;; Scheduling descriptions
957 (include "pentium.md")
960 (include "athlon.md")
961 (include "bdver1.md")
967 ;; Operand and operator predicates and constraints
969 (include "predicates.md")
970 (include "constraints.md")
973 ;; Compare and branch/compare and store instructions.
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1049 (match_operand:QI 0 "general_operand" "Qm")
1052 (match_operand 1 "ext_register_operand" "Q")
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1063 (match_operand:QI 0 "register_operand" "Q")
1066 (match_operand 1 "ext_register_operand" "Q")
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1094 (match_operand 0 "ext_register_operand" "")
1097 (match_operand:QI 1 "immediate_operand" "")))])
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1119 (match_operand 0 "ext_register_operand" "Q")
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1134 (match_operand 0 "ext_register_operand" "Q")
1139 (match_operand 1 "ext_register_operand" "Q")
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1160 (label_ref (match_operand 3 "" ""))
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1192 (label_ref (match_operand 3 "" ""))
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))])
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1293 (cond [(match_operand:SF 1 "" "")
1295 (match_operand:DF 1 "" "")
1298 (const_string "XF")))])
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354 && TARGET_SAHF && !TARGET_CMOVE"
1356 "&& reload_completed"
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1381 (cond [(match_operand:SF 1 "" "")
1383 (match_operand:DF 1 "" "")
1386 (const_string "XF")))])
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398 "&& reload_completed"
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))])
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1445 "&& reload_completed"
1450 (match_op_dup 3 [(match_dup 2)]))]
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1481 #ifndef HAVE_AS_IX86_SAHF
1483 return ASM_BYTE "0x9e";
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1517 (eq_attr "mode" "DF")
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1559 (cond [(match_operand:SF 1 "" "")
1561 (match_operand:DF 1 "" "")
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1590 (eq_attr "mode" "DF")
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1609 (if_then_else (match_operand:SF 1 "" "")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1632 (cond [(match_operand:SF 1 "" "")
1634 (match_operand:DF 1 "" "")
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1656 "ix86_split_long_move (operands); DONE;")
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1722 "ix86_split_long_move (operands); DONE;")
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 ;; Move instructions.
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1785 "ix86_expand_move (OImode, operands); DONE;")
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1797 ix86_expand_vector_move (TImode, operands);
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1813 emit_move_complex_parts (operands[0], operands[1]);
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1849 switch (which_alternative)
1852 return standard_sse_constant_opcode (insn, operands[1]);
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 switch (which_alternative)
1879 return standard_sse_constant_opcode (insn, operands[1]);
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1906 (cond [(eq_attr "alternative" "2,3")
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1928 "ix86_split_long_move (operands); DONE;")
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 switch (which_alternative)
1939 return standard_sse_constant_opcode (insn, operands[1]);
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1989 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1998 return "%vmovq\t{%1, %0|%0, %1}";
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "movd\t{%1, %0|%0, %1}";
2005 return "movq\t{%1, %0|%0, %1}";
2008 return standard_sse_constant_opcode (insn, operands[1]);
2011 return "pxor\t%0, %0";
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2026 return "mov{q}\t{%1, %0|%0, %1}";
2030 (cond [(eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (eq_attr "alternative" "5")
2033 (const_string "mmx")
2034 (eq_attr "alternative" "6,7,8,9")
2035 (const_string "mmxmov")
2036 (eq_attr "alternative" "10")
2037 (const_string "sselog1")
2038 (eq_attr "alternative" "11,12,13,14,15")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "16,17")
2041 (const_string "ssecvt")
2042 (match_operand:DI 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2045 (const_string "imov")))
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "8,9")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "11")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2112 switch (get_attr_type (insn))
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2118 return "movdq2q\t{%1, %0|%0, %1}";
2121 switch (get_attr_mode (insn))
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2126 return "%vmovq\t{%1, %0|%0, %1}";
2128 return "movaps\t{%1, %0|%0, %1}";
2130 return "movlps\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 return standard_sse_constant_opcode (insn, operands[1]);
2142 return "pxor\t%0, %0";
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "*")))
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2181 "ix86_split_long_move (operands); DONE;")
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2188 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2190 switch (get_attr_type (insn))
2193 return standard_sse_constant_opcode (insn, operands[1]);
2196 switch (get_attr_mode (insn))
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2201 return "%vmovaps\t{%1, %0|%0, %1}";
2203 return "%vmovd\t{%1, %0|%0, %1}";
2205 return "%vmovss\t{%1, %0|%0, %1}";
2211 return "pxor\t%0, %0";
2214 if (get_attr_mode (insn) == MODE_DI)
2215 return "movq\t{%1, %0|%0, %1}";
2216 return "movd\t{%1, %0|%0, %1}";
2219 return "lea{l}\t{%a1, %0|%0, %a1}";
2222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223 return "mov{l}\t{%1, %0|%0, %1}";
2227 (cond [(eq_attr "alternative" "2")
2228 (const_string "mmx")
2229 (eq_attr "alternative" "3,4,5")
2230 (const_string "mmxmov")
2231 (eq_attr "alternative" "6")
2232 (const_string "sselog1")
2233 (eq_attr "alternative" "7,8,9,10,11")
2234 (const_string "ssemov")
2235 (match_operand:DI 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2246 (const_string "*")))
2248 (cond [(eq_attr "alternative" "2,3")
2250 (eq_attr "alternative" "6,7")
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2259 (const_string "SI")))])
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2276 return "mov{w}\t{%1, %0|%0, %1}";
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2297 (const_string "imov")))
2299 (cond [(eq_attr "type" "imovx")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2311 (const_string "HI")))])
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328 switch (get_attr_type (insn))
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337 return "mov{b}\t{%1, %0|%0, %1}";
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2360 (const_string "imov")))
2362 (cond [(eq_attr "alternative" "3,4,5")
2364 (eq_attr "alternative" "6")
2366 (eq_attr "type" "imovx")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2386 (const_string "QI")))])
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2513 switch (get_attr_type (insn))
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2525 (const_string "imovx")
2526 (const_string "imov")))
2528 (if_then_else (eq_attr "type" "imovx")
2530 (const_string "QI")))])
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2539 switch (get_attr_type (insn))
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2552 (const_string "imovx")
2553 (const_string "imov")))
2555 (if_then_else (eq_attr "type" "imovx")
2557 (const_string "QI")))])
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2577 switch (get_attr_type (insn))
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2589 (const_string "imovx")
2590 (const_string "imov")))
2592 (if_then_else (eq_attr "type" "imovx")
2594 (const_string "QI")))])
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2604 switch (get_attr_type (insn))
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2617 (const_string "imovx")
2618 (const_string "imov")))
2620 (if_then_else (eq_attr "type" "imovx")
2622 (const_string "QI")))])
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2661 ;; Floating point push instructions.
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2668 /* This insn should be already split before reg-stack. */
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2675 ;; %%% Kill this when call knows how to work this out.
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2688 /* This insn should be already split before reg-stack. */
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2706 /* This insn should be already split before reg-stack. */
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2713 ;; %%% Kill this when call knows how to work this out.
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2738 ;; %%% Kill this when call knows how to work this out.
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2797 "ix86_split_long_move (operands); DONE;")
2799 ;; Floating point move instructions.
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2806 ix86_expand_move (TFmode, operands);
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2830 switch (which_alternative)
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2853 return standard_sse_constant_opcode (insn, operands[1]);
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2866 (cond [(eq_attr "alternative" "0,2")
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2896 switch (which_alternative)
2900 return output_387_reg_move (insn, operands);
2903 return standard_80387_constant_opcode (operands[1]);
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2932 switch (which_alternative)
2936 return output_387_reg_move (insn, operands);
2939 return standard_80387_constant_opcode (operands[1]);
2943 return "mov{q}\t{%1, %0|%0, %1}";
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2952 return standard_sse_constant_opcode (insn, operands[1]);
2957 switch (get_attr_mode (insn))
2960 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovapd\t{%1, %0|%0, %1}";
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2966 return "%vmovq\t{%1, %0|%0, %1}";
2968 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "%vmovsd\t{%1, %0|%0, %1}";
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2981 /* Handle broken assemblers that require movd instead of movq. */
2982 return "%vmovd\t{%1, %0|%0, %1}";
2988 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2993 (const_string "*")))
2994 (set (attr "length_immediate")
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2998 (const_string "*")))
2999 (set (attr "prefix")
3000 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001 (const_string "orig")
3002 (const_string "maybe_vex")))
3003 (set (attr "prefix_data16")
3004 (if_then_else (eq_attr "mode" "V1DF")
3006 (const_string "*")))
3008 (cond [(eq_attr "alternative" "0,1,2")
3010 (eq_attr "alternative" "3,4,5,6,11,12")
3013 /* xorps is one byte shorter. */
3014 (eq_attr "alternative" "7")
3015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3022 (const_string "V2DF"))
3024 /* For architectures resolving dependencies on
3025 whole SSE registers use APD move to break dependency
3026 chains, otherwise use short move to avoid extra work.
3028 movaps encodes one byte shorter. */
3029 (eq_attr "alternative" "8")
3031 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3033 (const_string "V4SF")
3034 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3036 (const_string "V2DF")
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3042 (eq_attr "alternative" "9")
3044 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3046 (const_string "V1DF")
3047 (const_string "DF"))
3049 (const_string "DF")))])
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3070 switch (which_alternative)
3074 return output_387_reg_move (insn, operands);
3077 return standard_80387_constant_opcode (operands[1]);
3084 return standard_sse_constant_opcode (insn, operands[1]);
3089 switch (get_attr_mode (insn))
3092 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3095 return "%vmovaps\t{%1, %0|%0, %1}";
3098 return "%vmovq\t{%1, %0|%0, %1}";
3100 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3104 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3106 return "%vmovlps\t{%1, %d0|%d0, %1}";
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133 (eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146 (const_string "V2DF"))
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160 (const_string "V2DF")
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "7")
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3191 switch (which_alternative)
3195 return output_387_reg_move (insn, operands);
3198 return standard_80387_constant_opcode (operands[1]);
3202 return "mov{l}\t{%1, %0|%0, %1}";
3205 return standard_sse_constant_opcode (insn, operands[1]);
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3215 return "%vmovss\t{%1, %0|%0, %1}";
3221 return "movd\t{%1, %0|%0, %1}";
3224 return "movq\t{%1, %0|%0, %1}";
3228 return "%vmovd\t{%1, %0|%0, %1}";
3234 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235 (set (attr "prefix")
3236 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237 (const_string "maybe_vex")
3238 (const_string "orig")))
3240 (cond [(eq_attr "alternative" "3,4,9,10")
3242 (eq_attr "alternative" "5")
3244 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3246 (ne (symbol_ref "TARGET_SSE2")
3248 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3266 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3320 (neg:X87MODEF (match_dup 0)))]
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3328 operands[1] = CONST1_RTX (<MODE>mode);
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3340 "ix86_split_long_move (operands); DONE;")
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3349 if (STACK_TOP_P (operands[0]))
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3362 "TARGET_80387 || reload_completed"
3364 if (STACK_TOP_P (operands[0]))
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3372 ;; Zero extension instructions
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3381 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3389 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3392 mov\t{%k1, %k0|%k0, %k1}
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}
3397 %vmovd\t{%1, %0|%0, %1}"
3398 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3404 [(set (match_operand:DI 0 "memory_operand" "")
3405 (zero_extend:DI (match_dup 0)))]
3407 [(set (match_dup 4) (const_int 0))]
3408 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3414 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3415 (clobber (reg:CC FLAGS_REG))]
3421 movd\t{%1, %0|%0, %1}
3422 movd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}"
3425 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3457 (define_expand "zero_extendhisi2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3464 operands[1] = force_reg (HImode, operands[1]);
3465 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3470 (define_insn_and_split "zero_extendhisi2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3476 "&& reload_completed"
3477 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478 (clobber (reg:CC FLAGS_REG))])]
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "SI")])
3483 (define_insn "*zero_extendhisi2_movzwl"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486 "!TARGET_ZERO_EXTEND_WITH_AND
3487 || optimize_function_for_size_p (cfun)"
3488 "movz{wl|x}\t{%1, %0|%0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3492 (define_expand "zero_extendqi<mode>2"
3494 [(set (match_operand:SWI24 0 "register_operand" "")
3495 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])])
3498 (define_insn "*zero_extendqi<mode>2_and"
3499 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "<MODE>")])
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3514 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 && ANY_QI_REG_P (operands[0])
3516 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3520 operands[2] = gen_lowpart (QImode, operands[0]);
3521 ix86_expand_clear (operands[0]);
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "<MODE>")])
3533 ;; For the movzbl case strip only the clobber
3535 [(set (match_operand:SWI24 0 "register_operand" "")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537 (clobber (reg:CC FLAGS_REG))]
3539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3542 (zero_extend:SWI24 (match_dup 1)))])
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546 [(set (match_operand:SWI24 0 "register_operand" "=r")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3554 ;; Rest is handled by single and.
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC FLAGS_REG))])])
3564 ;; Sign extension instructions
3566 (define_expand "extendsidi2"
3567 [(set (match_operand:DI 0 "register_operand" "")
3568 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3573 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3578 (define_insn "*extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3584 movs{lq|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "DI")
3587 (set_attr "prefix_0f" "0")
3588 (set_attr "modrm" "0,1")])
3590 (define_insn "extendsidi2_1"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3598 ;; Extend to memory case when source register does die.
3600 [(set (match_operand:DI 0 "memory_operand" "")
3601 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602 (clobber (reg:CC FLAGS_REG))
3603 (clobber (match_operand:SI 2 "register_operand" ""))]
3605 && dead_or_set_p (insn, operands[1])
3606 && !reg_mentioned_p (operands[1], operands[0]))"
3607 [(set (match_dup 3) (match_dup 1))
3608 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609 (clobber (reg:CC FLAGS_REG))])
3610 (set (match_dup 4) (match_dup 1))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 ;; Extend to memory case when source register does not die.
3615 [(set (match_operand:DI 0 "memory_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_operand:SI 2 "register_operand" ""))]
3622 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3624 emit_move_insn (operands[3], operands[1]);
3626 /* Generate a cltd if possible and doing so it profitable. */
3627 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628 && true_regnum (operands[1]) == AX_REG
3629 && true_regnum (operands[2]) == DX_REG)
3631 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3635 emit_move_insn (operands[2], operands[1]);
3636 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3638 emit_move_insn (operands[4], operands[2]);
3642 ;; Extend to register case. Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3645 [(set (match_operand:DI 0 "register_operand" "")
3646 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647 (clobber (reg:CC FLAGS_REG))
3648 (clobber (match_scratch:SI 2 ""))]
3652 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3654 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[3], operands[1]);
3657 /* Generate a cltd if possible and doing so it profitable. */
3658 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659 && true_regnum (operands[3]) == AX_REG
3660 && true_regnum (operands[4]) == DX_REG)
3662 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3666 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667 emit_move_insn (operands[4], operands[1]);
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3673 (define_insn "extend<mode>di2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3678 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "DI")])
3682 (define_insn "extendhisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3687 switch (get_attr_prefix_0f (insn))
3690 return "{cwtl|cwde}";
3692 return "movs{wl|x}\t{%1, %0|%0, %1}";
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")
3697 (set (attr "prefix_0f")
3698 ;; movsx is short decodable while cwtl is vector decoded.
3699 (if_then_else (and (eq_attr "cpu" "!k6")
3700 (eq_attr "alternative" "0"))
3702 (const_string "1")))
3704 (if_then_else (eq_attr "prefix_0f" "0")
3706 (const_string "1")))])
3708 (define_insn "*extendhisi2_zext"
3709 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3712 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3715 switch (get_attr_prefix_0f (insn))
3718 return "{cwtl|cwde}";
3720 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3723 [(set_attr "type" "imovx")
3724 (set_attr "mode" "SI")
3725 (set (attr "prefix_0f")
3726 ;; movsx is short decodable while cwtl is vector decoded.
3727 (if_then_else (and (eq_attr "cpu" "!k6")
3728 (eq_attr "alternative" "0"))
3730 (const_string "1")))
3732 (if_then_else (eq_attr "prefix_0f" "0")
3734 (const_string "1")))])
3736 (define_insn "extendqisi2"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740 "movs{bl|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 (define_insn "*extendqisi2_zext"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3749 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3753 (define_insn "extendqihi2"
3754 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3758 switch (get_attr_prefix_0f (insn))
3761 return "{cbtw|cbw}";
3763 return "movs{bw|x}\t{%1, %0|%0, %1}";
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "HI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3773 (const_string "1")))
3775 (if_then_else (eq_attr "prefix_0f" "0")
3777 (const_string "1")))])
3779 ;; Conversions between float and double.
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3786 [(set (match_operand:DF 0 "push_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3793 [(set (match_operand:XF 0 "push_operand" "")
3794 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3800 (define_expand "extendsfdf2"
3801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3805 /* ??? Needed for compress_float_constant since all fp constants
3806 are TARGET_LEGITIMATE_CONSTANT_P. */
3807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3809 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810 && standard_80387_constant_p (operands[1]) > 0)
3812 operands[1] = simplify_const_unary_operation
3813 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814 emit_move_insn_1 (operands[0], operands[1]);
3817 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3823 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3825 We do the conversion post reload to avoid producing of 128bit spills
3826 that might lead to ICE on 32bit target. The sequence unlikely combine
3829 [(set (match_operand:DF 0 "register_operand" "")
3831 (match_operand:SF 1 "nonimmediate_operand" "")))]
3832 "TARGET_USE_VECTOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && reload_completed && SSE_REG_P (operands[0])"
3839 (parallel [(const_int 0) (const_int 1)]))))]
3841 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844 Try to avoid move when unpacking can be done in source. */
3845 if (REG_P (operands[1]))
3847 /* If it is unsafe to overwrite upper half of source, we need
3848 to move to destination and unpack there. */
3849 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851 && true_regnum (operands[0]) != true_regnum (operands[1]))
3853 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854 emit_move_insn (tmp, operands[1]);
3857 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3862 emit_insn (gen_vec_setv4sf_0 (operands[3],
3863 CONST0_RTX (V4SFmode), operands[1]));
3866 (define_insn "*extendsfdf2_mixed"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3869 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3872 switch (which_alternative)
3876 return output_387_reg_move (insn, operands);
3879 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "prefix" "orig,orig,maybe_vex")
3887 (set_attr "mode" "SF,XF,DF")])
3889 (define_insn "*extendsfdf2_sse"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892 "TARGET_SSE2 && TARGET_SSE_MATH"
3893 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894 [(set_attr "type" "ssecvt")
3895 (set_attr "prefix" "maybe_vex")
3896 (set_attr "mode" "DF")])
3898 (define_insn "*extendsfdf2_i387"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3902 "* return output_387_reg_move (insn, operands);"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "SF,XF")])
3906 (define_expand "extend<mode>xf2"
3907 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3911 /* ??? Needed for compress_float_constant since all fp constants
3912 are TARGET_LEGITIMATE_CONSTANT_P. */
3913 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3915 if (standard_80387_constant_p (operands[1]) > 0)
3917 operands[1] = simplify_const_unary_operation
3918 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919 emit_move_insn_1 (operands[0], operands[1]);
3922 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3926 (define_insn "*extend<mode>xf2_i387"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3929 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>,XF")])
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3941 ;; Conversion from DFmode to SFmode.
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3951 else if (flag_unsafe_math_optimizations)
3955 enum ix86_stack_slot slot = (virtuals_instantiated
3958 rtx temp = assign_386_stack_local (SFmode, slot);
3959 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3966 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3968 We do the conversion post reload to avoid producing of 128bit spills
3969 that might lead to ICE on 32bit target. The sequence unlikely combine
3972 [(set (match_operand:SF 0 "register_operand" "")
3974 (match_operand:DF 1 "nonimmediate_operand" "")))]
3975 "TARGET_USE_VECTOR_FP_CONVERTS
3976 && optimize_insn_for_speed_p ()
3977 && reload_completed && SSE_REG_P (operands[0])"
3980 (float_truncate:V2SF
3984 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985 operands[3] = CONST0_RTX (V2SFmode);
3986 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987 /* Use movsd for loading from memory, unpcklpd for registers.
3988 Try to avoid move when unpacking can be done in source, or SSE3
3989 movddup is available. */
3990 if (REG_P (operands[1]))
3993 && true_regnum (operands[0]) != true_regnum (operands[1])
3994 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3997 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998 emit_move_insn (tmp, operands[1]);
4001 else if (!TARGET_SSE3)
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4006 emit_insn (gen_sse2_loadlpd (operands[4],
4007 CONST0_RTX (V2DFmode), operands[1]));
4010 (define_expand "truncdfsf2_with_temp"
4011 [(parallel [(set (match_operand:SF 0 "" "")
4012 (float_truncate:SF (match_operand:DF 1 "" "")))
4013 (clobber (match_operand:SF 2 "" ""))])])
4015 (define_insn "*truncdfsf_fast_mixed"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4018 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4019 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4021 switch (which_alternative)
4024 return output_387_reg_move (insn, operands);
4026 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4031 [(set_attr "type" "fmov,ssecvt")
4032 (set_attr "prefix" "orig,maybe_vex")
4033 (set_attr "mode" "SF")])
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4040 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4042 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043 [(set_attr "type" "ssecvt")
4044 (set_attr "prefix" "maybe_vex")
4045 (set_attr "mode" "SF")])
4047 (define_insn "*truncdfsf_fast_i387"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4050 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051 "TARGET_80387 && flag_unsafe_math_optimizations"
4052 "* return output_387_reg_move (insn, operands);"
4053 [(set_attr "type" "fmov")
4054 (set_attr "mode" "SF")])
4056 (define_insn "*truncdfsf_mixed"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4059 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4061 "TARGET_MIX_SSE_I387"
4063 switch (which_alternative)
4066 return output_387_reg_move (insn, operands);
4068 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4074 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "DF")])
4174 (define_insn "truncxf<mode>2_i387_noop"
4175 [(set (match_operand:MODEF 0 "register_operand" "=f")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "f")))]
4178 "TARGET_80387 && flag_unsafe_math_optimizations"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "<MODE>")])
4183 (define_insn "*truncxf<mode>2_i387"
4184 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4193 [(set (match_operand:MODEF 0 "register_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))])
4202 [(set (match_operand:MODEF 0 "memory_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209 ;; Signed conversion to DImode.
4211 (define_expand "fix_truncxfdi2"
4212 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (fix:DI (match_operand:XF 1 "register_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))])]
4219 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4224 (define_expand "fix_trunc<mode>di2"
4225 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))])]
4228 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4231 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4233 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4236 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4238 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240 if (out != operands[0])
4241 emit_move_insn (operands[0], out);
4246 ;; Signed conversion to SImode.
4248 (define_expand "fix_truncxfsi2"
4249 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250 (fix:SI (match_operand:XF 1 "register_operand" "")))
4251 (clobber (reg:CC FLAGS_REG))])]
4256 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4261 (define_expand "fix_trunc<mode>si2"
4262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4268 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4273 if (SSE_FLOAT_MODE_P (<MODE>mode))
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4283 ;; Signed conversion to HImode.
4285 (define_expand "fix_trunc<mode>hi2"
4286 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288 (clobber (reg:CC FLAGS_REG))])]
4290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4294 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4299 ;; Unsigned conversion to SImode.
4301 (define_expand "fixuns_trunc<mode>si2"
4303 [(set (match_operand:SI 0 "register_operand" "")
4305 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307 (clobber (match_scratch:<ssevecmode> 3 ""))
4308 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311 enum machine_mode mode = <MODE>mode;
4312 enum machine_mode vecmode = <ssevecmode>mode;
4313 REAL_VALUE_TYPE TWO31r;
4316 if (optimize_insn_for_size_p ())
4319 real_ldexp (&TWO31r, &dconst1, 31);
4320 two31 = const_double_from_real_value (TWO31r, mode);
4321 two31 = ix86_build_const_vector (vecmode, true, two31);
4322 operands[2] = force_reg (vecmode, two31);
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4330 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333 && optimize_function_for_speed_p (cfun)"
4335 "&& reload_completed"
4338 ix86_split_convert_uns_si_sse (operands);
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346 (define_expand "fixuns_trunc<mode>hi2"
4348 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349 (set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (subreg:HI (match_dup 2) 0))]
4351 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352 "operands[2] = gen_reg_rtx (SImode);")
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "sseicvt")
4362 (set_attr "prefix" "maybe_vex")
4363 (set_attr "prefix_rex" "1")
4364 (set_attr "mode" "<MODE>")
4365 (set_attr "athlon_decode" "double,vector")
4366 (set_attr "amdfam10_decode" "double,double")
4367 (set_attr "bdver1_decode" "double,double")])
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "prefix" "maybe_vex")
4377 (set_attr "mode" "<MODE>")
4378 (set_attr "athlon_decode" "double,vector")
4379 (set_attr "amdfam10_decode" "double,double")
4380 (set_attr "bdver1_decode" "double,double")])
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (match_operand:MODEF 1 "memory_operand" ""))
4386 (set (match_operand:SWI48x 2 "register_operand" "")
4387 (fix:SWI48x (match_dup 0)))]
4388 "TARGET_SHORTEN_X87_SSE
4389 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390 && peep2_reg_dead_p (2, operands[0])"
4391 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393 ;; Avoid vector decoded forms of the instruction.
4395 [(match_scratch:DF 2 "Y2")
4396 (set (match_operand:SWI48x 0 "register_operand" "")
4397 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4403 [(match_scratch:SF 2 "x")
4404 (set (match_operand:SWI48x 0 "register_operand" "")
4405 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407 [(set (match_dup 2) (match_dup 1))
4408 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4418 && can_create_pseudo_p ()"
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, true);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4465 [(set (match_operand:SWI248x 0 "register_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4470 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))])
4475 [(set (match_operand:SWI248x 0 "memory_operand" "")
4476 (fix:SWI248x (match_operand 1 "register_operand" "")))
4477 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478 (clobber (match_scratch 3 ""))]
4480 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481 (clobber (match_dup 3))])])
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490 (fix:SWI248x (match_operand 1 "register_operand" "")))
4491 (clobber (reg:CC FLAGS_REG))]
4492 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && can_create_pseudo_p ()"
4501 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505 if (memory_operand (operands[0], VOIDmode))
4506 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507 operands[2], operands[3]));
4510 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512 operands[2], operands[3],
4517 [(set_attr "type" "fistp")
4518 (set_attr "i387_cw" "trunc")
4519 (set_attr "mode" "<MODE>")])
4521 (define_insn "fix_truncdi_i387"
4522 [(set (match_operand:DI 0 "memory_operand" "=m")
4523 (fix:DI (match_operand 1 "register_operand" "f")))
4524 (use (match_operand:HI 2 "memory_operand" "m"))
4525 (use (match_operand:HI 3 "memory_operand" "m"))
4526 (clobber (match_scratch:XF 4 "=&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "* return output_fix_trunc (insn, operands, false);"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4535 (define_insn "fix_truncdi_i387_with_temp"
4536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:DI (match_operand 1 "register_operand" "f,f")))
4538 (use (match_operand:HI 2 "memory_operand" "m,m"))
4539 (use (match_operand:HI 3 "memory_operand" "m,m"))
4540 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "DI")])
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (fix:DI (match_operand 1 "register_operand" "")))
4553 (use (match_operand:HI 2 "memory_operand" ""))
4554 (use (match_operand:HI 3 "memory_operand" ""))
4555 (clobber (match_operand:DI 4 "memory_operand" ""))
4556 (clobber (match_scratch 5 ""))]
4558 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4561 (clobber (match_dup 5))])
4562 (set (match_dup 0) (match_dup 4))])
4565 [(set (match_operand:DI 0 "memory_operand" "")
4566 (fix:DI (match_operand 1 "register_operand" "")))
4567 (use (match_operand:HI 2 "memory_operand" ""))
4568 (use (match_operand:HI 3 "memory_operand" ""))
4569 (clobber (match_operand:DI 4 "memory_operand" ""))
4570 (clobber (match_scratch 5 ""))]
4572 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4575 (clobber (match_dup 5))])])
4577 (define_insn "fix_trunc<mode>_i387"
4578 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "<MODE>")])
4605 [(set (match_operand:SWI24 0 "register_operand" "")
4606 (fix:SWI24 (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4611 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613 (use (match_dup 3))])
4614 (set (match_dup 0) (match_dup 4))])
4617 [(set (match_operand:SWI24 0 "memory_operand" "")
4618 (fix:SWI24 (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:SWI24 4 "memory_operand" ""))]
4623 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625 (use (match_dup 3))])])
4627 (define_insn "x86_fnstcw_1"
4628 [(set (match_operand:HI 0 "memory_operand" "=m")
4629 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4632 [(set (attr "length")
4633 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "bdver1_decode" "vector")])
4638 (define_insn "x86_fldcw_1"
4639 [(set (reg:HI FPCR_REG)
4640 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "athlon_decode" "vector")
4648 (set_attr "amdfam10_decode" "vector")
4649 (set_attr "bdver1_decode" "vector")])
4651 ;; Conversion between fixed point and floating point.
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4656 (define_expand "floathi<mode>2"
4657 [(set (match_operand:X87MODEF 0 "register_operand" "")
4658 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)")
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665 [(set (match_operand:X87MODEF 0 "register_operand" "")
4666 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)
4670 && can_create_pseudo_p ()"
4673 [(parallel [(set (match_dup 0)
4674 (float:X87MODEF (match_dup 1)))
4675 (clobber (match_dup 2))])]
4676 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684 || TARGET_MIX_SSE_I387)"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "<MODE>")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4691 (define_insn "*floathi<mode>2_i387"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)"
4698 [(set_attr "type" "fmov")
4699 (set_attr "mode" "<MODE>")
4700 (set_attr "fp_int_src" "true")])
4703 [(set (match_operand:X87MODEF 0 "register_operand" "")
4704 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705 (clobber (match_operand:HI 2 "memory_operand" ""))]
4707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387)
4709 && reload_completed"
4710 [(set (match_dup 2) (match_dup 1))
4711 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716 (clobber (match_operand:HI 2 "memory_operand" ""))]
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)
4720 && reload_completed"
4721 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724 [(set (match_operand:X87MODEF 0 "register_operand" "")
4726 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4731 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4735 rtx reg = gen_reg_rtx (XFmode);
4736 rtx (*insn)(rtx, rtx);
4738 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4740 if (<X87MODEF:MODE>mode == SFmode)
4741 insn = gen_truncxfsf2;
4742 else if (<X87MODEF:MODE>mode == DFmode)
4743 insn = gen_truncxfdf2;
4747 emit_insn (insn (operands[0], reg));
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "")
4755 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387))
4761 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763 && ((<SWI48x:MODE>mode == SImode
4764 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765 && optimize_function_for_speed_p (cfun)
4766 && flag_trapping_math)
4767 || !(TARGET_INTER_UNIT_CONVERSIONS
4768 || optimize_function_for_size_p (cfun)))))
4769 && can_create_pseudo_p ()"
4772 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773 (clobber (match_dup 2))])]
4775 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4777 /* Avoid store forwarding (partial memory) stall penalty
4778 by passing DImode value through XMM registers. */
4779 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781 && optimize_function_for_speed_p (cfun))
4783 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800 (set_attr "unit" "*,i387,*,*,*")
4801 (set_attr "athlon_decode" "*,*,double,direct,double")
4802 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803 (set_attr "bdver1_decode" "*,*,double,direct,double")
4804 (set_attr "fp_int_src" "true")])
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4814 [(set_attr "type" "fmov,sseicvt")
4815 (set_attr "mode" "<MODE>,<ssevecmode>")
4816 (set_attr "unit" "i387,*")
4817 (set_attr "athlon_decode" "*,direct")
4818 (set_attr "amdfam10_decode" "*,double")
4819 (set_attr "bdver1_decode" "*,direct")
4820 (set_attr "fp_int_src" "true")])
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "unit" "*,i387,*,*")
4833 (set_attr "athlon_decode" "*,*,double,direct")
4834 (set_attr "amdfam10_decode" "*,*,vector,double")
4835 (set_attr "bdver1_decode" "*,*,double,direct")
4836 (set_attr "fp_int_src" "true")])
4839 [(set (match_operand:MODEF 0 "register_operand" "")
4840 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4846 && (SSE_REG_P (operands[0])
4847 || (GET_CODE (operands[0]) == SUBREG
4848 && SSE_REG_P (operands[0])))"
4849 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4852 [(set (match_operand:MODEF 0 "register_operand" "")
4853 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859 && (SSE_REG_P (operands[0])
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && SSE_REG_P (operands[0])))"
4862 [(set (match_dup 2) (match_dup 1))
4863 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876 [(set_attr "type" "fmov,sseicvt,sseicvt")
4877 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878 (set_attr "mode" "<MODEF:MODE>")
4879 (set (attr "prefix_rex")
4881 (and (eq_attr "prefix" "maybe_vex")
4882 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4884 (const_string "*")))
4885 (set_attr "unit" "i387,*,*")
4886 (set_attr "athlon_decode" "*,double,direct")
4887 (set_attr "amdfam10_decode" "*,vector,double")
4888 (set_attr "bdver1_decode" "*,double,direct")
4889 (set_attr "fp_int_src" "true")])
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4900 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901 [(set_attr "type" "fmov,sseicvt")
4902 (set_attr "prefix" "orig,maybe_vex")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set (attr "prefix_rex")
4906 (and (eq_attr "prefix" "maybe_vex")
4907 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4909 (const_string "*")))
4910 (set_attr "athlon_decode" "*,direct")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "bdver1_decode" "*,direct")
4913 (set_attr "fp_int_src" "true")])
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920 "TARGET_SSE2 && TARGET_SSE_MATH
4921 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923 [(set_attr "type" "sseicvt")
4924 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925 (set_attr "athlon_decode" "double,direct,double")
4926 (set_attr "amdfam10_decode" "vector,double,double")
4927 (set_attr "bdver1_decode" "double,direct,double")
4928 (set_attr "fp_int_src" "true")])
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931 [(set (match_operand:MODEF 0 "register_operand" "=x")
4932 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933 "TARGET_SSE2 && TARGET_SSE_MATH
4934 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936 [(set_attr "type" "sseicvt")
4937 (set_attr "mode" "<MODE>")
4938 (set_attr "athlon_decode" "direct")
4939 (set_attr "amdfam10_decode" "double")
4940 (set_attr "bdver1_decode" "direct")
4941 (set_attr "fp_int_src" "true")])
4944 [(set (match_operand:MODEF 0 "register_operand" "")
4945 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946 (clobber (match_operand:SI 2 "memory_operand" ""))]
4947 "TARGET_SSE2 && TARGET_SSE_MATH
4948 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (operands[0])))"
4955 rtx op1 = operands[1];
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4962 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[1]));
4968 /* We can ignore possible trapping value in the
4969 high part of SSE register for non-trapping math. */
4970 else if (SSE_REG_P (op1) && !flag_trapping_math)
4971 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4974 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975 emit_move_insn (operands[2], operands[1]);
4976 emit_insn (gen_sse2_loadld (operands[4],
4977 CONST0_RTX (V4SImode), operands[2]));
4980 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4985 [(set (match_operand:MODEF 0 "register_operand" "")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987 (clobber (match_operand:SI 2 "memory_operand" ""))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4996 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4998 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5003 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5008 [(set (match_operand:MODEF 0 "register_operand" "")
5009 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5013 && (SSE_REG_P (operands[0])
5014 || (GET_CODE (operands[0]) == SUBREG
5015 && SSE_REG_P (operands[0])))"
5018 rtx op1 = operands[1];
5020 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5022 if (GET_CODE (op1) == SUBREG)
5023 op1 = SUBREG_REG (op1);
5025 if (GENERAL_REG_P (op1))
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 if (TARGET_INTER_UNIT_MOVES)
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5033 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[5]));
5037 ix86_free_from_memory (GET_MODE (operands[1]));
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5052 [(set (match_operand:MODEF 0 "register_operand" "")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (operands[0])))"
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5069 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5076 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODEF:MODE>")
5083 (set_attr "athlon_decode" "double,direct")
5084 (set_attr "amdfam10_decode" "vector,double")
5085 (set_attr "bdver1_decode" "double,direct")
5086 (set_attr "fp_int_src" "true")])
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5091 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096 [(set_attr "type" "sseicvt")
5097 (set_attr "prefix" "maybe_vex")
5098 (set_attr "mode" "<MODEF:MODE>")
5099 (set (attr "prefix_rex")
5101 (and (eq_attr "prefix" "maybe_vex")
5102 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5104 (const_string "*")))
5105 (set_attr "athlon_decode" "double,direct")
5106 (set_attr "amdfam10_decode" "vector,double")
5107 (set_attr "bdver1_decode" "double,direct")
5108 (set_attr "fp_int_src" "true")])
5111 [(set (match_operand:MODEF 0 "register_operand" "")
5112 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (operands[0])))"
5121 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x")
5126 (match_operand:SWI48x 1 "memory_operand" "m")))]
5127 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "prefix" "maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5139 (const_string "*")))
5140 (set_attr "athlon_decode" "direct")
5141 (set_attr "amdfam10_decode" "double")
5142 (set_attr "bdver1_decode" "direct")
5143 (set_attr "fp_int_src" "true")])
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5156 [(set (match_dup 2) (match_dup 1))
5157 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5169 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5177 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5181 [(set_attr "type" "fmov,multi")
5182 (set_attr "mode" "<X87MODEF:MODE>")
5183 (set_attr "unit" "*,i387")
5184 (set_attr "fp_int_src" "true")])
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5191 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5193 [(set_attr "type" "fmov")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203 && reload_completed"
5204 [(set (match_dup 2) (match_dup 1))
5205 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5208 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213 && reload_completed"
5214 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers. */
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5222 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223 (clobber (match_scratch:V4SI 3 "=X,x"))
5224 (clobber (match_scratch:V4SI 4 "=X,x"))
5225 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5230 [(set_attr "type" "multi")
5231 (set_attr "mode" "<X87MODEF:MODE>")
5232 (set_attr "unit" "i387")
5233 (set_attr "fp_int_src" "true")])
5236 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238 (clobber (match_scratch:V4SI 3 ""))
5239 (clobber (match_scratch:V4SI 4 ""))
5240 (clobber (match_operand:DI 2 "memory_operand" ""))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 3))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5248 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249 Assemble the 64-bit DImode value in an xmm register. */
5250 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 0)));
5252 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253 gen_rtx_SUBREG (SImode, operands[1], 4)));
5254 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5257 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263 (clobber (match_scratch:V4SI 3 ""))
5264 (clobber (match_scratch:V4SI 4 ""))
5265 (clobber (match_operand:DI 2 "memory_operand" ""))]
5266 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269 && reload_completed"
5270 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5278 (define_insn "*floatunssi<mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283 (clobber (match_scratch:SI 3 "=X,x"))]
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5288 [(set_attr "type" "multi")
5289 (set_attr "mode" "<MODE>")])
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (unsigned_float:X87MODEF
5294 (match_operand:SI 1 "register_operand" "")))
5295 (clobber (match_operand:DI 2 "memory_operand" ""))
5296 (clobber (match_scratch:SI 3 ""))]
5298 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && reload_completed"
5301 [(set (match_dup 2) (match_dup 1))
5303 (float:X87MODEF (match_dup 2)))]
5304 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5307 [(set (match_operand:X87MODEF 0 "register_operand" "")
5308 (unsigned_float:X87MODEF
5309 (match_operand:SI 1 "memory_operand" "")))
5310 (clobber (match_operand:DI 2 "memory_operand" ""))
5311 (clobber (match_scratch:SI 3 ""))]
5313 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5318 (float:X87MODEF (match_dup 2)))]
5320 emit_move_insn (operands[3], operands[1]);
5321 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5324 (define_expand "floatunssi<mode>2"
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "nonimmediate_operand" "")))
5329 (clobber (match_dup 2))
5330 (clobber (match_scratch:SI 3 ""))])]
5332 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5338 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5343 enum ix86_stack_slot slot = (virtuals_instantiated
5346 operands[2] = assign_386_stack_local (DImode, slot);
5350 (define_expand "floatunsdisf2"
5351 [(use (match_operand:SF 0 "register_operand" ""))
5352 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353 "TARGET_64BIT && TARGET_SSE_MATH"
5354 "x86_emit_floatuns (operands); DONE;")
5356 (define_expand "floatunsdidf2"
5357 [(use (match_operand:DF 0 "register_operand" ""))
5358 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360 && TARGET_SSE2 && TARGET_SSE_MATH"
5363 x86_emit_floatuns (operands);
5365 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5371 (define_expand "add<mode>3"
5372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374 (match_operand:SDWIM 2 "<general_operand>" "")))]
5376 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5381 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383 (clobber (reg:CC FLAGS_REG))]
5384 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5387 [(parallel [(set (reg:CC FLAGS_REG)
5388 (unspec:CC [(match_dup 1) (match_dup 2)]
5391 (plus:DWIH (match_dup 1) (match_dup 2)))])
5392 (parallel [(set (match_dup 3)
5396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5398 (clobber (reg:CC FLAGS_REG))])]
5399 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5401 (define_insn "*add<mode>3_cc"
5402 [(set (reg:CC FLAGS_REG)
5404 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5407 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411 [(set_attr "type" "alu")
5412 (set_attr "mode" "<MODE>")])
5414 (define_insn "addqi3_cc"
5415 [(set (reg:CC FLAGS_REG)
5417 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:QI 2 "general_operand" "qn,qm")]
5420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421 (plus:QI (match_dup 1) (match_dup 2)))]
5422 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423 "add{b}\t{%2, %0|%0, %2}"
5424 [(set_attr "type" "alu")
5425 (set_attr "mode" "QI")])
5427 (define_insn "*lea_1"
5428 [(set (match_operand:P 0 "register_operand" "=r")
5429 (match_operand:P 1 "no_seg_address_operand" "p"))]
5431 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432 [(set_attr "type" "lea")
5433 (set_attr "mode" "<MODE>")])
5435 (define_insn "*lea_2"
5436 [(set (match_operand:SI 0 "register_operand" "=r")
5437 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5439 "lea{l}\t{%a1, %0|%0, %a1}"
5440 [(set_attr "type" "lea")
5441 (set_attr "mode" "SI")])
5443 (define_insn "*lea_2_zext"
5444 [(set (match_operand:DI 0 "register_operand" "=r")
5446 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5448 "lea{l}\t{%a1, %k0|%k0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "SI")])
5452 (define_insn "*add<mode>_1"
5453 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5455 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5456 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5457 (clobber (reg:CC FLAGS_REG))]
5458 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5460 switch (get_attr_type (insn))
5466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5467 if (operands[2] == const1_rtx)
5468 return "inc{<imodesuffix>}\t%0";
5471 gcc_assert (operands[2] == constm1_rtx);
5472 return "dec{<imodesuffix>}\t%0";
5476 /* For most processors, ADD is faster than LEA. This alternative
5477 was added to use ADD as much as possible. */
5478 if (which_alternative == 2)
5481 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5485 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5486 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5488 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5492 (cond [(eq_attr "alternative" "3")
5493 (const_string "lea")
5494 (match_operand:SWI48 2 "incdec_operand" "")
5495 (const_string "incdec")
5497 (const_string "alu")))
5498 (set (attr "length_immediate")
5500 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5502 (const_string "*")))
5503 (set_attr "mode" "<MODE>")])
5505 ;; It may seem that nonimmediate operand is proper one for operand 1.
5506 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5507 ;; we take care in ix86_binary_operator_ok to not allow two memory
5508 ;; operands so proper swapping will be done in reload. This allow
5509 ;; patterns constructed from addsi_1 to match.
5511 (define_insn "addsi_1_zext"
5512 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5514 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5515 (match_operand:SI 2 "general_operand" "g,0,li"))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5519 switch (get_attr_type (insn))
5525 if (operands[2] == const1_rtx)
5526 return "inc{l}\t%k0";
5529 gcc_assert (operands[2] == constm1_rtx);
5530 return "dec{l}\t%k0";
5534 /* For most processors, ADD is faster than LEA. This alternative
5535 was added to use ADD as much as possible. */
5536 if (which_alternative == 1)
5539 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5542 if (x86_maybe_negate_const_int (&operands[2], SImode))
5543 return "sub{l}\t{%2, %k0|%k0, %2}";
5545 return "add{l}\t{%2, %k0|%k0, %2}";
5549 (cond [(eq_attr "alternative" "2")
5550 (const_string "lea")
5551 (match_operand:SI 2 "incdec_operand" "")
5552 (const_string "incdec")
5554 (const_string "alu")))
5555 (set (attr "length_immediate")
5557 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5559 (const_string "*")))
5560 (set_attr "mode" "SI")])
5562 (define_insn "*addhi_1"
5563 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5564 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5565 (match_operand:HI 2 "general_operand" "rn,rm")))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_PARTIAL_REG_STALL
5568 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5570 switch (get_attr_type (insn))
5573 if (operands[2] == const1_rtx)
5574 return "inc{w}\t%0";
5577 gcc_assert (operands[2] == constm1_rtx);
5578 return "dec{w}\t%0";
5582 if (x86_maybe_negate_const_int (&operands[2], HImode))
5583 return "sub{w}\t{%2, %0|%0, %2}";
5585 return "add{w}\t{%2, %0|%0, %2}";
5589 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set (attr "length_immediate")
5594 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5596 (const_string "*")))
5597 (set_attr "mode" "HI")])
5599 (define_insn "*addhi_1_lea"
5600 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5601 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5602 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "!TARGET_PARTIAL_REG_STALL
5605 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5607 switch (get_attr_type (insn))
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{w}\t%0";
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{w}\t%0";
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], HImode))
5633 return "sub{w}\t{%2, %0|%0, %2}";
5635 return "add{w}\t{%2, %0|%0, %2}";
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:HI 2 "incdec_operand" "")
5642 (const_string "incdec")
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5649 (const_string "*")))
5650 (set_attr "mode" "HI,HI,HI,SI")])
5652 ;; %%% Potential partial reg stall on alternative 2. What to do?
5653 (define_insn "*addqi_1"
5654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5655 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5656 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5657 (clobber (reg:CC FLAGS_REG))]
5658 "TARGET_PARTIAL_REG_STALL
5659 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5661 int widen = (which_alternative == 2);
5662 switch (get_attr_type (insn))
5665 if (operands[2] == const1_rtx)
5666 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5674 if (x86_maybe_negate_const_int (&operands[2], QImode))
5677 return "sub{l}\t{%2, %k0|%k0, %2}";
5679 return "sub{b}\t{%2, %0|%0, %2}";
5682 return "add{l}\t{%k2, %k0|%k0, %k2}";
5684 return "add{b}\t{%2, %0|%0, %2}";
5688 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5689 (const_string "incdec")
5690 (const_string "alu")))
5691 (set (attr "length_immediate")
5693 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5695 (const_string "*")))
5696 (set_attr "mode" "QI,QI,SI")])
5698 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5699 (define_insn "*addqi_1_lea"
5700 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5701 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5702 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5703 (clobber (reg:CC FLAGS_REG))]
5704 "!TARGET_PARTIAL_REG_STALL
5705 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5707 int widen = (which_alternative == 3 || which_alternative == 4);
5709 switch (get_attr_type (insn))
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (operands[2] == const1_rtx)
5717 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5725 /* For most processors, ADD is faster than LEA. These alternatives
5726 were added to use ADD as much as possible. */
5727 if (which_alternative == 2 || which_alternative == 4)
5730 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 if (x86_maybe_negate_const_int (&operands[2], QImode))
5737 return "sub{l}\t{%2, %k0|%k0, %2}";
5739 return "sub{b}\t{%2, %0|%0, %2}";
5742 return "add{l}\t{%k2, %k0|%k0, %k2}";
5744 return "add{b}\t{%2, %0|%0, %2}";
5748 (cond [(eq_attr "alternative" "5")
5749 (const_string "lea")
5750 (match_operand:QI 2 "incdec_operand" "")
5751 (const_string "incdec")
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5758 (const_string "*")))
5759 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5761 (define_insn "*addqi_1_slp"
5762 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5763 (plus:QI (match_dup 0)
5764 (match_operand:QI 1 "general_operand" "qn,qnm")))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5769 switch (get_attr_type (insn))
5772 if (operands[1] == const1_rtx)
5773 return "inc{b}\t%0";
5776 gcc_assert (operands[1] == constm1_rtx);
5777 return "dec{b}\t%0";
5781 if (x86_maybe_negate_const_int (&operands[1], QImode))
5782 return "sub{b}\t{%1, %0|%0, %1}";
5784 return "add{b}\t{%1, %0|%0, %1}";
5788 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5789 (const_string "incdec")
5790 (const_string "alu1")))
5791 (set (attr "memory")
5792 (if_then_else (match_operand 1 "memory_operand" "")
5793 (const_string "load")
5794 (const_string "none")))
5795 (set_attr "mode" "QI")])
5797 ;; Convert lea to the lea pattern to avoid flags dependency.
5799 [(set (match_operand 0 "register_operand" "")
5800 (plus (match_operand 1 "register_operand" "")
5801 (match_operand 2 "nonmemory_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5807 enum machine_mode mode = GET_MODE (operands[0]);
5809 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5810 may confuse gen_lowpart. */
5813 operands[1] = gen_lowpart (Pmode, operands[1]);
5814 operands[2] = gen_lowpart (Pmode, operands[2]);
5817 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5819 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5820 operands[0] = gen_lowpart (SImode, operands[0]);
5822 if (TARGET_64BIT && mode != Pmode)
5823 pat = gen_rtx_SUBREG (SImode, pat, 0);
5825 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5829 ;; Convert lea to the lea pattern to avoid flags dependency.
5830 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5831 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5833 [(set (match_operand:DI 0 "register_operand" "")
5834 (plus:DI (match_operand:DI 1 "register_operand" "")
5835 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 "TARGET_64BIT && reload_completed
5838 && true_regnum (operands[0]) != true_regnum (operands[1])"
5840 (plus:DI (match_dup 1) (match_dup 2)))])
5842 ;; Convert lea to the lea pattern to avoid flags dependency.
5844 [(set (match_operand:DI 0 "register_operand" "")
5846 (plus:SI (match_operand:SI 1 "register_operand" "")
5847 (match_operand:SI 2 "nonmemory_operand" ""))))
5848 (clobber (reg:CC FLAGS_REG))]
5849 "TARGET_64BIT && reload_completed
5850 && ix86_lea_for_add_ok (insn, operands)"
5852 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5854 operands[1] = gen_lowpart (DImode, operands[1]);
5855 operands[2] = gen_lowpart (DImode, operands[2]);
5858 (define_insn "*add<mode>_2"
5859 [(set (reg FLAGS_REG)
5862 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5863 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5865 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5866 (plus:SWI (match_dup 1) (match_dup 2)))]
5867 "ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{<imodesuffix>}\t%0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{<imodesuffix>}\t%0";
5882 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5883 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5885 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5889 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5890 (const_string "incdec")
5891 (const_string "alu")))
5892 (set (attr "length_immediate")
5894 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5896 (const_string "*")))
5897 (set_attr "mode" "<MODE>")])
5899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5900 (define_insn "*addsi_2_zext"
5901 [(set (reg FLAGS_REG)
5903 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5904 (match_operand:SI 2 "general_operand" "g"))
5906 (set (match_operand:DI 0 "register_operand" "=r")
5907 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5908 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5909 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5911 switch (get_attr_type (insn))
5914 if (operands[2] == const1_rtx)
5915 return "inc{l}\t%k0";
5918 gcc_assert (operands[2] == constm1_rtx);
5919 return "dec{l}\t%k0";
5923 if (x86_maybe_negate_const_int (&operands[2], SImode))
5924 return "sub{l}\t{%2, %k0|%k0, %2}";
5926 return "add{l}\t{%2, %k0|%k0, %2}";
5930 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5931 (const_string "incdec")
5932 (const_string "alu")))
5933 (set (attr "length_immediate")
5935 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5937 (const_string "*")))
5938 (set_attr "mode" "SI")])
5940 (define_insn "*add<mode>_3"
5941 [(set (reg FLAGS_REG)
5943 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5944 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5945 (clobber (match_scratch:SWI 0 "=<r>"))]
5946 "ix86_match_ccmode (insn, CCZmode)
5947 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5949 switch (get_attr_type (insn))
5952 if (operands[2] == const1_rtx)
5953 return "inc{<imodesuffix>}\t%0";
5956 gcc_assert (operands[2] == constm1_rtx);
5957 return "dec{<imodesuffix>}\t%0";
5961 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5962 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5964 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5968 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set (attr "length_immediate")
5973 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5975 (const_string "*")))
5976 (set_attr "mode" "<MODE>")])
5978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5979 (define_insn "*addsi_3_zext"
5980 [(set (reg FLAGS_REG)
5982 (neg:SI (match_operand:SI 2 "general_operand" "g"))
5983 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5984 (set (match_operand:DI 0 "register_operand" "=r")
5985 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5986 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5987 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == const1_rtx)
5993 return "inc{l}\t%k0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{l}\t%k0";
6001 if (x86_maybe_negate_const_int (&operands[2], SImode))
6002 return "sub{l}\t{%2, %k0|%k0, %2}";
6004 return "add{l}\t{%2, %k0|%k0, %2}";
6008 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set (attr "length_immediate")
6013 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6015 (const_string "*")))
6016 (set_attr "mode" "SI")])
6018 ; For comparisons against 1, -1 and 128, we may generate better code
6019 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6020 ; is matched then. We can't accept general immediate, because for
6021 ; case of overflows, the result is messed up.
6022 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6023 ; only for comparisons not depending on it.
6025 (define_insn "*adddi_4"
6026 [(set (reg FLAGS_REG)
6028 (match_operand:DI 1 "nonimmediate_operand" "0")
6029 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6030 (clobber (match_scratch:DI 0 "=rm"))]
6032 && ix86_match_ccmode (insn, CCGCmode)"
6034 switch (get_attr_type (insn))
6037 if (operands[2] == constm1_rtx)
6038 return "inc{q}\t%0";
6041 gcc_assert (operands[2] == const1_rtx);
6042 return "dec{q}\t%0";
6046 if (x86_maybe_negate_const_int (&operands[2], DImode))
6047 return "add{q}\t{%2, %0|%0, %2}";
6049 return "sub{q}\t{%2, %0|%0, %2}";
6053 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6054 (const_string "incdec")
6055 (const_string "alu")))
6056 (set (attr "length_immediate")
6058 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6060 (const_string "*")))
6061 (set_attr "mode" "DI")])
6063 ; For comparisons against 1, -1 and 128, we may generate better code
6064 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6065 ; is matched then. We can't accept general immediate, because for
6066 ; case of overflows, the result is messed up.
6067 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6068 ; only for comparisons not depending on it.
6070 (define_insn "*add<mode>_4"
6071 [(set (reg FLAGS_REG)
6073 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6074 (match_operand:SWI124 2 "const_int_operand" "n")))
6075 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6076 "ix86_match_ccmode (insn, CCGCmode)"
6078 switch (get_attr_type (insn))
6081 if (operands[2] == constm1_rtx)
6082 return "inc{<imodesuffix>}\t%0";
6085 gcc_assert (operands[2] == const1_rtx);
6086 return "dec{<imodesuffix>}\t%0";
6090 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6091 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6093 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6097 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6098 (const_string "incdec")
6099 (const_string "alu")))
6100 (set (attr "length_immediate")
6102 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6104 (const_string "*")))
6105 (set_attr "mode" "<MODE>")])
6107 (define_insn "*add<mode>_5"
6108 [(set (reg FLAGS_REG)
6111 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6112 (match_operand:SWI 2 "<general_operand>" "<g>"))
6114 (clobber (match_scratch:SWI 0 "=<r>"))]
6115 "ix86_match_ccmode (insn, CCGOCmode)
6116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6118 switch (get_attr_type (insn))
6121 if (operands[2] == const1_rtx)
6122 return "inc{<imodesuffix>}\t%0";
6125 gcc_assert (operands[2] == constm1_rtx);
6126 return "dec{<imodesuffix>}\t%0";
6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138 (const_string "incdec")
6139 (const_string "alu")))
6140 (set (attr "length_immediate")
6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144 (const_string "*")))
6145 (set_attr "mode" "<MODE>")])
6147 (define_insn "*addqi_ext_1_rex64"
6148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6153 (match_operand 1 "ext_register_operand" "0")
6156 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157 (clobber (reg:CC FLAGS_REG))]
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{b}\t%h0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{b}\t%h0";
6172 return "add{b}\t{%2, %h0|%h0, %2}";
6176 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "modrm" "1")
6180 (set_attr "mode" "QI")])
6182 (define_insn "addqi_ext_1"
6183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6188 (match_operand 1 "ext_register_operand" "0")
6191 (match_operand:QI 2 "general_operand" "Qmn")))
6192 (clobber (reg:CC FLAGS_REG))]
6195 switch (get_attr_type (insn))
6198 if (operands[2] == const1_rtx)
6199 return "inc{b}\t%h0";
6202 gcc_assert (operands[2] == constm1_rtx);
6203 return "dec{b}\t%h0";
6207 return "add{b}\t{%2, %h0|%h0, %2}";
6211 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set_attr "modrm" "1")
6215 (set_attr "mode" "QI")])
6217 (define_insn "*addqi_ext_2"
6218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6223 (match_operand 1 "ext_register_operand" "%0")
6227 (match_operand 2 "ext_register_operand" "Q")
6230 (clobber (reg:CC FLAGS_REG))]
6232 "add{b}\t{%h2, %h0|%h0, %h2}"
6233 [(set_attr "type" "alu")
6234 (set_attr "mode" "QI")])
6236 ;; The lea patterns for non-Pmodes needs to be matched by
6237 ;; several insns converted to real lea by splitters.
6239 (define_insn_and_split "*lea_general_1"
6240 [(set (match_operand 0 "register_operand" "=r")
6241 (plus (plus (match_operand 1 "index_register_operand" "l")
6242 (match_operand 2 "register_operand" "r"))
6243 (match_operand 3 "immediate_operand" "i")))]
6244 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6245 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6246 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6247 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6248 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6249 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6250 || GET_MODE (operands[3]) == VOIDmode)"
6252 "&& reload_completed"
6256 operands[0] = gen_lowpart (SImode, operands[0]);
6257 operands[1] = gen_lowpart (Pmode, operands[1]);
6258 operands[2] = gen_lowpart (Pmode, operands[2]);
6259 operands[3] = gen_lowpart (Pmode, operands[3]);
6260 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6262 if (Pmode != SImode)
6263 pat = gen_rtx_SUBREG (SImode, pat, 0);
6264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6267 [(set_attr "type" "lea")
6268 (set_attr "mode" "SI")])
6270 (define_insn_and_split "*lea_general_1_zext"
6271 [(set (match_operand:DI 0 "register_operand" "=r")
6274 (match_operand:SI 1 "index_register_operand" "l")
6275 (match_operand:SI 2 "register_operand" "r"))
6276 (match_operand:SI 3 "immediate_operand" "i"))))]
6279 "&& reload_completed"
6281 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6283 (match_dup 3)) 0)))]
6285 operands[1] = gen_lowpart (Pmode, operands[1]);
6286 operands[2] = gen_lowpart (Pmode, operands[2]);
6287 operands[3] = gen_lowpart (Pmode, operands[3]);
6289 [(set_attr "type" "lea")
6290 (set_attr "mode" "SI")])
6292 (define_insn_and_split "*lea_general_2"
6293 [(set (match_operand 0 "register_operand" "=r")
6294 (plus (mult (match_operand 1 "index_register_operand" "l")
6295 (match_operand 2 "const248_operand" "i"))
6296 (match_operand 3 "nonmemory_operand" "ri")))]
6297 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6298 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6299 && (!TARGET_PARTIAL_REG_STALL
6300 || GET_MODE (operands[0]) == SImode
6301 || optimize_function_for_size_p (cfun))
6302 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6303 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6304 || GET_MODE (operands[3]) == VOIDmode)"
6306 "&& reload_completed"
6310 operands[0] = gen_lowpart (SImode, operands[0]);
6311 operands[1] = gen_lowpart (Pmode, operands[1]);
6312 operands[3] = gen_lowpart (Pmode, operands[3]);
6313 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6315 if (Pmode != SImode)
6316 pat = gen_rtx_SUBREG (SImode, pat, 0);
6317 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6320 [(set_attr "type" "lea")
6321 (set_attr "mode" "SI")])
6323 (define_insn_and_split "*lea_general_2_zext"
6324 [(set (match_operand:DI 0 "register_operand" "=r")
6327 (match_operand:SI 1 "index_register_operand" "l")
6328 (match_operand:SI 2 "const248_operand" "n"))
6329 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6332 "&& reload_completed"
6334 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6336 (match_dup 3)) 0)))]
6338 operands[1] = gen_lowpart (Pmode, operands[1]);
6339 operands[3] = gen_lowpart (Pmode, operands[3]);
6341 [(set_attr "type" "lea")
6342 (set_attr "mode" "SI")])
6344 (define_insn_and_split "*lea_general_3"
6345 [(set (match_operand 0 "register_operand" "=r")
6346 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6347 (match_operand 2 "const248_operand" "i"))
6348 (match_operand 3 "register_operand" "r"))
6349 (match_operand 4 "immediate_operand" "i")))]
6350 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6351 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6352 && (!TARGET_PARTIAL_REG_STALL
6353 || GET_MODE (operands[0]) == SImode
6354 || optimize_function_for_size_p (cfun))
6355 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6356 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6358 "&& reload_completed"
6362 operands[0] = gen_lowpart (SImode, operands[0]);
6363 operands[1] = gen_lowpart (Pmode, operands[1]);
6364 operands[3] = gen_lowpart (Pmode, operands[3]);
6365 operands[4] = gen_lowpart (Pmode, operands[4]);
6366 pat = gen_rtx_PLUS (Pmode,
6367 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6371 if (Pmode != SImode)
6372 pat = gen_rtx_SUBREG (SImode, pat, 0);
6373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6376 [(set_attr "type" "lea")
6377 (set_attr "mode" "SI")])
6379 (define_insn_and_split "*lea_general_3_zext"
6380 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (match_operand:SI 1 "index_register_operand" "l")
6385 (match_operand:SI 2 "const248_operand" "n"))
6386 (match_operand:SI 3 "register_operand" "r"))
6387 (match_operand:SI 4 "immediate_operand" "i"))))]
6390 "&& reload_completed"
6392 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6395 (match_dup 4)) 0)))]
6397 operands[1] = gen_lowpart (Pmode, operands[1]);
6398 operands[3] = gen_lowpart (Pmode, operands[3]);
6399 operands[4] = gen_lowpart (Pmode, operands[4]);
6401 [(set_attr "type" "lea")
6402 (set_attr "mode" "SI")])
6404 (define_insn_and_split "*lea_general_4"
6405 [(set (match_operand:SWI 0 "register_operand" "=r")
6406 (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6407 (match_operand:SWI 2 "const_int_operand" "n"))
6408 (match_operand 3 "const_int_operand" "n")))]
6409 "(<MODE>mode == DImode
6410 || <MODE>mode == SImode
6411 || !TARGET_PARTIAL_REG_STALL
6412 || optimize_function_for_size_p (cfun))
6413 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6414 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6415 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6417 "&& reload_completed"
6421 if (<MODE>mode != DImode)
6422 operands[0] = gen_lowpart (SImode, operands[0]);
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425 pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6427 if (Pmode != SImode && <MODE>mode != DImode)
6428 pat = gen_rtx_SUBREG (SImode, pat, 0);
6429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6432 [(set_attr "type" "lea")
6434 (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6436 (const_string "DI")))])
6438 ;; Subtract instructions
6440 (define_expand "sub<mode>3"
6441 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6442 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6443 (match_operand:SDWIM 2 "<general_operand>" "")))]
6445 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6447 (define_insn_and_split "*sub<dwi>3_doubleword"
6448 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6450 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6451 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6456 [(parallel [(set (reg:CC FLAGS_REG)
6457 (compare:CC (match_dup 1) (match_dup 2)))
6459 (minus:DWIH (match_dup 1) (match_dup 2)))])
6460 (parallel [(set (match_dup 3)
6464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6469 (define_insn "*sub<mode>_1"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6476 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "mode" "<MODE>")])
6480 (define_insn "*subsi_1_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (match_operand:SI 2 "general_operand" "g"))))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6487 "sub{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "SI")])
6491 (define_insn "*subqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (minus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qm")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6498 "sub{b}\t{%1, %0|%0, %1}"
6499 [(set_attr "type" "alu1")
6500 (set_attr "mode" "QI")])
6502 (define_insn "*sub<mode>_2"
6503 [(set (reg FLAGS_REG)
6506 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6509 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (minus:SWI (match_dup 1) (match_dup 2)))]
6511 "ix86_match_ccmode (insn, CCGOCmode)
6512 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*subsi_2_zext"
6518 [(set (reg FLAGS_REG)
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "general_operand" "g"))
6523 (set (match_operand:DI 0 "register_operand" "=r")
6525 (minus:SI (match_dup 1)
6527 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6528 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %k0|%k0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6533 (define_insn "*sub<mode>_3"
6534 [(set (reg FLAGS_REG)
6535 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6538 (minus:SWI (match_dup 1) (match_dup 2)))]
6539 "ix86_match_ccmode (insn, CCmode)
6540 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6541 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "<MODE>")])
6545 (define_insn "*subsi_3_zext"
6546 [(set (reg FLAGS_REG)
6547 (compare (match_operand:SI 1 "register_operand" "0")
6548 (match_operand:SI 2 "general_operand" "g")))
6549 (set (match_operand:DI 0 "register_operand" "=r")
6551 (minus:SI (match_dup 1)
6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555 "sub{l}\t{%2, %1|%1, %2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "SI")])
6559 ;; Add with carry and subtract with borrow
6561 (define_expand "<plusminus_insn><mode>3_carry"
6563 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6565 (match_operand:SWI 1 "nonimmediate_operand" "")
6566 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6567 [(match_operand 3 "flags_reg_operand" "")
6569 (match_operand:SWI 2 "<general_operand>" ""))))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6573 (define_insn "*<plusminus_insn><mode>3_carry"
6574 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6578 (match_operator 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)])
6580 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "<MODE>")])
6589 (define_insn "*addsi3_carry_zext"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6593 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SI 2 "general_operand" "g")))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6604 (define_insn "*subsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (minus:SI (match_operand:SI 1 "register_operand" "0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "general_operand" "g")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6613 "sbb{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "SI")])
6618 ;; Overflow setting add and subtract instructions
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6633 (define_insn "*sub<mode>3_cconly_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6637 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6638 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6641 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6642 [(set_attr "type" "icmp")
6643 (set_attr "mode" "<MODE>")])
6645 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6646 [(set (reg:CCC FLAGS_REG)
6649 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6650 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6654 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6655 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "<MODE>")])
6659 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6660 [(set (reg:CCC FLAGS_REG)
6663 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6664 (match_operand:SI 2 "general_operand" "g"))
6666 (set (match_operand:DI 0 "register_operand" "=r")
6667 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6668 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6669 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6673 ;; The patterns that match these are at the end of this file.
6675 (define_expand "<plusminus_insn>xf3"
6676 [(set (match_operand:XF 0 "register_operand" "")
6678 (match_operand:XF 1 "register_operand" "")
6679 (match_operand:XF 2 "register_operand" "")))]
6682 (define_expand "<plusminus_insn><mode>3"
6683 [(set (match_operand:MODEF 0 "register_operand" "")
6685 (match_operand:MODEF 1 "register_operand" "")
6686 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6690 ;; Multiply instructions
6692 (define_expand "mul<mode>3"
6693 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6695 (match_operand:SWIM248 1 "register_operand" "")
6696 (match_operand:SWIM248 2 "<general_operand>" "")))
6697 (clobber (reg:CC FLAGS_REG))])])
6699 (define_expand "mulqi3"
6700 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6702 (match_operand:QI 1 "register_operand" "")
6703 (match_operand:QI 2 "nonimmediate_operand" "")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_QIMODE_MATH")
6708 ;; IMUL reg32/64, reg32/64, imm8 Direct
6709 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6710 ;; IMUL reg32/64, reg32/64, imm32 Direct
6711 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6712 ;; IMUL reg32/64, reg32/64 Direct
6713 ;; IMUL reg32/64, mem32/64 Direct
6715 ;; On BDVER1, all above IMULs use DirectPath
6717 (define_insn "*mul<mode>3_1"
6718 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6720 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6721 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6728 [(set_attr "type" "imul")
6729 (set_attr "prefix_0f" "0,0,1")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (eq_attr "alternative" "1")
6734 (const_string "vector")
6735 (and (eq_attr "alternative" "2")
6736 (match_operand 1 "memory_operand" ""))
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set (attr "amdfam10_decode")
6740 (cond [(and (eq_attr "alternative" "0,1")
6741 (match_operand 1 "memory_operand" ""))
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "<MODE>")])
6747 (define_insn "*mulsi3_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6750 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6752 (clobber (reg:CC FLAGS_REG))]
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "imul")
6760 (set_attr "prefix_0f" "0,0,1")
6761 (set (attr "athlon_decode")
6762 (cond [(eq_attr "cpu" "athlon")
6763 (const_string "vector")
6764 (eq_attr "alternative" "1")
6765 (const_string "vector")
6766 (and (eq_attr "alternative" "2")
6767 (match_operand 1 "memory_operand" ""))
6768 (const_string "vector")]
6769 (const_string "direct")))
6770 (set (attr "amdfam10_decode")
6771 (cond [(and (eq_attr "alternative" "0,1")
6772 (match_operand 1 "memory_operand" ""))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "SI")])
6779 ;; IMUL reg16, reg16, imm8 VectorPath
6780 ;; IMUL reg16, mem16, imm8 VectorPath
6781 ;; IMUL reg16, reg16, imm16 VectorPath
6782 ;; IMUL reg16, mem16, imm16 VectorPath
6783 ;; IMUL reg16, reg16 Direct
6784 ;; IMUL reg16, mem16 Direct
6786 ;; On BDVER1, all HI MULs use DoublePath
6788 (define_insn "*mulhi3_1"
6789 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6790 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:HI 2 "general_operand" "K,n,mr")))
6792 (clobber (reg:CC FLAGS_REG))]
6794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1,2")
6805 (const_string "vector")]
6806 (const_string "direct")))
6807 (set (attr "amdfam10_decode")
6808 (cond [(eq_attr "alternative" "0,1")
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "double")
6812 (set_attr "mode" "HI")])
6814 ;;On AMDFAM10 and BDVER1
6818 (define_insn "*mulqi3_1"
6819 [(set (match_operand:QI 0 "register_operand" "=a")
6820 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6821 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6822 (clobber (reg:CC FLAGS_REG))]
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 [(set_attr "type" "imul")
6827 (set_attr "length_immediate" "0")
6828 (set (attr "athlon_decode")
6829 (if_then_else (eq_attr "cpu" "athlon")
6830 (const_string "vector")
6831 (const_string "direct")))
6832 (set_attr "amdfam10_decode" "direct")
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "QI")])
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6840 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6842 (match_operand:DWIH 2 "register_operand" ""))))
6843 (clobber (reg:CC FLAGS_REG))])])
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6849 (match_operand:QI 1 "nonimmediate_operand" ""))
6851 (match_operand:QI 2 "register_operand" ""))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6855 (define_insn "*<u>mul<mode><dwi>3_1"
6856 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6859 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6861 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{<imodesuffix>}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "double")))
6871 (set_attr "amdfam10_decode" "double")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "<MODE>")])
6875 (define_insn "*<u>mulqihi3_1"
6876 [(set (match_operand:HI 0 "register_operand" "=a")
6879 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6881 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "<sgnprefix>mul{b}\t%2"
6886 [(set_attr "type" "imul")
6887 (set_attr "length_immediate" "0")
6888 (set (attr "athlon_decode")
6889 (if_then_else (eq_attr "cpu" "athlon")
6890 (const_string "vector")
6891 (const_string "direct")))
6892 (set_attr "amdfam10_decode" "direct")
6893 (set_attr "bdver1_decode" "direct")
6894 (set_attr "mode" "QI")])
6896 (define_expand "<s>mul<mode>3_highpart"
6897 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6902 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6904 (match_operand:SWI48 2 "register_operand" "")))
6906 (clobber (match_scratch:SWI48 3 ""))
6907 (clobber (reg:CC FLAGS_REG))])]
6909 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6911 (define_insn "*<s>muldi3_highpart_1"
6912 [(set (match_operand:DI 0 "register_operand" "=d")
6917 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6919 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6921 (clobber (match_scratch:DI 3 "=1"))
6922 (clobber (reg:CC FLAGS_REG))]
6924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6925 "<sgnprefix>mul{q}\t%2"
6926 [(set_attr "type" "imul")
6927 (set_attr "length_immediate" "0")
6928 (set (attr "athlon_decode")
6929 (if_then_else (eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (const_string "double")))
6932 (set_attr "amdfam10_decode" "double")
6933 (set_attr "bdver1_decode" "direct")
6934 (set_attr "mode" "DI")])
6936 (define_insn "*<s>mulsi3_highpart_1"
6937 [(set (match_operand:SI 0 "register_operand" "=d")
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))]
6948 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949 "<sgnprefix>mul{l}\t%2"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "amdfam10_decode" "double")
6957 (set_attr "bdver1_decode" "direct")
6958 (set_attr "mode" "SI")])
6960 (define_insn "*<s>mulsi3_highpart_zext"
6961 [(set (match_operand:DI 0 "register_operand" "=d")
6962 (zero_extend:DI (truncate:SI
6964 (mult:DI (any_extend:DI
6965 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6967 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6969 (clobber (match_scratch:SI 3 "=1"))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{l}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "double")))
6980 (set_attr "amdfam10_decode" "double")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "SI")])
6984 ;; The patterns that match these are at the end of this file.
6986 (define_expand "mulxf3"
6987 [(set (match_operand:XF 0 "register_operand" "")
6988 (mult:XF (match_operand:XF 1 "register_operand" "")
6989 (match_operand:XF 2 "register_operand" "")))]
6992 (define_expand "mul<mode>3"
6993 [(set (match_operand:MODEF 0 "register_operand" "")
6994 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6995 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6996 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6997 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6999 ;; Divide instructions
7001 ;; The patterns that match these are at the end of this file.
7003 (define_expand "divxf3"
7004 [(set (match_operand:XF 0 "register_operand" "")
7005 (div:XF (match_operand:XF 1 "register_operand" "")
7006 (match_operand:XF 2 "register_operand" "")))]
7009 (define_expand "divdf3"
7010 [(set (match_operand:DF 0 "register_operand" "")
7011 (div:DF (match_operand:DF 1 "register_operand" "")
7012 (match_operand:DF 2 "nonimmediate_operand" "")))]
7013 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7014 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7016 (define_expand "divsf3"
7017 [(set (match_operand:SF 0 "register_operand" "")
7018 (div:SF (match_operand:SF 1 "register_operand" "")
7019 (match_operand:SF 2 "nonimmediate_operand" "")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7023 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7024 && flag_finite_math_only && !flag_trapping_math
7025 && flag_unsafe_math_optimizations)
7027 ix86_emit_swdivsf (operands[0], operands[1],
7028 operands[2], SFmode);
7033 ;; Divmod instructions.
7035 (define_expand "divmod<mode>4"
7036 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7038 (match_operand:SWIM248 1 "register_operand" "")
7039 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7040 (set (match_operand:SWIM248 3 "register_operand" "")
7041 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7042 (clobber (reg:CC FLAGS_REG))])])
7044 ;; Split with 8bit unsigned divide:
7045 ;; if (dividend an divisor are in [0-255])
7046 ;; use 8bit unsigned integer divide
7048 ;; use original integer divide
7050 [(set (match_operand:SWI48 0 "register_operand" "")
7051 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7052 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7053 (set (match_operand:SWI48 1 "register_operand" "")
7054 (mod:SWI48 (match_dup 2) (match_dup 3)))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "TARGET_USE_8BIT_IDIV
7057 && TARGET_QIMODE_MATH
7058 && can_create_pseudo_p ()
7059 && !optimize_insn_for_size_p ()"
7061 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7063 (define_insn_and_split "divmod<mode>4_1"
7064 [(set (match_operand:SWI48 0 "register_operand" "=a")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7066 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWI48 1 "register_operand" "=&d")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7070 (clobber (reg:CC FLAGS_REG))]
7074 [(parallel [(set (match_dup 1)
7075 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7076 (clobber (reg:CC FLAGS_REG))])
7077 (parallel [(set (match_dup 0)
7078 (div:SWI48 (match_dup 2) (match_dup 3)))
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7082 (clobber (reg:CC FLAGS_REG))])]
7084 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7086 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7087 operands[4] = operands[2];
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7098 (define_insn_and_split "*divmod<mode>4"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (clobber (reg:CC FLAGS_REG))]
7108 [(parallel [(set (match_dup 1)
7109 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7110 (clobber (reg:CC FLAGS_REG))])
7111 (parallel [(set (match_dup 0)
7112 (div:SWIM248 (match_dup 2) (match_dup 3)))
7114 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (clobber (reg:CC FLAGS_REG))])]
7118 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7120 if (<MODE>mode != HImode
7121 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7122 operands[4] = operands[2];
7125 /* Avoid use of cltd in favor of a mov+shift. */
7126 emit_move_insn (operands[1], operands[2]);
7127 operands[4] = operands[1];
7130 [(set_attr "type" "multi")
7131 (set_attr "mode" "<MODE>")])
7133 (define_insn "*divmod<mode>4_noext"
7134 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7135 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7136 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7137 (set (match_operand:SWIM248 1 "register_operand" "=d")
7138 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7139 (use (match_operand:SWIM248 4 "register_operand" "1"))
7140 (clobber (reg:CC FLAGS_REG))]
7142 "idiv{<imodesuffix>}\t%3"
7143 [(set_attr "type" "idiv")
7144 (set_attr "mode" "<MODE>")])
7146 (define_expand "divmodqi4"
7147 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7149 (match_operand:QI 1 "register_operand" "")
7150 (match_operand:QI 2 "nonimmediate_operand" "")))
7151 (set (match_operand:QI 3 "register_operand" "")
7152 (mod:QI (match_dup 1) (match_dup 2)))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_QIMODE_MATH"
7159 tmp0 = gen_reg_rtx (HImode);
7160 tmp1 = gen_reg_rtx (HImode);
7162 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7164 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7165 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7167 /* Extract remainder from AH. */
7168 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7169 insn = emit_move_insn (operands[3], tmp1);
7171 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7172 set_unique_reg_note (insn, REG_EQUAL, mod);
7174 /* Extract quotient from AL. */
7175 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7177 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7178 set_unique_reg_note (insn, REG_EQUAL, div);
7183 ;; Divide AX by r/m8, with result stored in
7186 ;; Change div/mod to HImode and extend the second argument to HImode
7187 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7188 ;; combine may fail.
7189 (define_insn "divmodhiqi3"
7190 [(set (match_operand:HI 0 "register_operand" "=a")
7195 (mod:HI (match_operand:HI 1 "register_operand" "0")
7197 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7201 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_QIMODE_MATH"
7205 [(set_attr "type" "idiv")
7206 (set_attr "mode" "QI")])
7208 (define_expand "udivmod<mode>4"
7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7211 (match_operand:SWIM248 1 "register_operand" "")
7212 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213 (set (match_operand:SWIM248 3 "register_operand" "")
7214 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])])
7217 ;; Split with 8bit unsigned divide:
7218 ;; if (dividend an divisor are in [0-255])
7219 ;; use 8bit unsigned integer divide
7221 ;; use original integer divide
7223 [(set (match_operand:SWI48 0 "register_operand" "")
7224 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226 (set (match_operand:SWI48 1 "register_operand" "")
7227 (umod:SWI48 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_USE_8BIT_IDIV
7230 && TARGET_QIMODE_MATH
7231 && can_create_pseudo_p ()
7232 && !optimize_insn_for_size_p ()"
7234 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7236 (define_insn_and_split "udivmod<mode>4_1"
7237 [(set (match_operand:SWI48 0 "register_operand" "=a")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240 (set (match_operand:SWI48 1 "register_operand" "=&d")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7251 (umod:SWI48 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7258 (define_insn_and_split "*udivmod<mode>4"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (clobber (reg:CC FLAGS_REG))]
7268 [(set (match_dup 1) (const_int 0))
7269 (parallel [(set (match_dup 0)
7270 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7272 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7274 (clobber (reg:CC FLAGS_REG))])]
7276 [(set_attr "type" "multi")
7277 (set_attr "mode" "<MODE>")])
7279 (define_insn "*udivmod<mode>4_noext"
7280 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7281 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7282 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWIM248 1 "register_operand" "=d")
7284 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7285 (use (match_operand:SWIM248 4 "register_operand" "1"))
7286 (clobber (reg:CC FLAGS_REG))]
7288 "div{<imodesuffix>}\t%3"
7289 [(set_attr "type" "idiv")
7290 (set_attr "mode" "<MODE>")])
7292 (define_expand "udivmodqi4"
7293 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (match_operand:QI 1 "register_operand" "")
7296 (match_operand:QI 2 "nonimmediate_operand" "")))
7297 (set (match_operand:QI 3 "register_operand" "")
7298 (umod:QI (match_dup 1) (match_dup 2)))
7299 (clobber (reg:CC FLAGS_REG))])]
7300 "TARGET_QIMODE_MATH"
7305 tmp0 = gen_reg_rtx (HImode);
7306 tmp1 = gen_reg_rtx (HImode);
7308 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7310 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7311 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7313 /* Extract remainder from AH. */
7314 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7315 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7316 insn = emit_move_insn (operands[3], tmp1);
7318 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7319 set_unique_reg_note (insn, REG_EQUAL, mod);
7321 /* Extract quotient from AL. */
7322 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7324 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7325 set_unique_reg_note (insn, REG_EQUAL, div);
7330 (define_insn "udivmodhiqi3"
7331 [(set (match_operand:HI 0 "register_operand" "=a")
7336 (mod:HI (match_operand:HI 1 "register_operand" "0")
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7342 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "TARGET_QIMODE_MATH"
7346 [(set_attr "type" "idiv")
7347 (set_attr "mode" "QI")])
7349 ;; We cannot use div/idiv for double division, because it causes
7350 ;; "division by zero" on the overflow and that's not what we expect
7351 ;; from truncate. Because true (non truncating) double division is
7352 ;; never generated, we can't create this insn anyway.
7355 ; [(set (match_operand:SI 0 "register_operand" "=a")
7357 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7359 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7360 ; (set (match_operand:SI 3 "register_operand" "=d")
7362 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7363 ; (clobber (reg:CC FLAGS_REG))]
7365 ; "div{l}\t{%2, %0|%0, %2}"
7366 ; [(set_attr "type" "idiv")])
7368 ;;- Logical AND instructions
7370 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7371 ;; Note that this excludes ah.
7373 (define_expand "testsi_ccno_1"
7374 [(set (reg:CCNO FLAGS_REG)
7376 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7377 (match_operand:SI 1 "nonmemory_operand" ""))
7380 (define_expand "testqi_ccz_1"
7381 [(set (reg:CCZ FLAGS_REG)
7382 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7383 (match_operand:QI 1 "nonmemory_operand" ""))
7386 (define_expand "testdi_ccno_1"
7387 [(set (reg:CCNO FLAGS_REG)
7389 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7390 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7392 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7394 (define_insn "*testdi_1"
7395 [(set (reg FLAGS_REG)
7398 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7399 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7404 test{l}\t{%k1, %k0|%k0, %k1}
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{q}\t{%1, %0|%0, %1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}"
7409 [(set_attr "type" "test")
7410 (set_attr "modrm" "0,1,0,1,1")
7411 (set_attr "mode" "SI,SI,DI,DI,DI")])
7413 (define_insn "*testqi_1_maybe_si"
7414 [(set (reg FLAGS_REG)
7417 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7418 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7421 && ix86_match_ccmode (insn,
7422 CONST_INT_P (operands[1])
7423 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7425 if (which_alternative == 3)
7427 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7428 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7429 return "test{l}\t{%1, %k0|%k0, %1}";
7431 return "test{b}\t{%1, %0|%0, %1}";
7433 [(set_attr "type" "test")
7434 (set_attr "modrm" "0,1,1,1")
7435 (set_attr "mode" "QI,QI,QI,SI")
7436 (set_attr "pent_pair" "uv,np,uv,np")])
7438 (define_insn "*test<mode>_1"
7439 [(set (reg FLAGS_REG)
7442 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7443 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7445 "ix86_match_ccmode (insn, CCNOmode)
7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,1")
7450 (set_attr "mode" "<MODE>")
7451 (set_attr "pent_pair" "uv,np,uv")])
7453 (define_expand "testqi_ext_ccno_0"
7454 [(set (reg:CCNO FLAGS_REG)
7458 (match_operand 0 "ext_register_operand" "")
7461 (match_operand 1 "const_int_operand" ""))
7464 (define_insn "*testqi_ext_0"
7465 [(set (reg FLAGS_REG)
7469 (match_operand 0 "ext_register_operand" "Q")
7472 (match_operand 1 "const_int_operand" "n"))
7474 "ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")
7478 (set_attr "length_immediate" "1")
7479 (set_attr "modrm" "1")
7480 (set_attr "pent_pair" "np")])
7482 (define_insn "*testqi_ext_1_rex64"
7483 [(set (reg FLAGS_REG)
7487 (match_operand 0 "ext_register_operand" "Q")
7491 (match_operand:QI 1 "register_operand" "Q")))
7493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7494 "test{b}\t{%1, %h0|%h0, %1}"
7495 [(set_attr "type" "test")
7496 (set_attr "mode" "QI")])
7498 (define_insn "*testqi_ext_1"
7499 [(set (reg FLAGS_REG)
7503 (match_operand 0 "ext_register_operand" "Q")
7507 (match_operand:QI 1 "general_operand" "Qm")))
7509 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7510 "test{b}\t{%1, %h0|%h0, %1}"
7511 [(set_attr "type" "test")
7512 (set_attr "mode" "QI")])
7514 (define_insn "*testqi_ext_2"
7515 [(set (reg FLAGS_REG)
7519 (match_operand 0 "ext_register_operand" "Q")
7523 (match_operand 1 "ext_register_operand" "Q")
7527 "ix86_match_ccmode (insn, CCNOmode)"
7528 "test{b}\t{%h1, %h0|%h0, %h1}"
7529 [(set_attr "type" "test")
7530 (set_attr "mode" "QI")])
7532 (define_insn "*testqi_ext_3_rex64"
7533 [(set (reg FLAGS_REG)
7534 (compare (zero_extract:DI
7535 (match_operand 0 "nonimmediate_operand" "rm")
7536 (match_operand:DI 1 "const_int_operand" "")
7537 (match_operand:DI 2 "const_int_operand" ""))
7540 && ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 /* Ensure that resulting mask is zero or sign extended operand. */
7544 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7545 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7546 && INTVAL (operands[1]) > 32))
7547 && (GET_MODE (operands[0]) == SImode
7548 || GET_MODE (operands[0]) == DImode
7549 || GET_MODE (operands[0]) == HImode
7550 || GET_MODE (operands[0]) == QImode)"
7553 ;; Combine likes to form bit extractions for some tests. Humor it.
7554 (define_insn "*testqi_ext_3"
7555 [(set (reg FLAGS_REG)
7556 (compare (zero_extract:SI
7557 (match_operand 0 "nonimmediate_operand" "rm")
7558 (match_operand:SI 1 "const_int_operand" "")
7559 (match_operand:SI 2 "const_int_operand" ""))
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && INTVAL (operands[1]) > 0
7563 && INTVAL (operands[2]) >= 0
7564 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7565 && (GET_MODE (operands[0]) == SImode
7566 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7567 || GET_MODE (operands[0]) == HImode
7568 || GET_MODE (operands[0]) == QImode)"
7572 [(set (match_operand 0 "flags_reg_operand" "")
7573 (match_operator 1 "compare_operator"
7575 (match_operand 2 "nonimmediate_operand" "")
7576 (match_operand 3 "const_int_operand" "")
7577 (match_operand 4 "const_int_operand" ""))
7579 "ix86_match_ccmode (insn, CCNOmode)"
7580 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7582 rtx val = operands[2];
7583 HOST_WIDE_INT len = INTVAL (operands[3]);
7584 HOST_WIDE_INT pos = INTVAL (operands[4]);
7586 enum machine_mode mode, submode;
7588 mode = GET_MODE (val);
7591 /* ??? Combine likes to put non-volatile mem extractions in QImode
7592 no matter the size of the test. So find a mode that works. */
7593 if (! MEM_VOLATILE_P (val))
7595 mode = smallest_mode_for_size (pos + len, MODE_INT);
7596 val = adjust_address (val, mode, 0);
7599 else if (GET_CODE (val) == SUBREG
7600 && (submode = GET_MODE (SUBREG_REG (val)),
7601 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7602 && pos + len <= GET_MODE_BITSIZE (submode)
7603 && GET_MODE_CLASS (submode) == MODE_INT)
7605 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7607 val = SUBREG_REG (val);
7609 else if (mode == HImode && pos + len <= 8)
7611 /* Small HImode tests can be converted to QImode. */
7613 val = gen_lowpart (QImode, val);
7616 if (len == HOST_BITS_PER_WIDE_INT)
7619 mask = ((HOST_WIDE_INT)1 << len) - 1;
7622 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7625 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7626 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7627 ;; this is relatively important trick.
7628 ;; Do the conversion only post-reload to avoid limiting of the register class
7631 [(set (match_operand 0 "flags_reg_operand" "")
7632 (match_operator 1 "compare_operator"
7633 [(and (match_operand 2 "register_operand" "")
7634 (match_operand 3 "const_int_operand" ""))
7637 && QI_REG_P (operands[2])
7638 && GET_MODE (operands[2]) != QImode
7639 && ((ix86_match_ccmode (insn, CCZmode)
7640 && !(INTVAL (operands[3]) & ~(255 << 8)))
7641 || (ix86_match_ccmode (insn, CCNOmode)
7642 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7645 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7648 "operands[2] = gen_lowpart (SImode, operands[2]);
7649 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7652 [(set (match_operand 0 "flags_reg_operand" "")
7653 (match_operator 1 "compare_operator"
7654 [(and (match_operand 2 "nonimmediate_operand" "")
7655 (match_operand 3 "const_int_operand" ""))
7658 && GET_MODE (operands[2]) != QImode
7659 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7660 && ((ix86_match_ccmode (insn, CCZmode)
7661 && !(INTVAL (operands[3]) & ~255))
7662 || (ix86_match_ccmode (insn, CCNOmode)
7663 && !(INTVAL (operands[3]) & ~127)))"
7665 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7667 "operands[2] = gen_lowpart (QImode, operands[2]);
7668 operands[3] = gen_lowpart (QImode, operands[3]);")
7670 ;; %%% This used to optimize known byte-wide and operations to memory,
7671 ;; and sometimes to QImode registers. If this is considered useful,
7672 ;; it should be done with splitters.
7674 (define_expand "and<mode>3"
7675 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7676 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7677 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7679 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7681 (define_insn "*anddi_1"
7682 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7684 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7685 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7689 switch (get_attr_type (insn))
7693 enum machine_mode mode;
7695 gcc_assert (CONST_INT_P (operands[2]));
7696 if (INTVAL (operands[2]) == 0xff)
7700 gcc_assert (INTVAL (operands[2]) == 0xffff);
7704 operands[1] = gen_lowpart (mode, operands[1]);
7706 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7708 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7712 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7713 if (get_attr_mode (insn) == MODE_SI)
7714 return "and{l}\t{%k2, %k0|%k0, %k2}";
7716 return "and{q}\t{%2, %0|%0, %2}";
7719 [(set_attr "type" "alu,alu,alu,imovx")
7720 (set_attr "length_immediate" "*,*,*,0")
7721 (set (attr "prefix_rex")
7723 (and (eq_attr "type" "imovx")
7724 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7725 (match_operand 1 "ext_QIreg_operand" "")))
7727 (const_string "*")))
7728 (set_attr "mode" "SI,DI,DI,SI")])
7730 (define_insn "*andsi_1"
7731 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7732 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7733 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "ix86_binary_operator_ok (AND, SImode, operands)"
7737 switch (get_attr_type (insn))
7741 enum machine_mode mode;
7743 gcc_assert (CONST_INT_P (operands[2]));
7744 if (INTVAL (operands[2]) == 0xff)
7748 gcc_assert (INTVAL (operands[2]) == 0xffff);
7752 operands[1] = gen_lowpart (mode, operands[1]);
7754 return "movz{bl|x}\t{%1, %0|%0, %1}";
7756 return "movz{wl|x}\t{%1, %0|%0, %1}";
7760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7761 return "and{l}\t{%2, %0|%0, %2}";
7764 [(set_attr "type" "alu,alu,imovx")
7765 (set (attr "prefix_rex")
7767 (and (eq_attr "type" "imovx")
7768 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7769 (match_operand 1 "ext_QIreg_operand" "")))
7771 (const_string "*")))
7772 (set_attr "length_immediate" "*,*,0")
7773 (set_attr "mode" "SI")])
7775 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7776 (define_insn "*andsi_1_zext"
7777 [(set (match_operand:DI 0 "register_operand" "=r")
7779 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7780 (match_operand:SI 2 "general_operand" "g"))))
7781 (clobber (reg:CC FLAGS_REG))]
7782 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7783 "and{l}\t{%2, %k0|%k0, %2}"
7784 [(set_attr "type" "alu")
7785 (set_attr "mode" "SI")])
7787 (define_insn "*andhi_1"
7788 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7789 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7790 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "ix86_binary_operator_ok (AND, HImode, operands)"
7794 switch (get_attr_type (insn))
7797 gcc_assert (CONST_INT_P (operands[2]));
7798 gcc_assert (INTVAL (operands[2]) == 0xff);
7799 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7804 return "and{w}\t{%2, %0|%0, %2}";
7807 [(set_attr "type" "alu,alu,imovx")
7808 (set_attr "length_immediate" "*,*,0")
7809 (set (attr "prefix_rex")
7811 (and (eq_attr "type" "imovx")
7812 (match_operand 1 "ext_QIreg_operand" ""))
7814 (const_string "*")))
7815 (set_attr "mode" "HI,HI,SI")])
7817 ;; %%% Potential partial reg stall on alternative 2. What to do?
7818 (define_insn "*andqi_1"
7819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7820 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7821 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7822 (clobber (reg:CC FLAGS_REG))]
7823 "ix86_binary_operator_ok (AND, QImode, operands)"
7825 and{b}\t{%2, %0|%0, %2}
7826 and{b}\t{%2, %0|%0, %2}
7827 and{l}\t{%k2, %k0|%k0, %k2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "QI,QI,SI")])
7831 (define_insn "*andqi_1_slp"
7832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7833 (and:QI (match_dup 0)
7834 (match_operand:QI 1 "general_operand" "qn,qmn")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7837 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7838 "and{b}\t{%1, %0|%0, %1}"
7839 [(set_attr "type" "alu1")
7840 (set_attr "mode" "QI")])
7843 [(set (match_operand 0 "register_operand" "")
7845 (const_int -65536)))
7846 (clobber (reg:CC FLAGS_REG))]
7847 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7848 || optimize_function_for_size_p (cfun)"
7849 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7850 "operands[1] = gen_lowpart (HImode, operands[0]);")
7853 [(set (match_operand 0 "ext_register_operand" "")
7856 (clobber (reg:CC FLAGS_REG))]
7857 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7858 && reload_completed"
7859 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7860 "operands[1] = gen_lowpart (QImode, operands[0]);")
7863 [(set (match_operand 0 "ext_register_operand" "")
7865 (const_int -65281)))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7868 && reload_completed"
7869 [(parallel [(set (zero_extract:SI (match_dup 0)
7873 (zero_extract:SI (match_dup 0)
7876 (zero_extract:SI (match_dup 0)
7879 (clobber (reg:CC FLAGS_REG))])]
7880 "operands[0] = gen_lowpart (SImode, operands[0]);")
7882 (define_insn "*anddi_2"
7883 [(set (reg FLAGS_REG)
7886 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7887 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7889 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7890 (and:DI (match_dup 1) (match_dup 2)))]
7891 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && ix86_binary_operator_ok (AND, DImode, operands)"
7894 and{l}\t{%k2, %k0|%k0, %k2}
7895 and{q}\t{%2, %0|%0, %2}
7896 and{q}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI,DI,DI")])
7900 (define_insn "*andqi_2_maybe_si"
7901 [(set (reg FLAGS_REG)
7903 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7904 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7906 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7907 (and:QI (match_dup 1) (match_dup 2)))]
7908 "ix86_binary_operator_ok (AND, QImode, operands)
7909 && ix86_match_ccmode (insn,
7910 CONST_INT_P (operands[2])
7911 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7913 if (which_alternative == 2)
7915 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7916 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7917 return "and{l}\t{%2, %k0|%k0, %2}";
7919 return "and{b}\t{%2, %0|%0, %2}";
7921 [(set_attr "type" "alu")
7922 (set_attr "mode" "QI,QI,SI")])
7924 (define_insn "*and<mode>_2"
7925 [(set (reg FLAGS_REG)
7926 (compare (and:SWI124
7927 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7928 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7930 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7931 (and:SWI124 (match_dup 1) (match_dup 2)))]
7932 "ix86_match_ccmode (insn, CCNOmode)
7933 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7934 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7935 [(set_attr "type" "alu")
7936 (set_attr "mode" "<MODE>")])
7938 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7939 (define_insn "*andsi_2_zext"
7940 [(set (reg FLAGS_REG)
7942 (match_operand:SI 1 "nonimmediate_operand" "%0")
7943 (match_operand:SI 2 "general_operand" "g"))
7945 (set (match_operand:DI 0 "register_operand" "=r")
7946 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7947 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7948 && ix86_binary_operator_ok (AND, SImode, operands)"
7949 "and{l}\t{%2, %k0|%k0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "SI")])
7953 (define_insn "*andqi_2_slp"
7954 [(set (reg FLAGS_REG)
7956 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7957 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7959 (set (strict_low_part (match_dup 0))
7960 (and:QI (match_dup 0) (match_dup 1)))]
7961 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7962 && ix86_match_ccmode (insn, CCNOmode)
7963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7964 "and{b}\t{%1, %0|%0, %1}"
7965 [(set_attr "type" "alu1")
7966 (set_attr "mode" "QI")])
7968 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7969 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7970 ;; for a QImode operand, which of course failed.
7971 (define_insn "andqi_ext_0"
7972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7977 (match_operand 1 "ext_register_operand" "0")
7980 (match_operand 2 "const_int_operand" "n")))
7981 (clobber (reg:CC FLAGS_REG))]
7983 "and{b}\t{%2, %h0|%h0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "length_immediate" "1")
7986 (set_attr "modrm" "1")
7987 (set_attr "mode" "QI")])
7989 ;; Generated by peephole translating test to and. This shows up
7990 ;; often in fp comparisons.
7991 (define_insn "*andqi_ext_0_cc"
7992 [(set (reg FLAGS_REG)
7996 (match_operand 1 "ext_register_operand" "0")
7999 (match_operand 2 "const_int_operand" "n"))
8001 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8010 "ix86_match_ccmode (insn, CCNOmode)"
8011 "and{b}\t{%2, %h0|%h0, %2}"
8012 [(set_attr "type" "alu")
8013 (set_attr "length_immediate" "1")
8014 (set_attr "modrm" "1")
8015 (set_attr "mode" "QI")])
8017 (define_insn "*andqi_ext_1_rex64"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8023 (match_operand 1 "ext_register_operand" "0")
8027 (match_operand 2 "ext_register_operand" "Q"))))
8028 (clobber (reg:CC FLAGS_REG))]
8030 "and{b}\t{%2, %h0|%h0, %2}"
8031 [(set_attr "type" "alu")
8032 (set_attr "length_immediate" "0")
8033 (set_attr "mode" "QI")])
8035 (define_insn "*andqi_ext_1"
8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8041 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand:QI 2 "general_operand" "Qm"))))
8046 (clobber (reg:CC FLAGS_REG))]
8048 "and{b}\t{%2, %h0|%h0, %2}"
8049 [(set_attr "type" "alu")
8050 (set_attr "length_immediate" "0")
8051 (set_attr "mode" "QI")])
8053 (define_insn "*andqi_ext_2"
8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059 (match_operand 1 "ext_register_operand" "%0")
8063 (match_operand 2 "ext_register_operand" "Q")
8066 (clobber (reg:CC FLAGS_REG))]
8068 "and{b}\t{%h2, %h0|%h0, %h2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "length_immediate" "0")
8071 (set_attr "mode" "QI")])
8073 ;; Convert wide AND instructions with immediate operand to shorter QImode
8074 ;; equivalents when possible.
8075 ;; Don't do the splitting with memory operands, since it introduces risk
8076 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8077 ;; for size, but that can (should?) be handled by generic code instead.
8079 [(set (match_operand 0 "register_operand" "")
8080 (and (match_operand 1 "register_operand" "")
8081 (match_operand 2 "const_int_operand" "")))
8082 (clobber (reg:CC FLAGS_REG))]
8084 && QI_REG_P (operands[0])
8085 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && !(~INTVAL (operands[2]) & ~(255 << 8))
8087 && GET_MODE (operands[0]) != QImode"
8088 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8089 (and:SI (zero_extract:SI (match_dup 1)
8090 (const_int 8) (const_int 8))
8092 (clobber (reg:CC FLAGS_REG))])]
8093 "operands[0] = gen_lowpart (SImode, operands[0]);
8094 operands[1] = gen_lowpart (SImode, operands[1]);
8095 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8097 ;; Since AND can be encoded with sign extended immediate, this is only
8098 ;; profitable when 7th bit is not set.
8100 [(set (match_operand 0 "register_operand" "")
8101 (and (match_operand 1 "general_operand" "")
8102 (match_operand 2 "const_int_operand" "")))
8103 (clobber (reg:CC FLAGS_REG))]
8105 && ANY_QI_REG_P (operands[0])
8106 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8107 && !(~INTVAL (operands[2]) & ~255)
8108 && !(INTVAL (operands[2]) & 128)
8109 && GET_MODE (operands[0]) != QImode"
8110 [(parallel [(set (strict_low_part (match_dup 0))
8111 (and:QI (match_dup 1)
8113 (clobber (reg:CC FLAGS_REG))])]
8114 "operands[0] = gen_lowpart (QImode, operands[0]);
8115 operands[1] = gen_lowpart (QImode, operands[1]);
8116 operands[2] = gen_lowpart (QImode, operands[2]);")
8118 ;; Logical inclusive and exclusive OR instructions
8120 ;; %%% This used to optimize known byte-wide and operations to memory.
8121 ;; If this is considered useful, it should be done with splitters.
8123 (define_expand "<code><mode>3"
8124 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8125 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8126 (match_operand:SWIM 2 "<general_operand>" "")))]
8128 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8130 (define_insn "*<code><mode>_1"
8131 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8133 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8134 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8137 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "<MODE>")])
8141 ;; %%% Potential partial reg stall on alternative 2. What to do?
8142 (define_insn "*<code>qi_1"
8143 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8144 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8145 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8149 <logic>{b}\t{%2, %0|%0, %2}
8150 <logic>{b}\t{%2, %0|%0, %2}
8151 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "QI,QI,SI")])
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*<code>si_1_zext"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8159 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160 (match_operand:SI 2 "general_operand" "g"))))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8163 "<logic>{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8167 (define_insn "*<code>si_1_zext_imm"
8168 [(set (match_operand:DI 0 "register_operand" "=r")
8170 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8171 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8172 (clobber (reg:CC FLAGS_REG))]
8173 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8174 "<logic>{l}\t{%2, %k0|%k0, %2}"
8175 [(set_attr "type" "alu")
8176 (set_attr "mode" "SI")])
8178 (define_insn "*<code>qi_1_slp"
8179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8180 (any_or:QI (match_dup 0)
8181 (match_operand:QI 1 "general_operand" "qmn,qn")))
8182 (clobber (reg:CC FLAGS_REG))]
8183 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8184 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8185 "<logic>{b}\t{%1, %0|%0, %1}"
8186 [(set_attr "type" "alu1")
8187 (set_attr "mode" "QI")])
8189 (define_insn "*<code><mode>_2"
8190 [(set (reg FLAGS_REG)
8191 (compare (any_or:SWI
8192 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8193 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8195 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8196 (any_or:SWI (match_dup 1) (match_dup 2)))]
8197 "ix86_match_ccmode (insn, CCNOmode)
8198 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8199 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "<MODE>")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 ;; ??? Special case for immediate operand is missing - it is tricky.
8205 (define_insn "*<code>si_2_zext"
8206 [(set (reg FLAGS_REG)
8207 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "general_operand" "g"))
8210 (set (match_operand:DI 0 "register_operand" "=r")
8211 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8212 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214 "<logic>{l}\t{%2, %k0|%k0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "mode" "SI")])
8218 (define_insn "*<code>si_2_zext_imm"
8219 [(set (reg FLAGS_REG)
8221 (match_operand:SI 1 "nonimmediate_operand" "%0")
8222 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8224 (set (match_operand:DI 0 "register_operand" "=r")
8225 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8226 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228 "<logic>{l}\t{%2, %k0|%k0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "SI")])
8232 (define_insn "*<code>qi_2_slp"
8233 [(set (reg FLAGS_REG)
8234 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8235 (match_operand:QI 1 "general_operand" "qmn,qn"))
8237 (set (strict_low_part (match_dup 0))
8238 (any_or:QI (match_dup 0) (match_dup 1)))]
8239 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8240 && ix86_match_ccmode (insn, CCNOmode)
8241 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8242 "<logic>{b}\t{%1, %0|%0, %1}"
8243 [(set_attr "type" "alu1")
8244 (set_attr "mode" "QI")])
8246 (define_insn "*<code><mode>_3"
8247 [(set (reg FLAGS_REG)
8248 (compare (any_or:SWI
8249 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SWI 2 "<general_operand>" "<g>"))
8252 (clobber (match_scratch:SWI 0 "=<r>"))]
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8255 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "<MODE>")])
8259 (define_insn "*<code>qi_ext_0"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265 (match_operand 1 "ext_register_operand" "0")
8268 (match_operand 2 "const_int_operand" "n")))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8271 "<logic>{b}\t{%2, %h0|%h0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "length_immediate" "1")
8274 (set_attr "modrm" "1")
8275 (set_attr "mode" "QI")])
8277 (define_insn "*<code>qi_ext_1_rex64"
8278 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8283 (match_operand 1 "ext_register_operand" "0")
8287 (match_operand 2 "ext_register_operand" "Q"))))
8288 (clobber (reg:CC FLAGS_REG))]
8290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8291 "<logic>{b}\t{%2, %h0|%h0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "length_immediate" "0")
8294 (set_attr "mode" "QI")])
8296 (define_insn "*<code>qi_ext_1"
8297 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8302 (match_operand 1 "ext_register_operand" "0")
8306 (match_operand:QI 2 "general_operand" "Qm"))))
8307 (clobber (reg:CC FLAGS_REG))]
8309 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8310 "<logic>{b}\t{%2, %h0|%h0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "0")
8313 (set_attr "mode" "QI")])
8315 (define_insn "*<code>qi_ext_2"
8316 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8320 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8323 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8326 (clobber (reg:CC FLAGS_REG))]
8327 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8328 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "length_immediate" "0")
8331 (set_attr "mode" "QI")])
8334 [(set (match_operand 0 "register_operand" "")
8335 (any_or (match_operand 1 "register_operand" "")
8336 (match_operand 2 "const_int_operand" "")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && QI_REG_P (operands[0])
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8341 && !(INTVAL (operands[2]) & ~(255 << 8))
8342 && GET_MODE (operands[0]) != QImode"
8343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8344 (any_or:SI (zero_extract:SI (match_dup 1)
8345 (const_int 8) (const_int 8))
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[0] = gen_lowpart (SImode, operands[0]);
8349 operands[1] = gen_lowpart (SImode, operands[1]);
8350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8352 ;; Since OR can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is set.
8355 [(set (match_operand 0 "register_operand" "")
8356 (any_or (match_operand 1 "general_operand" "")
8357 (match_operand 2 "const_int_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && ANY_QI_REG_P (operands[0])
8361 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8362 && !(INTVAL (operands[2]) & ~255)
8363 && (INTVAL (operands[2]) & 128)
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (strict_low_part (match_dup 0))
8366 (any_or:QI (match_dup 1)
8368 (clobber (reg:CC FLAGS_REG))])]
8369 "operands[0] = gen_lowpart (QImode, operands[0]);
8370 operands[1] = gen_lowpart (QImode, operands[1]);
8371 operands[2] = gen_lowpart (QImode, operands[2]);")
8373 (define_expand "xorqi_cc_ext_1"
8375 (set (reg:CCNO FLAGS_REG)
8379 (match_operand 1 "ext_register_operand" "")
8382 (match_operand:QI 2 "general_operand" ""))
8384 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8394 (define_insn "*xorqi_cc_ext_1_rex64"
8395 [(set (reg FLAGS_REG)
8399 (match_operand 1 "ext_register_operand" "0")
8402 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8404 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8414 "xor{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "modrm" "1")
8417 (set_attr "mode" "QI")])
8419 (define_insn "*xorqi_cc_ext_1"
8420 [(set (reg FLAGS_REG)
8424 (match_operand 1 "ext_register_operand" "0")
8427 (match_operand:QI 2 "general_operand" "qmn"))
8429 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8438 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8439 "xor{b}\t{%2, %h0|%h0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "modrm" "1")
8442 (set_attr "mode" "QI")])
8444 ;; Negation instructions
8446 (define_expand "neg<mode>2"
8447 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8448 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8450 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8452 (define_insn_and_split "*neg<dwi>2_doubleword"
8453 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8454 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8455 (clobber (reg:CC FLAGS_REG))]
8456 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8460 [(set (reg:CCZ FLAGS_REG)
8461 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8462 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8465 (plus:DWIH (match_dup 3)
8466 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8468 (clobber (reg:CC FLAGS_REG))])
8471 (neg:DWIH (match_dup 2)))
8472 (clobber (reg:CC FLAGS_REG))])]
8473 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8475 (define_insn "*neg<mode>2_1"
8476 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8477 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8480 "neg{<imodesuffix>}\t%0"
8481 [(set_attr "type" "negnot")
8482 (set_attr "mode" "<MODE>")])
8484 ;; Combine is quite creative about this pattern.
8485 (define_insn "*negsi2_1_zext"
8486 [(set (match_operand:DI 0 "register_operand" "=r")
8488 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8494 [(set_attr "type" "negnot")
8495 (set_attr "mode" "SI")])
8497 ;; The problem with neg is that it does not perform (compare x 0),
8498 ;; it really performs (compare 0 x), which leaves us with the zero
8499 ;; flag being the only useful item.
8501 (define_insn "*neg<mode>2_cmpz"
8502 [(set (reg:CCZ FLAGS_REG)
8504 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8507 (neg:SWI (match_dup 1)))]
8508 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8509 "neg{<imodesuffix>}\t%0"
8510 [(set_attr "type" "negnot")
8511 (set_attr "mode" "<MODE>")])
8513 (define_insn "*negsi2_cmpz_zext"
8514 [(set (reg:CCZ FLAGS_REG)
8518 (match_operand:DI 1 "register_operand" "0")
8522 (set (match_operand:DI 0 "register_operand" "=r")
8523 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8526 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8528 [(set_attr "type" "negnot")
8529 (set_attr "mode" "SI")])
8531 ;; Changing of sign for FP values is doable using integer unit too.
8533 (define_expand "<code><mode>2"
8534 [(set (match_operand:X87MODEF 0 "register_operand" "")
8535 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8536 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8537 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8539 (define_insn "*absneg<mode>2_mixed"
8540 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8541 (match_operator:MODEF 3 "absneg_operator"
8542 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8543 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8548 (define_insn "*absneg<mode>2_sse"
8549 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8550 (match_operator:MODEF 3 "absneg_operator"
8551 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8552 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8557 (define_insn "*absneg<mode>2_i387"
8558 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8559 (match_operator:X87MODEF 3 "absneg_operator"
8560 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8561 (use (match_operand 2 "" ""))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8566 (define_expand "<code>tf2"
8567 [(set (match_operand:TF 0 "register_operand" "")
8568 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8570 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8572 (define_insn "*absnegtf2_sse"
8573 [(set (match_operand:TF 0 "register_operand" "=x,x")
8574 (match_operator:TF 3 "absneg_operator"
8575 [(match_operand:TF 1 "register_operand" "0,x")]))
8576 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8577 (clobber (reg:CC FLAGS_REG))]
8581 ;; Splitters for fp abs and neg.
8584 [(set (match_operand 0 "fp_register_operand" "")
8585 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8586 (use (match_operand 2 "" ""))
8587 (clobber (reg:CC FLAGS_REG))]
8589 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8592 [(set (match_operand 0 "register_operand" "")
8593 (match_operator 3 "absneg_operator"
8594 [(match_operand 1 "register_operand" "")]))
8595 (use (match_operand 2 "nonimmediate_operand" ""))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "reload_completed && SSE_REG_P (operands[0])"
8598 [(set (match_dup 0) (match_dup 3))]
8600 enum machine_mode mode = GET_MODE (operands[0]);
8601 enum machine_mode vmode = GET_MODE (operands[2]);
8604 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8605 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8606 if (operands_match_p (operands[0], operands[2]))
8609 operands[1] = operands[2];
8612 if (GET_CODE (operands[3]) == ABS)
8613 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8615 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8620 [(set (match_operand:SF 0 "register_operand" "")
8621 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8622 (use (match_operand:V4SF 2 "" ""))
8623 (clobber (reg:CC FLAGS_REG))]
8625 [(parallel [(set (match_dup 0) (match_dup 1))
8626 (clobber (reg:CC FLAGS_REG))])]
8629 operands[0] = gen_lowpart (SImode, operands[0]);
8630 if (GET_CODE (operands[1]) == ABS)
8632 tmp = gen_int_mode (0x7fffffff, SImode);
8633 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8637 tmp = gen_int_mode (0x80000000, SImode);
8638 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8644 [(set (match_operand:DF 0 "register_operand" "")
8645 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8646 (use (match_operand 2 "" ""))
8647 (clobber (reg:CC FLAGS_REG))]
8649 [(parallel [(set (match_dup 0) (match_dup 1))
8650 (clobber (reg:CC FLAGS_REG))])]
8655 tmp = gen_lowpart (DImode, operands[0]);
8656 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8659 if (GET_CODE (operands[1]) == ABS)
8662 tmp = gen_rtx_NOT (DImode, tmp);
8666 operands[0] = gen_highpart (SImode, operands[0]);
8667 if (GET_CODE (operands[1]) == ABS)
8669 tmp = gen_int_mode (0x7fffffff, SImode);
8670 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8674 tmp = gen_int_mode (0x80000000, SImode);
8675 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8682 [(set (match_operand:XF 0 "register_operand" "")
8683 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8684 (use (match_operand 2 "" ""))
8685 (clobber (reg:CC FLAGS_REG))]
8687 [(parallel [(set (match_dup 0) (match_dup 1))
8688 (clobber (reg:CC FLAGS_REG))])]
8691 operands[0] = gen_rtx_REG (SImode,
8692 true_regnum (operands[0])
8693 + (TARGET_64BIT ? 1 : 2));
8694 if (GET_CODE (operands[1]) == ABS)
8696 tmp = GEN_INT (0x7fff);
8697 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8701 tmp = GEN_INT (0x8000);
8702 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8707 ;; Conditionalize these after reload. If they match before reload, we
8708 ;; lose the clobber and ability to use integer instructions.
8710 (define_insn "*<code><mode>2_1"
8711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8712 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8714 && (reload_completed
8715 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8716 "f<absneg_mnemonic>"
8717 [(set_attr "type" "fsgn")
8718 (set_attr "mode" "<MODE>")])
8720 (define_insn "*<code>extendsfdf2"
8721 [(set (match_operand:DF 0 "register_operand" "=f")
8722 (absneg:DF (float_extend:DF
8723 (match_operand:SF 1 "register_operand" "0"))))]
8724 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8725 "f<absneg_mnemonic>"
8726 [(set_attr "type" "fsgn")
8727 (set_attr "mode" "DF")])
8729 (define_insn "*<code>extendsfxf2"
8730 [(set (match_operand:XF 0 "register_operand" "=f")
8731 (absneg:XF (float_extend:XF
8732 (match_operand:SF 1 "register_operand" "0"))))]
8734 "f<absneg_mnemonic>"
8735 [(set_attr "type" "fsgn")
8736 (set_attr "mode" "XF")])
8738 (define_insn "*<code>extenddfxf2"
8739 [(set (match_operand:XF 0 "register_operand" "=f")
8740 (absneg:XF (float_extend:XF
8741 (match_operand:DF 1 "register_operand" "0"))))]
8743 "f<absneg_mnemonic>"
8744 [(set_attr "type" "fsgn")
8745 (set_attr "mode" "XF")])
8747 ;; Copysign instructions
8749 (define_mode_iterator CSGNMODE [SF DF TF])
8750 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8752 (define_expand "copysign<mode>3"
8753 [(match_operand:CSGNMODE 0 "register_operand" "")
8754 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8755 (match_operand:CSGNMODE 2 "register_operand" "")]
8756 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8757 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8758 "ix86_expand_copysign (operands); DONE;")
8760 (define_insn_and_split "copysign<mode>3_const"
8761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8763 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8764 (match_operand:CSGNMODE 2 "register_operand" "0")
8765 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8767 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8768 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8770 "&& reload_completed"
8772 "ix86_split_copysign_const (operands); DONE;")
8774 (define_insn "copysign<mode>3_var"
8775 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8777 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8778 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8779 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8780 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8782 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8783 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8784 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8788 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8790 [(match_operand:CSGNMODE 2 "register_operand" "")
8791 (match_operand:CSGNMODE 3 "register_operand" "")
8792 (match_operand:<CSGNVMODE> 4 "" "")
8793 (match_operand:<CSGNVMODE> 5 "" "")]
8795 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8796 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8798 && reload_completed"
8800 "ix86_split_copysign_var (operands); DONE;")
8802 ;; One complement instructions
8804 (define_expand "one_cmpl<mode>2"
8805 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8806 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8808 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8810 (define_insn "*one_cmpl<mode>2_1"
8811 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8812 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8813 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8814 "not{<imodesuffix>}\t%0"
8815 [(set_attr "type" "negnot")
8816 (set_attr "mode" "<MODE>")])
8818 ;; %%% Potential partial reg stall on alternative 1. What to do?
8819 (define_insn "*one_cmplqi2_1"
8820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8821 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8822 "ix86_unary_operator_ok (NOT, QImode, operands)"
8826 [(set_attr "type" "negnot")
8827 (set_attr "mode" "QI,SI")])
8829 ;; ??? Currently never generated - xor is used instead.
8830 (define_insn "*one_cmplsi2_1_zext"
8831 [(set (match_operand:DI 0 "register_operand" "=r")
8833 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8834 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8836 [(set_attr "type" "negnot")
8837 (set_attr "mode" "SI")])
8839 (define_insn "*one_cmpl<mode>2_2"
8840 [(set (reg FLAGS_REG)
8841 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8843 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8844 (not:SWI (match_dup 1)))]
8845 "ix86_match_ccmode (insn, CCNOmode)
8846 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8848 [(set_attr "type" "alu1")
8849 (set_attr "mode" "<MODE>")])
8852 [(set (match_operand 0 "flags_reg_operand" "")
8853 (match_operator 2 "compare_operator"
8854 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8856 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8857 (not:SWI (match_dup 3)))]
8858 "ix86_match_ccmode (insn, CCNOmode)"
8859 [(parallel [(set (match_dup 0)
8860 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8863 (xor:SWI (match_dup 3) (const_int -1)))])])
8865 ;; ??? Currently never generated - xor is used instead.
8866 (define_insn "*one_cmplsi2_2_zext"
8867 [(set (reg FLAGS_REG)
8868 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8870 (set (match_operand:DI 0 "register_operand" "=r")
8871 (zero_extend:DI (not:SI (match_dup 1))))]
8872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8873 && ix86_unary_operator_ok (NOT, SImode, operands)"
8875 [(set_attr "type" "alu1")
8876 (set_attr "mode" "SI")])
8879 [(set (match_operand 0 "flags_reg_operand" "")
8880 (match_operator 2 "compare_operator"
8881 [(not:SI (match_operand:SI 3 "register_operand" ""))
8883 (set (match_operand:DI 1 "register_operand" "")
8884 (zero_extend:DI (not:SI (match_dup 3))))]
8885 "ix86_match_ccmode (insn, CCNOmode)"
8886 [(parallel [(set (match_dup 0)
8887 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8890 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8892 ;; Shift instructions
8894 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8895 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8896 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8897 ;; from the assembler input.
8899 ;; This instruction shifts the target reg/mem as usual, but instead of
8900 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8901 ;; is a left shift double, bits are taken from the high order bits of
8902 ;; reg, else if the insn is a shift right double, bits are taken from the
8903 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8904 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8906 ;; Since sh[lr]d does not change the `reg' operand, that is done
8907 ;; separately, making all shifts emit pairs of shift double and normal
8908 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8909 ;; support a 63 bit shift, each shift where the count is in a reg expands
8910 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8912 ;; If the shift count is a constant, we need never emit more than one
8913 ;; shift pair, instead using moves and sign extension for counts greater
8916 (define_expand "ashl<mode>3"
8917 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8918 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8919 (match_operand:QI 2 "nonmemory_operand" "")))]
8921 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8923 (define_insn "*ashl<mode>3_doubleword"
8924 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8925 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8926 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8927 (clobber (reg:CC FLAGS_REG))]
8930 [(set_attr "type" "multi")])
8933 [(set (match_operand:DWI 0 "register_operand" "")
8934 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8935 (match_operand:QI 2 "nonmemory_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8939 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8941 ;; By default we don't ask for a scratch register, because when DWImode
8942 ;; values are manipulated, registers are already at a premium. But if
8943 ;; we have one handy, we won't turn it away.
8946 [(match_scratch:DWIH 3 "r")
8947 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8949 (match_operand:<DWI> 1 "nonmemory_operand" "")
8950 (match_operand:QI 2 "nonmemory_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))])
8955 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8957 (define_insn "x86_64_shld"
8958 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8959 (ior:DI (ashift:DI (match_dup 0)
8960 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8961 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8962 (minus:QI (const_int 64) (match_dup 2)))))
8963 (clobber (reg:CC FLAGS_REG))]
8965 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8966 [(set_attr "type" "ishift")
8967 (set_attr "prefix_0f" "1")
8968 (set_attr "mode" "DI")
8969 (set_attr "athlon_decode" "vector")
8970 (set_attr "amdfam10_decode" "vector")
8971 (set_attr "bdver1_decode" "vector")])
8973 (define_insn "x86_shld"
8974 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8975 (ior:SI (ashift:SI (match_dup 0)
8976 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8977 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8978 (minus:QI (const_int 32) (match_dup 2)))))
8979 (clobber (reg:CC FLAGS_REG))]
8981 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8982 [(set_attr "type" "ishift")
8983 (set_attr "prefix_0f" "1")
8984 (set_attr "mode" "SI")
8985 (set_attr "pent_pair" "np")
8986 (set_attr "athlon_decode" "vector")
8987 (set_attr "amdfam10_decode" "vector")
8988 (set_attr "bdver1_decode" "vector")])
8990 (define_expand "x86_shift<mode>_adj_1"
8991 [(set (reg:CCZ FLAGS_REG)
8992 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8995 (set (match_operand:SWI48 0 "register_operand" "")
8996 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8997 (match_operand:SWI48 1 "register_operand" "")
9000 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9001 (match_operand:SWI48 3 "register_operand" "r")
9004 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9006 (define_expand "x86_shift<mode>_adj_2"
9007 [(use (match_operand:SWI48 0 "register_operand" ""))
9008 (use (match_operand:SWI48 1 "register_operand" ""))
9009 (use (match_operand:QI 2 "register_operand" ""))]
9012 rtx label = gen_label_rtx ();
9015 emit_insn (gen_testqi_ccz_1 (operands[2],
9016 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9018 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9019 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9020 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9021 gen_rtx_LABEL_REF (VOIDmode, label),
9023 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9024 JUMP_LABEL (tmp) = label;
9026 emit_move_insn (operands[0], operands[1]);
9027 ix86_expand_clear (operands[1]);
9030 LABEL_NUSES (label) = 1;
9035 ;; Avoid useless masking of count operand.
9036 (define_insn_and_split "*ashl<mode>3_mask"
9037 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9039 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9042 (match_operand:SI 2 "nonimmediate_operand" "c")
9043 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9046 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9047 == GET_MODE_BITSIZE (<MODE>mode)-1"
9050 [(parallel [(set (match_dup 0)
9051 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9052 (clobber (reg:CC FLAGS_REG))])]
9054 if (can_create_pseudo_p ())
9055 operands [2] = force_reg (SImode, operands[2]);
9057 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9059 [(set_attr "type" "ishift")
9060 (set_attr "mode" "<MODE>")])
9062 (define_insn "*ashl<mode>3_1"
9063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9064 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9065 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9069 switch (get_attr_type (insn))
9075 gcc_assert (operands[2] == const1_rtx);
9076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9077 return "add{<imodesuffix>}\t%0, %0";
9080 if (operands[2] == const1_rtx
9081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9082 return "sal{<imodesuffix>}\t%0";
9084 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9088 (cond [(eq_attr "alternative" "1")
9089 (const_string "lea")
9090 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9092 (match_operand 0 "register_operand" ""))
9093 (match_operand 2 "const1_operand" ""))
9094 (const_string "alu")
9096 (const_string "ishift")))
9097 (set (attr "length_immediate")
9099 (ior (eq_attr "type" "alu")
9100 (and (eq_attr "type" "ishift")
9101 (and (match_operand 2 "const1_operand" "")
9102 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9105 (const_string "*")))
9106 (set_attr "mode" "<MODE>")])
9108 (define_insn "*ashlsi3_1_zext"
9109 [(set (match_operand:DI 0 "register_operand" "=r,r")
9111 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9112 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9116 switch (get_attr_type (insn))
9122 gcc_assert (operands[2] == const1_rtx);
9123 return "add{l}\t%k0, %k0";
9126 if (operands[2] == const1_rtx
9127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9128 return "sal{l}\t%k0";
9130 return "sal{l}\t{%2, %k0|%k0, %2}";
9134 (cond [(eq_attr "alternative" "1")
9135 (const_string "lea")
9136 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9138 (match_operand 2 "const1_operand" ""))
9139 (const_string "alu")
9141 (const_string "ishift")))
9142 (set (attr "length_immediate")
9144 (ior (eq_attr "type" "alu")
9145 (and (eq_attr "type" "ishift")
9146 (and (match_operand 2 "const1_operand" "")
9147 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9150 (const_string "*")))
9151 (set_attr "mode" "SI")])
9153 (define_insn "*ashlhi3_1"
9154 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9155 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9156 (match_operand:QI 2 "nonmemory_operand" "cI")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "TARGET_PARTIAL_REG_STALL
9159 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9161 switch (get_attr_type (insn))
9164 gcc_assert (operands[2] == const1_rtx);
9165 return "add{w}\t%0, %0";
9168 if (operands[2] == const1_rtx
9169 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9170 return "sal{w}\t%0";
9172 return "sal{w}\t{%2, %0|%0, %2}";
9176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9178 (match_operand 0 "register_operand" ""))
9179 (match_operand 2 "const1_operand" ""))
9180 (const_string "alu")
9182 (const_string "ishift")))
9183 (set (attr "length_immediate")
9185 (ior (eq_attr "type" "alu")
9186 (and (eq_attr "type" "ishift")
9187 (and (match_operand 2 "const1_operand" "")
9188 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9191 (const_string "*")))
9192 (set_attr "mode" "HI")])
9194 (define_insn "*ashlhi3_1_lea"
9195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9196 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9197 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9198 (clobber (reg:CC FLAGS_REG))]
9199 "!TARGET_PARTIAL_REG_STALL
9200 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9202 switch (get_attr_type (insn))
9208 gcc_assert (operands[2] == const1_rtx);
9209 return "add{w}\t%0, %0";
9212 if (operands[2] == const1_rtx
9213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9214 return "sal{w}\t%0";
9216 return "sal{w}\t{%2, %0|%0, %2}";
9220 (cond [(eq_attr "alternative" "1")
9221 (const_string "lea")
9222 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9224 (match_operand 0 "register_operand" ""))
9225 (match_operand 2 "const1_operand" ""))
9226 (const_string "alu")
9228 (const_string "ishift")))
9229 (set (attr "length_immediate")
9231 (ior (eq_attr "type" "alu")
9232 (and (eq_attr "type" "ishift")
9233 (and (match_operand 2 "const1_operand" "")
9234 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9237 (const_string "*")))
9238 (set_attr "mode" "HI,SI")])
9240 (define_insn "*ashlqi3_1"
9241 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9242 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9243 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "TARGET_PARTIAL_REG_STALL
9246 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9248 switch (get_attr_type (insn))
9251 gcc_assert (operands[2] == const1_rtx);
9252 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9253 return "add{l}\t%k0, %k0";
9255 return "add{b}\t%0, %0";
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9261 if (get_attr_mode (insn) == MODE_SI)
9262 return "sal{l}\t%k0";
9264 return "sal{b}\t%0";
9268 if (get_attr_mode (insn) == MODE_SI)
9269 return "sal{l}\t{%2, %k0|%k0, %2}";
9271 return "sal{b}\t{%2, %0|%0, %2}";
9276 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9278 (match_operand 0 "register_operand" ""))
9279 (match_operand 2 "const1_operand" ""))
9280 (const_string "alu")
9282 (const_string "ishift")))
9283 (set (attr "length_immediate")
9285 (ior (eq_attr "type" "alu")
9286 (and (eq_attr "type" "ishift")
9287 (and (match_operand 2 "const1_operand" "")
9288 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9291 (const_string "*")))
9292 (set_attr "mode" "QI,SI")])
9294 ;; %%% Potential partial reg stall on alternative 2. What to do?
9295 (define_insn "*ashlqi3_1_lea"
9296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9297 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9298 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "!TARGET_PARTIAL_REG_STALL
9301 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9303 switch (get_attr_type (insn))
9309 gcc_assert (operands[2] == const1_rtx);
9310 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9311 return "add{l}\t%k0, %k0";
9313 return "add{b}\t%0, %0";
9316 if (operands[2] == const1_rtx
9317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9319 if (get_attr_mode (insn) == MODE_SI)
9320 return "sal{l}\t%k0";
9322 return "sal{b}\t%0";
9326 if (get_attr_mode (insn) == MODE_SI)
9327 return "sal{l}\t{%2, %k0|%k0, %2}";
9329 return "sal{b}\t{%2, %0|%0, %2}";
9334 (cond [(eq_attr "alternative" "2")
9335 (const_string "lea")
9336 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9338 (match_operand 0 "register_operand" ""))
9339 (match_operand 2 "const1_operand" ""))
9340 (const_string "alu")
9342 (const_string "ishift")))
9343 (set (attr "length_immediate")
9345 (ior (eq_attr "type" "alu")
9346 (and (eq_attr "type" "ishift")
9347 (and (match_operand 2 "const1_operand" "")
9348 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9351 (const_string "*")))
9352 (set_attr "mode" "QI,SI,SI")])
9354 (define_insn "*ashlqi3_1_slp"
9355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9356 (ashift:QI (match_dup 0)
9357 (match_operand:QI 1 "nonmemory_operand" "cI")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "(optimize_function_for_size_p (cfun)
9360 || !TARGET_PARTIAL_FLAG_REG_STALL
9361 || (operands[1] == const1_rtx
9363 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9365 switch (get_attr_type (insn))
9368 gcc_assert (operands[1] == const1_rtx);
9369 return "add{b}\t%0, %0";
9372 if (operands[1] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 return "sal{b}\t%0";
9376 return "sal{b}\t{%1, %0|%0, %1}";
9380 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9382 (match_operand 0 "register_operand" ""))
9383 (match_operand 1 "const1_operand" ""))
9384 (const_string "alu")
9386 (const_string "ishift1")))
9387 (set (attr "length_immediate")
9389 (ior (eq_attr "type" "alu")
9390 (and (eq_attr "type" "ishift1")
9391 (and (match_operand 1 "const1_operand" "")
9392 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9395 (const_string "*")))
9396 (set_attr "mode" "QI")])
9398 ;; Convert lea to the lea pattern to avoid flags dependency.
9400 [(set (match_operand 0 "register_operand" "")
9401 (ashift (match_operand 1 "index_register_operand" "")
9402 (match_operand:QI 2 "const_int_operand" "")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 && true_regnum (operands[0]) != true_regnum (operands[1])"
9409 enum machine_mode mode = GET_MODE (operands[0]);
9412 operands[1] = gen_lowpart (Pmode, operands[1]);
9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9415 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9418 operands[0] = gen_lowpart (SImode, operands[0]);
9420 if (TARGET_64BIT && mode != Pmode)
9421 pat = gen_rtx_SUBREG (SImode, pat, 0);
9423 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9427 ;; Convert lea to the lea pattern to avoid flags dependency.
9429 [(set (match_operand:DI 0 "register_operand" "")
9431 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9432 (match_operand:QI 2 "const_int_operand" ""))))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "TARGET_64BIT && reload_completed
9435 && true_regnum (operands[0]) != true_regnum (operands[1])"
9437 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9439 operands[1] = gen_lowpart (DImode, operands[1]);
9440 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9443 ;; This pattern can't accept a variable shift count, since shifts by
9444 ;; zero don't affect the flags. We assume that shifts by constant
9445 ;; zero are optimized away.
9446 (define_insn "*ashl<mode>3_cmp"
9447 [(set (reg FLAGS_REG)
9449 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9450 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9452 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9453 (ashift:SWI (match_dup 1) (match_dup 2)))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[2] == const1_rtx
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9459 && ix86_match_ccmode (insn, CCGOCmode)
9460 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9462 switch (get_attr_type (insn))
9465 gcc_assert (operands[2] == const1_rtx);
9466 return "add{<imodesuffix>}\t%0, %0";
9469 if (operands[2] == const1_rtx
9470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471 return "sal{<imodesuffix>}\t%0";
9473 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9477 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9479 (match_operand 0 "register_operand" ""))
9480 (match_operand 2 "const1_operand" ""))
9481 (const_string "alu")
9483 (const_string "ishift")))
9484 (set (attr "length_immediate")
9486 (ior (eq_attr "type" "alu")
9487 (and (eq_attr "type" "ishift")
9488 (and (match_operand 2 "const1_operand" "")
9489 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9492 (const_string "*")))
9493 (set_attr "mode" "<MODE>")])
9495 (define_insn "*ashlsi3_cmp_zext"
9496 [(set (reg FLAGS_REG)
9498 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9499 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9501 (set (match_operand:DI 0 "register_operand" "=r")
9502 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9504 && (optimize_function_for_size_p (cfun)
9505 || !TARGET_PARTIAL_FLAG_REG_STALL
9506 || (operands[2] == const1_rtx
9508 || TARGET_DOUBLE_WITH_ADD)))
9509 && ix86_match_ccmode (insn, CCGOCmode)
9510 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9512 switch (get_attr_type (insn))
9515 gcc_assert (operands[2] == const1_rtx);
9516 return "add{l}\t%k0, %k0";
9519 if (operands[2] == const1_rtx
9520 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521 return "sal{l}\t%k0";
9523 return "sal{l}\t{%2, %k0|%k0, %2}";
9527 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9529 (match_operand 2 "const1_operand" ""))
9530 (const_string "alu")
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand" "")
9538 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9541 (const_string "*")))
9542 (set_attr "mode" "SI")])
9544 (define_insn "*ashl<mode>3_cconly"
9545 [(set (reg FLAGS_REG)
9547 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9548 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9550 (clobber (match_scratch:SWI 0 "=<r>"))]
9551 "(optimize_function_for_size_p (cfun)
9552 || !TARGET_PARTIAL_FLAG_REG_STALL
9553 || (operands[2] == const1_rtx
9555 || TARGET_DOUBLE_WITH_ADD)))
9556 && ix86_match_ccmode (insn, CCGOCmode)"
9558 switch (get_attr_type (insn))
9561 gcc_assert (operands[2] == const1_rtx);
9562 return "add{<imodesuffix>}\t%0, %0";
9565 if (operands[2] == const1_rtx
9566 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9567 return "sal{<imodesuffix>}\t%0";
9569 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9575 (match_operand 0 "register_operand" ""))
9576 (match_operand 2 "const1_operand" ""))
9577 (const_string "alu")
9579 (const_string "ishift")))
9580 (set (attr "length_immediate")
9582 (ior (eq_attr "type" "alu")
9583 (and (eq_attr "type" "ishift")
9584 (and (match_operand 2 "const1_operand" "")
9585 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9588 (const_string "*")))
9589 (set_attr "mode" "<MODE>")])
9591 ;; See comment above `ashl<mode>3' about how this works.
9593 (define_expand "<shiftrt_insn><mode>3"
9594 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9595 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9596 (match_operand:QI 2 "nonmemory_operand" "")))]
9598 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9600 ;; Avoid useless masking of count operand.
9601 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9602 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9604 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9607 (match_operand:SI 2 "nonimmediate_operand" "c")
9608 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9609 (clobber (reg:CC FLAGS_REG))]
9610 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9611 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9612 == GET_MODE_BITSIZE (<MODE>mode)-1"
9615 [(parallel [(set (match_dup 0)
9616 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9617 (clobber (reg:CC FLAGS_REG))])]
9619 if (can_create_pseudo_p ())
9620 operands [2] = force_reg (SImode, operands[2]);
9622 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9624 [(set_attr "type" "ishift")
9625 (set_attr "mode" "<MODE>")])
9627 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9628 [(set (match_operand:DWI 0 "register_operand" "=r")
9629 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9630 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9631 (clobber (reg:CC FLAGS_REG))]
9634 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9636 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9637 [(set_attr "type" "multi")])
9639 ;; By default we don't ask for a scratch register, because when DWImode
9640 ;; values are manipulated, registers are already at a premium. But if
9641 ;; we have one handy, we won't turn it away.
9644 [(match_scratch:DWIH 3 "r")
9645 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9647 (match_operand:<DWI> 1 "register_operand" "")
9648 (match_operand:QI 2 "nonmemory_operand" "")))
9649 (clobber (reg:CC FLAGS_REG))])
9653 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9655 (define_insn "x86_64_shrd"
9656 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9657 (ior:DI (ashiftrt:DI (match_dup 0)
9658 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9659 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9660 (minus:QI (const_int 64) (match_dup 2)))))
9661 (clobber (reg:CC FLAGS_REG))]
9663 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9664 [(set_attr "type" "ishift")
9665 (set_attr "prefix_0f" "1")
9666 (set_attr "mode" "DI")
9667 (set_attr "athlon_decode" "vector")
9668 (set_attr "amdfam10_decode" "vector")
9669 (set_attr "bdver1_decode" "vector")])
9671 (define_insn "x86_shrd"
9672 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9673 (ior:SI (ashiftrt:SI (match_dup 0)
9674 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9675 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9676 (minus:QI (const_int 32) (match_dup 2)))))
9677 (clobber (reg:CC FLAGS_REG))]
9679 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9680 [(set_attr "type" "ishift")
9681 (set_attr "prefix_0f" "1")
9682 (set_attr "mode" "SI")
9683 (set_attr "pent_pair" "np")
9684 (set_attr "athlon_decode" "vector")
9685 (set_attr "amdfam10_decode" "vector")
9686 (set_attr "bdver1_decode" "vector")])
9688 (define_insn "ashrdi3_cvt"
9689 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9690 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9691 (match_operand:QI 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "TARGET_64BIT && INTVAL (operands[2]) == 63
9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9698 sar{q}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "imovx,ishift")
9700 (set_attr "prefix_0f" "0,*")
9701 (set_attr "length_immediate" "0,*")
9702 (set_attr "modrm" "0,1")
9703 (set_attr "mode" "DI")])
9705 (define_insn "ashrsi3_cvt"
9706 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9707 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9708 (match_operand:QI 2 "const_int_operand" "")))
9709 (clobber (reg:CC FLAGS_REG))]
9710 "INTVAL (operands[2]) == 31
9711 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9712 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9715 sar{l}\t{%2, %0|%0, %2}"
9716 [(set_attr "type" "imovx,ishift")
9717 (set_attr "prefix_0f" "0,*")
9718 (set_attr "length_immediate" "0,*")
9719 (set_attr "modrm" "0,1")
9720 (set_attr "mode" "SI")])
9722 (define_insn "*ashrsi3_cvt_zext"
9723 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9725 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9726 (match_operand:QI 2 "const_int_operand" ""))))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "TARGET_64BIT && INTVAL (operands[2]) == 31
9729 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9730 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9733 sar{l}\t{%2, %k0|%k0, %2}"
9734 [(set_attr "type" "imovx,ishift")
9735 (set_attr "prefix_0f" "0,*")
9736 (set_attr "length_immediate" "0,*")
9737 (set_attr "modrm" "0,1")
9738 (set_attr "mode" "SI")])
9740 (define_expand "x86_shift<mode>_adj_3"
9741 [(use (match_operand:SWI48 0 "register_operand" ""))
9742 (use (match_operand:SWI48 1 "register_operand" ""))
9743 (use (match_operand:QI 2 "register_operand" ""))]
9746 rtx label = gen_label_rtx ();
9749 emit_insn (gen_testqi_ccz_1 (operands[2],
9750 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9752 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9753 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9754 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9755 gen_rtx_LABEL_REF (VOIDmode, label),
9757 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9758 JUMP_LABEL (tmp) = label;
9760 emit_move_insn (operands[0], operands[1]);
9761 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9762 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9764 LABEL_NUSES (label) = 1;
9769 (define_insn "*<shiftrt_insn><mode>3_1"
9770 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9771 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9772 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shiftrt>{<imodesuffix>}\t%0";
9780 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9782 [(set_attr "type" "ishift")
9783 (set (attr "length_immediate")
9785 (and (match_operand 2 "const1_operand" "")
9786 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9789 (const_string "*")))
9790 (set_attr "mode" "<MODE>")])
9792 (define_insn "*<shiftrt_insn>si3_1_zext"
9793 [(set (match_operand:DI 0 "register_operand" "=r")
9795 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9796 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9800 if (operands[2] == const1_rtx
9801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9802 return "<shiftrt>{l}\t%k0";
9804 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9806 [(set_attr "type" "ishift")
9807 (set (attr "length_immediate")
9809 (and (match_operand 2 "const1_operand" "")
9810 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9813 (const_string "*")))
9814 (set_attr "mode" "SI")])
9816 (define_insn "*<shiftrt_insn>qi3_1_slp"
9817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9818 (any_shiftrt:QI (match_dup 0)
9819 (match_operand:QI 1 "nonmemory_operand" "cI")))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "(optimize_function_for_size_p (cfun)
9822 || !TARGET_PARTIAL_REG_STALL
9823 || (operands[1] == const1_rtx
9826 if (operands[1] == const1_rtx
9827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9828 return "<shiftrt>{b}\t%0";
9830 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9832 [(set_attr "type" "ishift1")
9833 (set (attr "length_immediate")
9835 (and (match_operand 1 "const1_operand" "")
9836 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9839 (const_string "*")))
9840 (set_attr "mode" "QI")])
9842 ;; This pattern can't accept a variable shift count, since shifts by
9843 ;; zero don't affect the flags. We assume that shifts by constant
9844 ;; zero are optimized away.
9845 (define_insn "*<shiftrt_insn><mode>3_cmp"
9846 [(set (reg FLAGS_REG)
9849 (match_operand:SWI 1 "nonimmediate_operand" "0")
9850 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9853 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9854 "(optimize_function_for_size_p (cfun)
9855 || !TARGET_PARTIAL_FLAG_REG_STALL
9856 || (operands[2] == const1_rtx
9858 && ix86_match_ccmode (insn, CCGOCmode)
9859 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9861 if (operands[2] == const1_rtx
9862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9863 return "<shiftrt>{<imodesuffix>}\t%0";
9865 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9867 [(set_attr "type" "ishift")
9868 (set (attr "length_immediate")
9870 (and (match_operand 2 "const1_operand" "")
9871 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9874 (const_string "*")))
9875 (set_attr "mode" "<MODE>")])
9877 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9878 [(set (reg FLAGS_REG)
9880 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9881 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9883 (set (match_operand:DI 0 "register_operand" "=r")
9884 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9886 && (optimize_function_for_size_p (cfun)
9887 || !TARGET_PARTIAL_FLAG_REG_STALL
9888 || (operands[2] == const1_rtx
9890 && ix86_match_ccmode (insn, CCGOCmode)
9891 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shiftrt>{l}\t%k0";
9897 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9899 [(set_attr "type" "ishift")
9900 (set (attr "length_immediate")
9902 (and (match_operand 2 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9906 (const_string "*")))
9907 (set_attr "mode" "SI")])
9909 (define_insn "*<shiftrt_insn><mode>3_cconly"
9910 [(set (reg FLAGS_REG)
9913 (match_operand:SWI 1 "register_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916 (clobber (match_scratch:SWI 0 "=<r>"))]
9917 "(optimize_function_for_size_p (cfun)
9918 || !TARGET_PARTIAL_FLAG_REG_STALL
9919 || (operands[2] == const1_rtx
9921 && ix86_match_ccmode (insn, CCGOCmode)"
9923 if (operands[2] == const1_rtx
9924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925 return "<shiftrt>{<imodesuffix>}\t%0";
9927 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9929 [(set_attr "type" "ishift")
9930 (set (attr "length_immediate")
9932 (and (match_operand 2 "const1_operand" "")
9933 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9936 (const_string "*")))
9937 (set_attr "mode" "<MODE>")])
9939 ;; Rotate instructions
9941 (define_expand "<rotate_insn>ti3"
9942 [(set (match_operand:TI 0 "register_operand" "")
9943 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9944 (match_operand:QI 2 "nonmemory_operand" "")))]
9947 if (const_1_to_63_operand (operands[2], VOIDmode))
9948 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9949 (operands[0], operands[1], operands[2]));
9956 (define_expand "<rotate_insn>di3"
9957 [(set (match_operand:DI 0 "shiftdi_operand" "")
9958 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9959 (match_operand:QI 2 "nonmemory_operand" "")))]
9963 ix86_expand_binary_operator (<CODE>, DImode, operands);
9964 else if (const_1_to_31_operand (operands[2], VOIDmode))
9965 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9966 (operands[0], operands[1], operands[2]));
9973 (define_expand "<rotate_insn><mode>3"
9974 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9975 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9976 (match_operand:QI 2 "nonmemory_operand" "")))]
9978 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9980 ;; Avoid useless masking of count operand.
9981 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9982 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9984 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9987 (match_operand:SI 2 "nonimmediate_operand" "c")
9988 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9991 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9992 == GET_MODE_BITSIZE (<MODE>mode)-1"
9995 [(parallel [(set (match_dup 0)
9996 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9997 (clobber (reg:CC FLAGS_REG))])]
9999 if (can_create_pseudo_p ())
10000 operands [2] = force_reg (SImode, operands[2]);
10002 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10004 [(set_attr "type" "rotate")
10005 (set_attr "mode" "<MODE>")])
10007 ;; Implement rotation using two double-precision
10008 ;; shift instructions and a scratch register.
10010 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10011 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10012 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10013 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10014 (clobber (reg:CC FLAGS_REG))
10015 (clobber (match_scratch:DWIH 3 "=&r"))]
10019 [(set (match_dup 3) (match_dup 4))
10021 [(set (match_dup 4)
10022 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10023 (lshiftrt:DWIH (match_dup 5)
10024 (minus:QI (match_dup 6) (match_dup 2)))))
10025 (clobber (reg:CC FLAGS_REG))])
10027 [(set (match_dup 5)
10028 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10029 (lshiftrt:DWIH (match_dup 3)
10030 (minus:QI (match_dup 6) (match_dup 2)))))
10031 (clobber (reg:CC FLAGS_REG))])]
10033 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10035 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10038 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10039 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10040 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10041 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10042 (clobber (reg:CC FLAGS_REG))
10043 (clobber (match_scratch:DWIH 3 "=&r"))]
10047 [(set (match_dup 3) (match_dup 4))
10049 [(set (match_dup 4)
10050 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10051 (ashift:DWIH (match_dup 5)
10052 (minus:QI (match_dup 6) (match_dup 2)))))
10053 (clobber (reg:CC FLAGS_REG))])
10055 [(set (match_dup 5)
10056 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10057 (ashift:DWIH (match_dup 3)
10058 (minus:QI (match_dup 6) (match_dup 2)))))
10059 (clobber (reg:CC FLAGS_REG))])]
10061 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10063 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10066 (define_insn "*<rotate_insn><mode>3_1"
10067 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10068 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10069 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10073 if (operands[2] == const1_rtx
10074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10075 return "<rotate>{<imodesuffix>}\t%0";
10077 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10079 [(set_attr "type" "rotate")
10080 (set (attr "length_immediate")
10082 (and (match_operand 2 "const1_operand" "")
10083 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10086 (const_string "*")))
10087 (set_attr "mode" "<MODE>")])
10089 (define_insn "*<rotate_insn>si3_1_zext"
10090 [(set (match_operand:DI 0 "register_operand" "=r")
10092 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10093 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10097 if (operands[2] == const1_rtx
10098 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10099 return "<rotate>{l}\t%k0";
10101 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10103 [(set_attr "type" "rotate")
10104 (set (attr "length_immediate")
10106 (and (match_operand 2 "const1_operand" "")
10107 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10110 (const_string "*")))
10111 (set_attr "mode" "SI")])
10113 (define_insn "*<rotate_insn>qi3_1_slp"
10114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10115 (any_rotate:QI (match_dup 0)
10116 (match_operand:QI 1 "nonmemory_operand" "cI")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_REG_STALL
10120 || (operands[1] == const1_rtx
10121 && TARGET_SHIFT1))"
10123 if (operands[1] == const1_rtx
10124 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10125 return "<rotate>{b}\t%0";
10127 return "<rotate>{b}\t{%1, %0|%0, %1}";
10129 [(set_attr "type" "rotate1")
10130 (set (attr "length_immediate")
10132 (and (match_operand 1 "const1_operand" "")
10133 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10136 (const_string "*")))
10137 (set_attr "mode" "QI")])
10140 [(set (match_operand:HI 0 "register_operand" "")
10141 (any_rotate:HI (match_dup 0) (const_int 8)))
10142 (clobber (reg:CC FLAGS_REG))]
10144 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10145 [(parallel [(set (strict_low_part (match_dup 0))
10146 (bswap:HI (match_dup 0)))
10147 (clobber (reg:CC FLAGS_REG))])])
10149 ;; Bit set / bit test instructions
10151 (define_expand "extv"
10152 [(set (match_operand:SI 0 "register_operand" "")
10153 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10154 (match_operand:SI 2 "const8_operand" "")
10155 (match_operand:SI 3 "const8_operand" "")))]
10158 /* Handle extractions from %ah et al. */
10159 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10162 /* From mips.md: extract_bit_field doesn't verify that our source
10163 matches the predicate, so check it again here. */
10164 if (! ext_register_operand (operands[1], VOIDmode))
10168 (define_expand "extzv"
10169 [(set (match_operand:SI 0 "register_operand" "")
10170 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10171 (match_operand:SI 2 "const8_operand" "")
10172 (match_operand:SI 3 "const8_operand" "")))]
10175 /* Handle extractions from %ah et al. */
10176 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10179 /* From mips.md: extract_bit_field doesn't verify that our source
10180 matches the predicate, so check it again here. */
10181 if (! ext_register_operand (operands[1], VOIDmode))
10185 (define_expand "insv"
10186 [(set (zero_extract (match_operand 0 "register_operand" "")
10187 (match_operand 1 "const_int_operand" "")
10188 (match_operand 2 "const_int_operand" ""))
10189 (match_operand 3 "register_operand" ""))]
10192 rtx (*gen_mov_insv_1) (rtx, rtx);
10194 if (ix86_expand_pinsr (operands))
10197 /* Handle insertions to %ah et al. */
10198 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10201 /* From mips.md: insert_bit_field doesn't verify that our source
10202 matches the predicate, so check it again here. */
10203 if (! ext_register_operand (operands[0], VOIDmode))
10206 gen_mov_insv_1 = (TARGET_64BIT
10207 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10209 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10213 ;; %%% bts, btr, btc, bt.
10214 ;; In general these instructions are *slow* when applied to memory,
10215 ;; since they enforce atomic operation. When applied to registers,
10216 ;; it depends on the cpu implementation. They're never faster than
10217 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10218 ;; no point. But in 64-bit, we can't hold the relevant immediates
10219 ;; within the instruction itself, so operating on bits in the high
10220 ;; 32-bits of a register becomes easier.
10222 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10223 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10224 ;; negdf respectively, so they can never be disabled entirely.
10226 (define_insn "*btsq"
10227 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10229 (match_operand:DI 1 "const_0_to_63_operand" ""))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10233 "bts{q}\t{%1, %0|%0, %1}"
10234 [(set_attr "type" "alu1")
10235 (set_attr "prefix_0f" "1")
10236 (set_attr "mode" "DI")])
10238 (define_insn "*btrq"
10239 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10241 (match_operand:DI 1 "const_0_to_63_operand" ""))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10245 "btr{q}\t{%1, %0|%0, %1}"
10246 [(set_attr "type" "alu1")
10247 (set_attr "prefix_0f" "1")
10248 (set_attr "mode" "DI")])
10250 (define_insn "*btcq"
10251 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10253 (match_operand:DI 1 "const_0_to_63_operand" ""))
10254 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10255 (clobber (reg:CC FLAGS_REG))]
10256 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10257 "btc{q}\t{%1, %0|%0, %1}"
10258 [(set_attr "type" "alu1")
10259 (set_attr "prefix_0f" "1")
10260 (set_attr "mode" "DI")])
10262 ;; Allow Nocona to avoid these instructions if a register is available.
10265 [(match_scratch:DI 2 "r")
10266 (parallel [(set (zero_extract:DI
10267 (match_operand:DI 0 "register_operand" "")
10269 (match_operand:DI 1 "const_0_to_63_operand" ""))
10271 (clobber (reg:CC FLAGS_REG))])]
10272 "TARGET_64BIT && !TARGET_USE_BT"
10275 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10278 if (HOST_BITS_PER_WIDE_INT >= 64)
10279 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10280 else if (i < HOST_BITS_PER_WIDE_INT)
10281 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10283 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10285 op1 = immed_double_const (lo, hi, DImode);
10288 emit_move_insn (operands[2], op1);
10292 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10297 [(match_scratch:DI 2 "r")
10298 (parallel [(set (zero_extract:DI
10299 (match_operand:DI 0 "register_operand" "")
10301 (match_operand:DI 1 "const_0_to_63_operand" ""))
10303 (clobber (reg:CC FLAGS_REG))])]
10304 "TARGET_64BIT && !TARGET_USE_BT"
10307 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10310 if (HOST_BITS_PER_WIDE_INT >= 64)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 else if (i < HOST_BITS_PER_WIDE_INT)
10313 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10315 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10317 op1 = immed_double_const (~lo, ~hi, DImode);
10320 emit_move_insn (operands[2], op1);
10324 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10329 [(match_scratch:DI 2 "r")
10330 (parallel [(set (zero_extract:DI
10331 (match_operand:DI 0 "register_operand" "")
10333 (match_operand:DI 1 "const_0_to_63_operand" ""))
10334 (not:DI (zero_extract:DI
10335 (match_dup 0) (const_int 1) (match_dup 1))))
10336 (clobber (reg:CC FLAGS_REG))])]
10337 "TARGET_64BIT && !TARGET_USE_BT"
10340 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10343 if (HOST_BITS_PER_WIDE_INT >= 64)
10344 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10345 else if (i < HOST_BITS_PER_WIDE_INT)
10346 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10348 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10350 op1 = immed_double_const (lo, hi, DImode);
10353 emit_move_insn (operands[2], op1);
10357 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10361 (define_insn "*bt<mode>"
10362 [(set (reg:CCC FLAGS_REG)
10364 (zero_extract:SWI48
10365 (match_operand:SWI48 0 "register_operand" "r")
10367 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10369 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10370 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10371 [(set_attr "type" "alu1")
10372 (set_attr "prefix_0f" "1")
10373 (set_attr "mode" "<MODE>")])
10375 ;; Store-flag instructions.
10377 ;; For all sCOND expanders, also expand the compare or test insn that
10378 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10380 (define_insn_and_split "*setcc_di_1"
10381 [(set (match_operand:DI 0 "register_operand" "=q")
10382 (match_operator:DI 1 "ix86_comparison_operator"
10383 [(reg FLAGS_REG) (const_int 0)]))]
10384 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10386 "&& reload_completed"
10387 [(set (match_dup 2) (match_dup 1))
10388 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10390 PUT_MODE (operands[1], QImode);
10391 operands[2] = gen_lowpart (QImode, operands[0]);
10394 (define_insn_and_split "*setcc_si_1_and"
10395 [(set (match_operand:SI 0 "register_operand" "=q")
10396 (match_operator:SI 1 "ix86_comparison_operator"
10397 [(reg FLAGS_REG) (const_int 0)]))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "!TARGET_PARTIAL_REG_STALL
10400 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10402 "&& reload_completed"
10403 [(set (match_dup 2) (match_dup 1))
10404 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10405 (clobber (reg:CC FLAGS_REG))])]
10407 PUT_MODE (operands[1], QImode);
10408 operands[2] = gen_lowpart (QImode, operands[0]);
10411 (define_insn_and_split "*setcc_si_1_movzbl"
10412 [(set (match_operand:SI 0 "register_operand" "=q")
10413 (match_operator:SI 1 "ix86_comparison_operator"
10414 [(reg FLAGS_REG) (const_int 0)]))]
10415 "!TARGET_PARTIAL_REG_STALL
10416 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10418 "&& reload_completed"
10419 [(set (match_dup 2) (match_dup 1))
10420 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10422 PUT_MODE (operands[1], QImode);
10423 operands[2] = gen_lowpart (QImode, operands[0]);
10426 (define_insn "*setcc_qi"
10427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10428 (match_operator:QI 1 "ix86_comparison_operator"
10429 [(reg FLAGS_REG) (const_int 0)]))]
10432 [(set_attr "type" "setcc")
10433 (set_attr "mode" "QI")])
10435 (define_insn "*setcc_qi_slp"
10436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10437 (match_operator:QI 1 "ix86_comparison_operator"
10438 [(reg FLAGS_REG) (const_int 0)]))]
10441 [(set_attr "type" "setcc")
10442 (set_attr "mode" "QI")])
10444 ;; In general it is not safe to assume too much about CCmode registers,
10445 ;; so simplify-rtx stops when it sees a second one. Under certain
10446 ;; conditions this is safe on x86, so help combine not create
10453 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10454 (ne:QI (match_operator 1 "ix86_comparison_operator"
10455 [(reg FLAGS_REG) (const_int 0)])
10458 [(set (match_dup 0) (match_dup 1))]
10459 "PUT_MODE (operands[1], QImode);")
10462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10463 (ne:QI (match_operator 1 "ix86_comparison_operator"
10464 [(reg FLAGS_REG) (const_int 0)])
10467 [(set (match_dup 0) (match_dup 1))]
10468 "PUT_MODE (operands[1], QImode);")
10471 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10472 (eq:QI (match_operator 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)])
10476 [(set (match_dup 0) (match_dup 1))]
10478 rtx new_op1 = copy_rtx (operands[1]);
10479 operands[1] = new_op1;
10480 PUT_MODE (new_op1, QImode);
10481 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10482 GET_MODE (XEXP (new_op1, 0))));
10484 /* Make sure that (a) the CCmode we have for the flags is strong
10485 enough for the reversed compare or (b) we have a valid FP compare. */
10486 if (! ix86_comparison_operator (new_op1, VOIDmode))
10491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10492 (eq:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10496 [(set (match_dup 0) (match_dup 1))]
10498 rtx new_op1 = copy_rtx (operands[1]);
10499 operands[1] = new_op1;
10500 PUT_MODE (new_op1, QImode);
10501 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10502 GET_MODE (XEXP (new_op1, 0))));
10504 /* Make sure that (a) the CCmode we have for the flags is strong
10505 enough for the reversed compare or (b) we have a valid FP compare. */
10506 if (! ix86_comparison_operator (new_op1, VOIDmode))
10510 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10511 ;; subsequent logical operations are used to imitate conditional moves.
10512 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10515 (define_insn "setcc_<mode>_sse"
10516 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10517 (match_operator:MODEF 3 "sse_comparison_operator"
10518 [(match_operand:MODEF 1 "register_operand" "0,x")
10519 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10520 "SSE_FLOAT_MODE_P (<MODE>mode)"
10522 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10523 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10524 [(set_attr "isa" "noavx,avx")
10525 (set_attr "type" "ssecmp")
10526 (set_attr "length_immediate" "1")
10527 (set_attr "prefix" "orig,vex")
10528 (set_attr "mode" "<MODE>")])
10530 ;; Basic conditional jump instructions.
10531 ;; We ignore the overflow flag for signed branch instructions.
10533 (define_insn "*jcc_1"
10535 (if_then_else (match_operator 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)])
10537 (label_ref (match_operand 0 "" ""))
10541 [(set_attr "type" "ibr")
10542 (set_attr "modrm" "0")
10543 (set (attr "length")
10544 (if_then_else (and (ge (minus (match_dup 0) (pc))
10546 (lt (minus (match_dup 0) (pc))
10551 (define_insn "*jcc_2"
10553 (if_then_else (match_operator 1 "ix86_comparison_operator"
10554 [(reg FLAGS_REG) (const_int 0)])
10556 (label_ref (match_operand 0 "" ""))))]
10559 [(set_attr "type" "ibr")
10560 (set_attr "modrm" "0")
10561 (set (attr "length")
10562 (if_then_else (and (ge (minus (match_dup 0) (pc))
10564 (lt (minus (match_dup 0) (pc))
10569 ;; In general it is not safe to assume too much about CCmode registers,
10570 ;; so simplify-rtx stops when it sees a second one. Under certain
10571 ;; conditions this is safe on x86, so help combine not create
10579 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10580 [(reg FLAGS_REG) (const_int 0)])
10582 (label_ref (match_operand 1 "" ""))
10586 (if_then_else (match_dup 0)
10587 (label_ref (match_dup 1))
10589 "PUT_MODE (operands[0], VOIDmode);")
10593 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)])
10596 (label_ref (match_operand 1 "" ""))
10600 (if_then_else (match_dup 0)
10601 (label_ref (match_dup 1))
10604 rtx new_op0 = copy_rtx (operands[0]);
10605 operands[0] = new_op0;
10606 PUT_MODE (new_op0, VOIDmode);
10607 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10608 GET_MODE (XEXP (new_op0, 0))));
10610 /* Make sure that (a) the CCmode we have for the flags is strong
10611 enough for the reversed compare or (b) we have a valid FP compare. */
10612 if (! ix86_comparison_operator (new_op0, VOIDmode))
10616 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10617 ;; pass generates from shift insn with QImode operand. Actually, the mode
10618 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10619 ;; appropriate modulo of the bit offset value.
10621 (define_insn_and_split "*jcc_bt<mode>"
10623 (if_then_else (match_operator 0 "bt_comparison_operator"
10624 [(zero_extract:SWI48
10625 (match_operand:SWI48 1 "register_operand" "r")
10628 (match_operand:QI 2 "register_operand" "r")))
10630 (label_ref (match_operand 3 "" ""))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10636 [(set (reg:CCC FLAGS_REG)
10638 (zero_extract:SWI48
10644 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10645 (label_ref (match_dup 3))
10648 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10650 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10653 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10654 ;; also for DImode, this is what combine produces.
10655 (define_insn_and_split "*jcc_bt<mode>_mask"
10657 (if_then_else (match_operator 0 "bt_comparison_operator"
10658 [(zero_extract:SWI48
10659 (match_operand:SWI48 1 "register_operand" "r")
10662 (match_operand:SI 2 "register_operand" "r")
10663 (match_operand:SI 3 "const_int_operand" "n")))])
10664 (label_ref (match_operand 4 "" ""))
10666 (clobber (reg:CC FLAGS_REG))]
10667 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10668 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10669 == GET_MODE_BITSIZE (<MODE>mode)-1"
10672 [(set (reg:CCC FLAGS_REG)
10674 (zero_extract:SWI48
10680 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10681 (label_ref (match_dup 4))
10684 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10686 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10689 (define_insn_and_split "*jcc_btsi_1"
10691 (if_then_else (match_operator 0 "bt_comparison_operator"
10694 (match_operand:SI 1 "register_operand" "r")
10695 (match_operand:QI 2 "register_operand" "r"))
10698 (label_ref (match_operand 3 "" ""))
10700 (clobber (reg:CC FLAGS_REG))]
10701 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10704 [(set (reg:CCC FLAGS_REG)
10712 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10713 (label_ref (match_dup 3))
10716 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10718 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10721 ;; avoid useless masking of bit offset operand
10722 (define_insn_and_split "*jcc_btsi_mask_1"
10725 (match_operator 0 "bt_comparison_operator"
10728 (match_operand:SI 1 "register_operand" "r")
10731 (match_operand:SI 2 "register_operand" "r")
10732 (match_operand:SI 3 "const_int_operand" "n")) 0))
10735 (label_ref (match_operand 4 "" ""))
10737 (clobber (reg:CC FLAGS_REG))]
10738 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10739 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10742 [(set (reg:CCC FLAGS_REG)
10750 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10751 (label_ref (match_dup 4))
10753 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10755 ;; Define combination compare-and-branch fp compare instructions to help
10758 (define_insn "*fp_jcc_1_387"
10760 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10761 [(match_operand 1 "register_operand" "f")
10762 (match_operand 2 "nonimmediate_operand" "fm")])
10763 (label_ref (match_operand 3 "" ""))
10765 (clobber (reg:CCFP FPSR_REG))
10766 (clobber (reg:CCFP FLAGS_REG))
10767 (clobber (match_scratch:HI 4 "=a"))]
10769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10771 && SELECT_CC_MODE (GET_CODE (operands[0]),
10772 operands[1], operands[2]) == CCFPmode
10776 (define_insn "*fp_jcc_1r_387"
10778 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10779 [(match_operand 1 "register_operand" "f")
10780 (match_operand 2 "nonimmediate_operand" "fm")])
10782 (label_ref (match_operand 3 "" ""))))
10783 (clobber (reg:CCFP FPSR_REG))
10784 (clobber (reg:CCFP FLAGS_REG))
10785 (clobber (match_scratch:HI 4 "=a"))]
10787 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10789 && SELECT_CC_MODE (GET_CODE (operands[0]),
10790 operands[1], operands[2]) == CCFPmode
10794 (define_insn "*fp_jcc_2_387"
10796 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10797 [(match_operand 1 "register_operand" "f")
10798 (match_operand 2 "register_operand" "f")])
10799 (label_ref (match_operand 3 "" ""))
10801 (clobber (reg:CCFP FPSR_REG))
10802 (clobber (reg:CCFP FLAGS_REG))
10803 (clobber (match_scratch:HI 4 "=a"))]
10804 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10809 (define_insn "*fp_jcc_2r_387"
10811 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10812 [(match_operand 1 "register_operand" "f")
10813 (match_operand 2 "register_operand" "f")])
10815 (label_ref (match_operand 3 "" ""))))
10816 (clobber (reg:CCFP FPSR_REG))
10817 (clobber (reg:CCFP FLAGS_REG))
10818 (clobber (match_scratch:HI 4 "=a"))]
10819 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10820 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10824 (define_insn "*fp_jcc_3_387"
10826 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10827 [(match_operand 1 "register_operand" "f")
10828 (match_operand 2 "const0_operand" "")])
10829 (label_ref (match_operand 3 "" ""))
10831 (clobber (reg:CCFP FPSR_REG))
10832 (clobber (reg:CCFP FLAGS_REG))
10833 (clobber (match_scratch:HI 4 "=a"))]
10834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10836 && SELECT_CC_MODE (GET_CODE (operands[0]),
10837 operands[1], operands[2]) == CCFPmode
10843 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10844 [(match_operand 1 "register_operand" "")
10845 (match_operand 2 "nonimmediate_operand" "")])
10846 (match_operand 3 "" "")
10847 (match_operand 4 "" "")))
10848 (clobber (reg:CCFP FPSR_REG))
10849 (clobber (reg:CCFP FLAGS_REG))]
10853 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10854 operands[3], operands[4], NULL_RTX, NULL_RTX);
10860 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10861 [(match_operand 1 "register_operand" "")
10862 (match_operand 2 "general_operand" "")])
10863 (match_operand 3 "" "")
10864 (match_operand 4 "" "")))
10865 (clobber (reg:CCFP FPSR_REG))
10866 (clobber (reg:CCFP FLAGS_REG))
10867 (clobber (match_scratch:HI 5 "=a"))]
10871 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10872 operands[3], operands[4], operands[5], NULL_RTX);
10876 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10877 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10878 ;; with a precedence over other operators and is always put in the first
10879 ;; place. Swap condition and operands to match ficom instruction.
10881 (define_insn "*fp_jcc_4_<mode>_387"
10884 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10885 [(match_operator 1 "float_operator"
10886 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10887 (match_operand 3 "register_operand" "f,f")])
10888 (label_ref (match_operand 4 "" ""))
10890 (clobber (reg:CCFP FPSR_REG))
10891 (clobber (reg:CCFP FLAGS_REG))
10892 (clobber (match_scratch:HI 5 "=a,a"))]
10893 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10894 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10895 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10896 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10903 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10904 [(match_operator 1 "float_operator"
10905 [(match_operand:SWI24 2 "memory_operand" "")])
10906 (match_operand 3 "register_operand" "")])
10907 (match_operand 4 "" "")
10908 (match_operand 5 "" "")))
10909 (clobber (reg:CCFP FPSR_REG))
10910 (clobber (reg:CCFP FLAGS_REG))
10911 (clobber (match_scratch:HI 6 "=a"))]
10915 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10917 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10918 operands[3], operands[7],
10919 operands[4], operands[5], operands[6], NULL_RTX);
10923 ;; %%% Kill this when reload knows how to do it.
10927 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10928 [(match_operator 1 "float_operator"
10929 [(match_operand:SWI24 2 "register_operand" "")])
10930 (match_operand 3 "register_operand" "")])
10931 (match_operand 4 "" "")
10932 (match_operand 5 "" "")))
10933 (clobber (reg:CCFP FPSR_REG))
10934 (clobber (reg:CCFP FLAGS_REG))
10935 (clobber (match_scratch:HI 6 "=a"))]
10939 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10940 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10942 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10943 operands[3], operands[7],
10944 operands[4], operands[5], operands[6], operands[2]);
10948 ;; Unconditional and other jump instructions
10950 (define_insn "jump"
10952 (label_ref (match_operand 0 "" "")))]
10955 [(set_attr "type" "ibr")
10956 (set (attr "length")
10957 (if_then_else (and (ge (minus (match_dup 0) (pc))
10959 (lt (minus (match_dup 0) (pc))
10963 (set_attr "modrm" "0")])
10965 (define_expand "indirect_jump"
10966 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))])
10968 (define_insn "*indirect_jump"
10969 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10972 [(set_attr "type" "ibr")
10973 (set_attr "length_immediate" "0")])
10975 (define_expand "tablejump"
10976 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10977 (use (label_ref (match_operand 1 "" "")))])]
10980 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10981 relative. Convert the relative address to an absolute address. */
10985 enum rtx_code code;
10987 /* We can't use @GOTOFF for text labels on VxWorks;
10988 see gotoff_operand. */
10989 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10993 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10995 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10999 op1 = pic_offset_table_rtx;
11004 op0 = pic_offset_table_rtx;
11008 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11013 (define_insn "*tablejump_1"
11014 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11015 (use (label_ref (match_operand 1 "" "")))]
11018 [(set_attr "type" "ibr")
11019 (set_attr "length_immediate" "0")])
11021 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
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 (set (match_operand 3 "q_regs_operand" "")
11029 (zero_extend (match_dup 1)))]
11030 "(peep2_reg_dead_p (3, operands[1])
11031 || operands_match_p (operands[1], operands[3]))
11032 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11033 [(set (match_dup 4) (match_dup 0))
11034 (set (strict_low_part (match_dup 5))
11037 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11038 operands[5] = gen_lowpart (QImode, operands[3]);
11039 ix86_expand_clear (operands[3]);
11042 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11045 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11046 (set (match_operand:QI 1 "register_operand" "")
11047 (match_operator:QI 2 "ix86_comparison_operator"
11048 [(reg FLAGS_REG) (const_int 0)]))
11049 (parallel [(set (match_operand 3 "q_regs_operand" "")
11050 (zero_extend (match_dup 1)))
11051 (clobber (reg:CC FLAGS_REG))])]
11052 "(peep2_reg_dead_p (3, operands[1])
11053 || operands_match_p (operands[1], operands[3]))
11054 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11055 [(set (match_dup 4) (match_dup 0))
11056 (set (strict_low_part (match_dup 5))
11059 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11060 operands[5] = gen_lowpart (QImode, operands[3]);
11061 ix86_expand_clear (operands[3]);
11064 ;; Call instructions.
11066 ;; The predicates normally associated with named expanders are not properly
11067 ;; checked for calls. This is a bug in the generic code, but it isn't that
11068 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11070 ;; P6 processors will jump to the address after the decrement when %esp
11071 ;; is used as a call operand, so they will execute return address as a code.
11072 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11074 ;; Register constraint for call instruction.
11075 (define_mode_attr c [(SI "l") (DI "r")])
11077 ;; Call subroutine returning no value.
11079 (define_expand "call"
11080 [(call (match_operand:QI 0 "" "")
11081 (match_operand 1 "" ""))
11082 (use (match_operand 2 "" ""))]
11085 ix86_expand_call (NULL, operands[0], operands[1],
11086 operands[2], NULL, false);
11090 (define_expand "sibcall"
11091 [(call (match_operand:QI 0 "" "")
11092 (match_operand 1 "" ""))
11093 (use (match_operand 2 "" ""))]
11096 ix86_expand_call (NULL, operands[0], operands[1],
11097 operands[2], NULL, true);
11101 (define_insn_and_split "*call_vzeroupper"
11102 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11103 (match_operand 1 "" ""))
11104 (unspec [(match_operand 2 "const_int_operand" "")]
11105 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11106 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11108 "&& reload_completed"
11110 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11111 [(set_attr "type" "call")])
11113 (define_insn "*call"
11114 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11115 (match_operand 1 "" ""))]
11116 "!SIBLING_CALL_P (insn)"
11117 "* return ix86_output_call_insn (insn, operands[0]);"
11118 [(set_attr "type" "call")])
11120 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11122 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11123 (match_operand 1 "" ""))
11124 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11125 (clobber (reg:TI XMM6_REG))
11126 (clobber (reg:TI XMM7_REG))
11127 (clobber (reg:TI XMM8_REG))
11128 (clobber (reg:TI XMM9_REG))
11129 (clobber (reg:TI XMM10_REG))
11130 (clobber (reg:TI XMM11_REG))
11131 (clobber (reg:TI XMM12_REG))
11132 (clobber (reg:TI XMM13_REG))
11133 (clobber (reg:TI XMM14_REG))
11134 (clobber (reg:TI XMM15_REG))
11135 (clobber (reg:DI SI_REG))
11136 (clobber (reg:DI DI_REG))])
11137 (unspec [(match_operand 2 "const_int_operand" "")]
11138 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11139 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11141 "&& reload_completed"
11143 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11144 [(set_attr "type" "call")])
11146 (define_insn "*call_rex64_ms_sysv"
11147 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11148 (match_operand 1 "" ""))
11149 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11150 (clobber (reg:TI XMM6_REG))
11151 (clobber (reg:TI XMM7_REG))
11152 (clobber (reg:TI XMM8_REG))
11153 (clobber (reg:TI XMM9_REG))
11154 (clobber (reg:TI XMM10_REG))
11155 (clobber (reg:TI XMM11_REG))
11156 (clobber (reg:TI XMM12_REG))
11157 (clobber (reg:TI XMM13_REG))
11158 (clobber (reg:TI XMM14_REG))
11159 (clobber (reg:TI XMM15_REG))
11160 (clobber (reg:DI SI_REG))
11161 (clobber (reg:DI DI_REG))]
11162 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11163 "* return ix86_output_call_insn (insn, operands[0]);"
11164 [(set_attr "type" "call")])
11166 (define_insn_and_split "*sibcall_vzeroupper"
11167 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11168 (match_operand 1 "" ""))
11169 (unspec [(match_operand 2 "const_int_operand" "")]
11170 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11171 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11173 "&& reload_completed"
11175 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11176 [(set_attr "type" "call")])
11178 (define_insn "*sibcall"
11179 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11180 (match_operand 1 "" ""))]
11181 "SIBLING_CALL_P (insn)"
11182 "* return ix86_output_call_insn (insn, operands[0]);"
11183 [(set_attr "type" "call")])
11185 (define_expand "call_pop"
11186 [(parallel [(call (match_operand:QI 0 "" "")
11187 (match_operand:SI 1 "" ""))
11188 (set (reg:SI SP_REG)
11189 (plus:SI (reg:SI SP_REG)
11190 (match_operand:SI 3 "" "")))])]
11193 ix86_expand_call (NULL, operands[0], operands[1],
11194 operands[2], operands[3], false);
11198 (define_insn_and_split "*call_pop_vzeroupper"
11200 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11201 (match_operand:SI 1 "" ""))
11202 (set (reg:SI SP_REG)
11203 (plus:SI (reg:SI SP_REG)
11204 (match_operand:SI 2 "immediate_operand" "i")))])
11205 (unspec [(match_operand 3 "const_int_operand" "")]
11206 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11207 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11209 "&& reload_completed"
11211 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11212 [(set_attr "type" "call")])
11214 (define_insn "*call_pop"
11215 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11216 (match_operand 1 "" ""))
11217 (set (reg:SI SP_REG)
11218 (plus:SI (reg:SI SP_REG)
11219 (match_operand:SI 2 "immediate_operand" "i")))]
11220 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11221 "* return ix86_output_call_insn (insn, operands[0]);"
11222 [(set_attr "type" "call")])
11224 (define_insn_and_split "*sibcall_pop_vzeroupper"
11226 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11227 (match_operand 1 "" ""))
11228 (set (reg:SI SP_REG)
11229 (plus:SI (reg:SI SP_REG)
11230 (match_operand:SI 2 "immediate_operand" "i")))])
11231 (unspec [(match_operand 3 "const_int_operand" "")]
11232 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11233 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11235 "&& reload_completed"
11237 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11238 [(set_attr "type" "call")])
11240 (define_insn "*sibcall_pop"
11241 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11242 (match_operand 1 "" ""))
11243 (set (reg:SI SP_REG)
11244 (plus:SI (reg:SI SP_REG)
11245 (match_operand:SI 2 "immediate_operand" "i")))]
11246 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11247 "* return ix86_output_call_insn (insn, operands[0]);"
11248 [(set_attr "type" "call")])
11250 ;; Call subroutine, returning value in operand 0
11252 (define_expand "call_value"
11253 [(set (match_operand 0 "" "")
11254 (call (match_operand:QI 1 "" "")
11255 (match_operand 2 "" "")))
11256 (use (match_operand 3 "" ""))]
11259 ix86_expand_call (operands[0], operands[1], operands[2],
11260 operands[3], NULL, false);
11264 (define_expand "sibcall_value"
11265 [(set (match_operand 0 "" "")
11266 (call (match_operand:QI 1 "" "")
11267 (match_operand 2 "" "")))
11268 (use (match_operand 3 "" ""))]
11271 ix86_expand_call (operands[0], operands[1], operands[2],
11272 operands[3], NULL, true);
11276 (define_insn_and_split "*call_value_vzeroupper"
11277 [(set (match_operand 0 "" "")
11278 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11279 (match_operand 2 "" "")))
11280 (unspec [(match_operand 3 "const_int_operand" "")]
11281 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11282 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11284 "&& reload_completed"
11286 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11287 [(set_attr "type" "callv")])
11289 (define_insn "*call_value"
11290 [(set (match_operand 0 "" "")
11291 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11292 (match_operand 2 "" "")))]
11293 "!SIBLING_CALL_P (insn)"
11294 "* return ix86_output_call_insn (insn, operands[1]);"
11295 [(set_attr "type" "callv")])
11297 (define_insn_and_split "*sibcall_value_vzeroupper"
11298 [(set (match_operand 0 "" "")
11299 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11300 (match_operand 2 "" "")))
11301 (unspec [(match_operand 3 "const_int_operand" "")]
11302 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11303 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11305 "&& reload_completed"
11307 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11308 [(set_attr "type" "callv")])
11310 (define_insn "*sibcall_value"
11311 [(set (match_operand 0 "" "")
11312 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11313 (match_operand 2 "" "")))]
11314 "SIBLING_CALL_P (insn)"
11315 "* return ix86_output_call_insn (insn, operands[1]);"
11316 [(set_attr "type" "callv")])
11318 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11320 [(set (match_operand 0 "" "")
11321 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11322 (match_operand 2 "" "")))
11323 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11324 (clobber (reg:TI XMM6_REG))
11325 (clobber (reg:TI XMM7_REG))
11326 (clobber (reg:TI XMM8_REG))
11327 (clobber (reg:TI XMM9_REG))
11328 (clobber (reg:TI XMM10_REG))
11329 (clobber (reg:TI XMM11_REG))
11330 (clobber (reg:TI XMM12_REG))
11331 (clobber (reg:TI XMM13_REG))
11332 (clobber (reg:TI XMM14_REG))
11333 (clobber (reg:TI XMM15_REG))
11334 (clobber (reg:DI SI_REG))
11335 (clobber (reg:DI DI_REG))])
11336 (unspec [(match_operand 3 "const_int_operand" "")]
11337 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11338 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 "&& reload_completed"
11342 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11343 [(set_attr "type" "callv")])
11345 (define_insn "*call_value_rex64_ms_sysv"
11346 [(set (match_operand 0 "" "")
11347 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11348 (match_operand 2 "" "")))
11349 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11350 (clobber (reg:TI XMM6_REG))
11351 (clobber (reg:TI XMM7_REG))
11352 (clobber (reg:TI XMM8_REG))
11353 (clobber (reg:TI XMM9_REG))
11354 (clobber (reg:TI XMM10_REG))
11355 (clobber (reg:TI XMM11_REG))
11356 (clobber (reg:TI XMM12_REG))
11357 (clobber (reg:TI XMM13_REG))
11358 (clobber (reg:TI XMM14_REG))
11359 (clobber (reg:TI XMM15_REG))
11360 (clobber (reg:DI SI_REG))
11361 (clobber (reg:DI DI_REG))]
11362 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11363 "* return ix86_output_call_insn (insn, operands[1]);"
11364 [(set_attr "type" "callv")])
11366 (define_expand "call_value_pop"
11367 [(parallel [(set (match_operand 0 "" "")
11368 (call (match_operand:QI 1 "" "")
11369 (match_operand:SI 2 "" "")))
11370 (set (reg:SI SP_REG)
11371 (plus:SI (reg:SI SP_REG)
11372 (match_operand:SI 4 "" "")))])]
11375 ix86_expand_call (operands[0], operands[1], operands[2],
11376 operands[3], operands[4], false);
11380 (define_insn_and_split "*call_value_pop_vzeroupper"
11382 [(set (match_operand 0 "" "")
11383 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11384 (match_operand 2 "" "")))
11385 (set (reg:SI SP_REG)
11386 (plus:SI (reg:SI SP_REG)
11387 (match_operand:SI 3 "immediate_operand" "i")))])
11388 (unspec [(match_operand 4 "const_int_operand" "")]
11389 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11390 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11392 "&& reload_completed"
11394 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11395 [(set_attr "type" "callv")])
11397 (define_insn "*call_value_pop"
11398 [(set (match_operand 0 "" "")
11399 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11400 (match_operand 2 "" "")))
11401 (set (reg:SI SP_REG)
11402 (plus:SI (reg:SI SP_REG)
11403 (match_operand:SI 3 "immediate_operand" "i")))]
11404 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11405 "* return ix86_output_call_insn (insn, operands[1]);"
11406 [(set_attr "type" "callv")])
11408 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11410 [(set (match_operand 0 "" "")
11411 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11412 (match_operand 2 "" "")))
11413 (set (reg:SI SP_REG)
11414 (plus:SI (reg:SI SP_REG)
11415 (match_operand:SI 3 "immediate_operand" "i")))])
11416 (unspec [(match_operand 4 "const_int_operand" "")]
11417 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11418 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11420 "&& reload_completed"
11422 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11423 [(set_attr "type" "callv")])
11425 (define_insn "*sibcall_value_pop"
11426 [(set (match_operand 0 "" "")
11427 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11428 (match_operand 2 "" "")))
11429 (set (reg:SI SP_REG)
11430 (plus:SI (reg:SI SP_REG)
11431 (match_operand:SI 3 "immediate_operand" "i")))]
11432 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11433 "* return ix86_output_call_insn (insn, operands[1]);"
11434 [(set_attr "type" "callv")])
11436 ;; Call subroutine returning any type.
11438 (define_expand "untyped_call"
11439 [(parallel [(call (match_operand 0 "" "")
11441 (match_operand 1 "" "")
11442 (match_operand 2 "" "")])]
11447 /* In order to give reg-stack an easier job in validating two
11448 coprocessor registers as containing a possible return value,
11449 simply pretend the untyped call returns a complex long double
11452 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11453 and should have the default ABI. */
11455 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11456 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11457 operands[0], const0_rtx,
11458 GEN_INT ((TARGET_64BIT
11459 ? (ix86_abi == SYSV_ABI
11460 ? X86_64_SSE_REGPARM_MAX
11461 : X86_64_MS_SSE_REGPARM_MAX)
11462 : X86_32_SSE_REGPARM_MAX)
11466 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11468 rtx set = XVECEXP (operands[2], 0, i);
11469 emit_move_insn (SET_DEST (set), SET_SRC (set));
11472 /* The optimizer does not know that the call sets the function value
11473 registers we stored in the result block. We avoid problems by
11474 claiming that all hard registers are used and clobbered at this
11476 emit_insn (gen_blockage ());
11481 ;; Prologue and epilogue instructions
11483 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11484 ;; all of memory. This blocks insns from being moved across this point.
11486 (define_insn "blockage"
11487 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11490 [(set_attr "length" "0")])
11492 ;; Do not schedule instructions accessing memory across this point.
11494 (define_expand "memory_blockage"
11495 [(set (match_dup 0)
11496 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11499 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11500 MEM_VOLATILE_P (operands[0]) = 1;
11503 (define_insn "*memory_blockage"
11504 [(set (match_operand:BLK 0 "" "")
11505 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11508 [(set_attr "length" "0")])
11510 ;; As USE insns aren't meaningful after reload, this is used instead
11511 ;; to prevent deleting instructions setting registers for PIC code
11512 (define_insn "prologue_use"
11513 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11516 [(set_attr "length" "0")])
11518 ;; Insn emitted into the body of a function to return from a function.
11519 ;; This is only done if the function's epilogue is known to be simple.
11520 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11522 (define_expand "return"
11524 "ix86_can_use_return_insn_p ()"
11526 if (crtl->args.pops_args)
11528 rtx popc = GEN_INT (crtl->args.pops_args);
11529 emit_jump_insn (gen_return_pop_internal (popc));
11534 (define_insn "return_internal"
11538 [(set_attr "length" "1")
11539 (set_attr "atom_unit" "jeu")
11540 (set_attr "length_immediate" "0")
11541 (set_attr "modrm" "0")])
11543 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11544 ;; instruction Athlon and K8 have.
11546 (define_insn "return_internal_long"
11548 (unspec [(const_int 0)] UNSPEC_REP)]
11551 [(set_attr "length" "2")
11552 (set_attr "atom_unit" "jeu")
11553 (set_attr "length_immediate" "0")
11554 (set_attr "prefix_rep" "1")
11555 (set_attr "modrm" "0")])
11557 (define_insn "return_pop_internal"
11559 (use (match_operand:SI 0 "const_int_operand" ""))]
11562 [(set_attr "length" "3")
11563 (set_attr "atom_unit" "jeu")
11564 (set_attr "length_immediate" "2")
11565 (set_attr "modrm" "0")])
11567 (define_insn "return_indirect_internal"
11569 (use (match_operand:SI 0 "register_operand" "r"))]
11572 [(set_attr "type" "ibr")
11573 (set_attr "length_immediate" "0")])
11579 [(set_attr "length" "1")
11580 (set_attr "length_immediate" "0")
11581 (set_attr "modrm" "0")])
11583 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11584 (define_insn "nops"
11585 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11589 int num = INTVAL (operands[0]);
11591 gcc_assert (num >= 1 && num <= 8);
11594 fputs ("\tnop\n", asm_out_file);
11598 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11599 (set_attr "length_immediate" "0")
11600 (set_attr "modrm" "0")])
11602 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11603 ;; branch prediction penalty for the third jump in a 16-byte
11607 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11610 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11611 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11613 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11614 The align insn is used to avoid 3 jump instructions in the row to improve
11615 branch prediction and the benefits hardly outweigh the cost of extra 8
11616 nops on the average inserted by full alignment pseudo operation. */
11620 [(set_attr "length" "16")])
11622 (define_expand "prologue"
11625 "ix86_expand_prologue (); DONE;")
11627 (define_insn "set_got"
11628 [(set (match_operand:SI 0 "register_operand" "=r")
11629 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11630 (clobber (reg:CC FLAGS_REG))]
11632 "* return output_set_got (operands[0], NULL_RTX);"
11633 [(set_attr "type" "multi")
11634 (set_attr "length" "12")])
11636 (define_insn "set_got_labelled"
11637 [(set (match_operand:SI 0 "register_operand" "=r")
11638 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11640 (clobber (reg:CC FLAGS_REG))]
11642 "* return output_set_got (operands[0], operands[1]);"
11643 [(set_attr "type" "multi")
11644 (set_attr "length" "12")])
11646 (define_insn "set_got_rex64"
11647 [(set (match_operand:DI 0 "register_operand" "=r")
11648 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11650 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11651 [(set_attr "type" "lea")
11652 (set_attr "length_address" "4")
11653 (set_attr "mode" "DI")])
11655 (define_insn "set_rip_rex64"
11656 [(set (match_operand:DI 0 "register_operand" "=r")
11657 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11659 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11660 [(set_attr "type" "lea")
11661 (set_attr "length_address" "4")
11662 (set_attr "mode" "DI")])
11664 (define_insn "set_got_offset_rex64"
11665 [(set (match_operand:DI 0 "register_operand" "=r")
11667 [(label_ref (match_operand 1 "" ""))]
11668 UNSPEC_SET_GOT_OFFSET))]
11670 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11671 [(set_attr "type" "imov")
11672 (set_attr "length_immediate" "0")
11673 (set_attr "length_address" "8")
11674 (set_attr "mode" "DI")])
11676 (define_expand "epilogue"
11679 "ix86_expand_epilogue (1); DONE;")
11681 (define_expand "sibcall_epilogue"
11684 "ix86_expand_epilogue (0); DONE;")
11686 (define_expand "eh_return"
11687 [(use (match_operand 0 "register_operand" ""))]
11690 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11692 /* Tricky bit: we write the address of the handler to which we will
11693 be returning into someone else's stack frame, one word below the
11694 stack address we wish to restore. */
11695 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11696 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11697 tmp = gen_rtx_MEM (Pmode, tmp);
11698 emit_move_insn (tmp, ra);
11700 emit_jump_insn (gen_eh_return_internal ());
11705 (define_insn_and_split "eh_return_internal"
11709 "epilogue_completed"
11711 "ix86_expand_epilogue (2); DONE;")
11713 (define_insn "leave"
11714 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11715 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11716 (clobber (mem:BLK (scratch)))]
11719 [(set_attr "type" "leave")])
11721 (define_insn "leave_rex64"
11722 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11723 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11724 (clobber (mem:BLK (scratch)))]
11727 [(set_attr "type" "leave")])
11729 ;; Handle -fsplit-stack.
11731 (define_expand "split_stack_prologue"
11735 ix86_expand_split_stack_prologue ();
11739 ;; In order to support the call/return predictor, we use a return
11740 ;; instruction which the middle-end doesn't see.
11741 (define_insn "split_stack_return"
11742 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11743 UNSPECV_SPLIT_STACK_RETURN)]
11746 if (operands[0] == const0_rtx)
11751 [(set_attr "atom_unit" "jeu")
11752 (set_attr "modrm" "0")
11753 (set (attr "length")
11754 (if_then_else (match_operand:SI 0 "const0_operand" "")
11757 (set (attr "length_immediate")
11758 (if_then_else (match_operand:SI 0 "const0_operand" "")
11762 ;; If there are operand 0 bytes available on the stack, jump to
11765 (define_expand "split_stack_space_check"
11766 [(set (pc) (if_then_else
11767 (ltu (minus (reg SP_REG)
11768 (match_operand 0 "register_operand" ""))
11769 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11770 (label_ref (match_operand 1 "" ""))
11774 rtx reg, size, limit;
11776 reg = gen_reg_rtx (Pmode);
11777 size = force_reg (Pmode, operands[0]);
11778 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11779 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11780 UNSPEC_STACK_CHECK);
11781 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11782 ix86_expand_branch (GEU, reg, limit, operands[1]);
11787 ;; Bit manipulation instructions.
11789 (define_expand "ffs<mode>2"
11790 [(set (match_dup 2) (const_int -1))
11791 (parallel [(set (reg:CCZ FLAGS_REG)
11793 (match_operand:SWI48 1 "nonimmediate_operand" "")
11795 (set (match_operand:SWI48 0 "register_operand" "")
11796 (ctz:SWI48 (match_dup 1)))])
11797 (set (match_dup 0) (if_then_else:SWI48
11798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11801 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11802 (clobber (reg:CC FLAGS_REG))])]
11805 if (<MODE>mode == SImode && !TARGET_CMOVE)
11807 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11810 operands[2] = gen_reg_rtx (<MODE>mode);
11813 (define_insn_and_split "ffssi2_no_cmove"
11814 [(set (match_operand:SI 0 "register_operand" "=r")
11815 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11816 (clobber (match_scratch:SI 2 "=&q"))
11817 (clobber (reg:CC FLAGS_REG))]
11820 "&& reload_completed"
11821 [(parallel [(set (reg:CCZ FLAGS_REG)
11822 (compare:CCZ (match_dup 1) (const_int 0)))
11823 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11824 (set (strict_low_part (match_dup 3))
11825 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11826 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11827 (clobber (reg:CC FLAGS_REG))])
11828 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11829 (clobber (reg:CC FLAGS_REG))])
11830 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11831 (clobber (reg:CC FLAGS_REG))])]
11833 operands[3] = gen_lowpart (QImode, operands[2]);
11834 ix86_expand_clear (operands[2]);
11837 (define_insn "*ffs<mode>_1"
11838 [(set (reg:CCZ FLAGS_REG)
11839 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11841 (set (match_operand:SWI48 0 "register_operand" "=r")
11842 (ctz:SWI48 (match_dup 1)))]
11844 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11845 [(set_attr "type" "alu1")
11846 (set_attr "prefix_0f" "1")
11847 (set_attr "mode" "<MODE>")])
11849 (define_insn "ctz<mode>2"
11850 [(set (match_operand:SWI248 0 "register_operand" "=r")
11851 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11852 (clobber (reg:CC FLAGS_REG))]
11856 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11858 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11860 [(set_attr "type" "alu1")
11861 (set_attr "prefix_0f" "1")
11862 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11863 (set_attr "mode" "<MODE>")])
11865 (define_expand "clz<mode>2"
11867 [(set (match_operand:SWI248 0 "register_operand" "")
11870 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11871 (clobber (reg:CC FLAGS_REG))])
11873 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11874 (clobber (reg:CC FLAGS_REG))])]
11879 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11882 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11885 (define_insn "clz<mode>2_abm"
11886 [(set (match_operand:SWI248 0 "register_operand" "=r")
11887 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "TARGET_ABM || TARGET_BMI"
11890 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11891 [(set_attr "prefix_rep" "1")
11892 (set_attr "type" "bitmanip")
11893 (set_attr "mode" "<MODE>")])
11895 ;; BMI instructions.
11896 (define_insn "*bmi_andn_<mode>"
11897 [(set (match_operand:SWI48 0 "register_operand" "=r")
11900 (match_operand:SWI48 1 "register_operand" "r"))
11901 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11902 (clobber (reg:CC FLAGS_REG))]
11904 "andn\t{%2, %1, %0|%0, %1, %2}"
11905 [(set_attr "type" "bitmanip")
11906 (set_attr "mode" "<MODE>")])
11908 (define_insn "bmi_bextr_<mode>"
11909 [(set (match_operand:SWI48 0 "register_operand" "=r")
11910 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11911 (match_operand:SWI48 2 "register_operand" "r")]
11913 (clobber (reg:CC FLAGS_REG))]
11915 "bextr\t{%2, %1, %0|%0, %1, %2}"
11916 [(set_attr "type" "bitmanip")
11917 (set_attr "mode" "<MODE>")])
11919 (define_insn "*bmi_blsi_<mode>"
11920 [(set (match_operand:SWI48 0 "register_operand" "=r")
11923 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11925 (clobber (reg:CC FLAGS_REG))]
11927 "blsi\t{%1, %0|%0, %1}"
11928 [(set_attr "type" "bitmanip")
11929 (set_attr "mode" "<MODE>")])
11931 (define_insn "*bmi_blsmsk_<mode>"
11932 [(set (match_operand:SWI48 0 "register_operand" "=r")
11935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11938 (clobber (reg:CC FLAGS_REG))]
11940 "blsmsk\t{%1, %0|%0, %1}"
11941 [(set_attr "type" "bitmanip")
11942 (set_attr "mode" "<MODE>")])
11944 (define_insn "*bmi_blsr_<mode>"
11945 [(set (match_operand:SWI48 0 "register_operand" "=r")
11948 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11951 (clobber (reg:CC FLAGS_REG))]
11953 "blsr\t{%1, %0|%0, %1}"
11954 [(set_attr "type" "bitmanip")
11955 (set_attr "mode" "<MODE>")])
11957 ;; TBM instructions.
11958 (define_insn "tbm_bextri_<mode>"
11959 [(set (match_operand:SWI48 0 "register_operand" "=r")
11960 (zero_extract:SWI48
11961 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11962 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11963 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11964 (clobber (reg:CC FLAGS_REG))]
11967 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11968 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11970 [(set_attr "type" "bitmanip")
11971 (set_attr "mode" "<MODE>")])
11973 (define_insn "*tbm_blcfill_<mode>"
11974 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11980 (clobber (reg:CC FLAGS_REG))]
11982 "blcfill\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "bitmanip")
11984 (set_attr "mode" "<MODE>")])
11986 (define_insn "*tbm_blci_<mode>"
11987 [(set (match_operand:SWI48 0 "register_operand" "=r")
11991 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11994 (clobber (reg:CC FLAGS_REG))]
11996 "blci\t{%1, %0|%0, %1}"
11997 [(set_attr "type" "bitmanip")
11998 (set_attr "mode" "<MODE>")])
12000 (define_insn "*tbm_blcic_<mode>"
12001 [(set (match_operand:SWI48 0 "register_operand" "=r")
12004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12008 (clobber (reg:CC FLAGS_REG))]
12010 "blcic\t{%1, %0|%0, %1}"
12011 [(set_attr "type" "bitmanip")
12012 (set_attr "mode" "<MODE>")])
12014 (define_insn "*tbm_blcmsk_<mode>"
12015 [(set (match_operand:SWI48 0 "register_operand" "=r")
12018 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12021 (clobber (reg:CC FLAGS_REG))]
12023 "blcmsk\t{%1, %0|%0, %1}"
12024 [(set_attr "type" "bitmanip")
12025 (set_attr "mode" "<MODE>")])
12027 (define_insn "*tbm_blcs_<mode>"
12028 [(set (match_operand:SWI48 0 "register_operand" "=r")
12031 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12034 (clobber (reg:CC FLAGS_REG))]
12036 "blcs\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "bitmanip")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "*tbm_blsfill_<mode>"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12047 (clobber (reg:CC FLAGS_REG))]
12049 "blsfill\t{%1, %0|%0, %1}"
12050 [(set_attr "type" "bitmanip")
12051 (set_attr "mode" "<MODE>")])
12053 (define_insn "*tbm_blsic_<mode>"
12054 [(set (match_operand:SWI48 0 "register_operand" "=r")
12057 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12061 (clobber (reg:CC FLAGS_REG))]
12063 "blsic\t{%1, %0|%0, %1}"
12064 [(set_attr "type" "bitmanip")
12065 (set_attr "mode" "<MODE>")])
12067 (define_insn "*tbm_t1mskc_<mode>"
12068 [(set (match_operand:SWI48 0 "register_operand" "=r")
12071 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12075 (clobber (reg:CC FLAGS_REG))]
12077 "t1mskc\t{%1, %0|%0, %1}"
12078 [(set_attr "type" "bitmanip")
12079 (set_attr "mode" "<MODE>")])
12081 (define_insn "*tbm_tzmsk_<mode>"
12082 [(set (match_operand:SWI48 0 "register_operand" "=r")
12085 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12089 (clobber (reg:CC FLAGS_REG))]
12091 "tzmsk\t{%1, %0|%0, %1}"
12092 [(set_attr "type" "bitmanip")
12093 (set_attr "mode" "<MODE>")])
12095 (define_insn "bsr_rex64"
12096 [(set (match_operand:DI 0 "register_operand" "=r")
12097 (minus:DI (const_int 63)
12098 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12099 (clobber (reg:CC FLAGS_REG))]
12101 "bsr{q}\t{%1, %0|%0, %1}"
12102 [(set_attr "type" "alu1")
12103 (set_attr "prefix_0f" "1")
12104 (set_attr "mode" "DI")])
12107 [(set (match_operand:SI 0 "register_operand" "=r")
12108 (minus:SI (const_int 31)
12109 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12110 (clobber (reg:CC FLAGS_REG))]
12112 "bsr{l}\t{%1, %0|%0, %1}"
12113 [(set_attr "type" "alu1")
12114 (set_attr "prefix_0f" "1")
12115 (set_attr "mode" "SI")])
12117 (define_insn "*bsrhi"
12118 [(set (match_operand:HI 0 "register_operand" "=r")
12119 (minus:HI (const_int 15)
12120 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12121 (clobber (reg:CC FLAGS_REG))]
12123 "bsr{w}\t{%1, %0|%0, %1}"
12124 [(set_attr "type" "alu1")
12125 (set_attr "prefix_0f" "1")
12126 (set_attr "mode" "HI")])
12128 (define_insn "popcount<mode>2"
12129 [(set (match_operand:SWI248 0 "register_operand" "=r")
12131 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12132 (clobber (reg:CC FLAGS_REG))]
12136 return "popcnt\t{%1, %0|%0, %1}";
12138 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12141 [(set_attr "prefix_rep" "1")
12142 (set_attr "type" "bitmanip")
12143 (set_attr "mode" "<MODE>")])
12145 (define_insn "*popcount<mode>2_cmp"
12146 [(set (reg FLAGS_REG)
12149 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12151 (set (match_operand:SWI248 0 "register_operand" "=r")
12152 (popcount:SWI248 (match_dup 1)))]
12153 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12156 return "popcnt\t{%1, %0|%0, %1}";
12158 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12161 [(set_attr "prefix_rep" "1")
12162 (set_attr "type" "bitmanip")
12163 (set_attr "mode" "<MODE>")])
12165 (define_insn "*popcountsi2_cmp_zext"
12166 [(set (reg FLAGS_REG)
12168 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12170 (set (match_operand:DI 0 "register_operand" "=r")
12171 (zero_extend:DI(popcount:SI (match_dup 1))))]
12172 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12175 return "popcnt\t{%1, %0|%0, %1}";
12177 return "popcnt{l}\t{%1, %0|%0, %1}";
12180 [(set_attr "prefix_rep" "1")
12181 (set_attr "type" "bitmanip")
12182 (set_attr "mode" "SI")])
12184 (define_expand "bswap<mode>2"
12185 [(set (match_operand:SWI48 0 "register_operand" "")
12186 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12189 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12191 rtx x = operands[0];
12193 emit_move_insn (x, operands[1]);
12194 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12195 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12196 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12201 (define_insn "*bswap<mode>2_movbe"
12202 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12203 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12205 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12208 movbe\t{%1, %0|%0, %1}
12209 movbe\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "bitmanip,imov,imov")
12211 (set_attr "modrm" "0,1,1")
12212 (set_attr "prefix_0f" "*,1,1")
12213 (set_attr "prefix_extra" "*,1,1")
12214 (set_attr "mode" "<MODE>")])
12216 (define_insn "*bswap<mode>2_1"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "modrm" "0")
12223 (set_attr "mode" "<MODE>")])
12225 (define_insn "*bswaphi_lowpart_1"
12226 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12227 (bswap:HI (match_dup 0)))
12228 (clobber (reg:CC FLAGS_REG))]
12229 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12231 xchg{b}\t{%h0, %b0|%b0, %h0}
12232 rol{w}\t{$8, %0|%0, 8}"
12233 [(set_attr "length" "2,4")
12234 (set_attr "mode" "QI,HI")])
12236 (define_insn "bswaphi_lowpart"
12237 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12238 (bswap:HI (match_dup 0)))
12239 (clobber (reg:CC FLAGS_REG))]
12241 "rol{w}\t{$8, %0|%0, 8}"
12242 [(set_attr "length" "4")
12243 (set_attr "mode" "HI")])
12245 (define_expand "paritydi2"
12246 [(set (match_operand:DI 0 "register_operand" "")
12247 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12250 rtx scratch = gen_reg_rtx (QImode);
12253 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12254 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));
12262 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12265 rtx tmp = gen_reg_rtx (SImode);
12267 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12268 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12273 (define_expand "paritysi2"
12274 [(set (match_operand:SI 0 "register_operand" "")
12275 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12278 rtx scratch = gen_reg_rtx (QImode);
12281 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12283 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12284 gen_rtx_REG (CCmode, FLAGS_REG),
12286 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12288 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12292 (define_insn_and_split "paritydi2_cmp"
12293 [(set (reg:CC FLAGS_REG)
12294 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12296 (clobber (match_scratch:DI 0 "=r"))
12297 (clobber (match_scratch:SI 1 "=&r"))
12298 (clobber (match_scratch:HI 2 "=Q"))]
12301 "&& reload_completed"
12303 [(set (match_dup 1)
12304 (xor:SI (match_dup 1) (match_dup 4)))
12305 (clobber (reg:CC FLAGS_REG))])
12307 [(set (reg:CC FLAGS_REG)
12308 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12309 (clobber (match_dup 1))
12310 (clobber (match_dup 2))])]
12312 operands[4] = gen_lowpart (SImode, operands[3]);
12316 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12317 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12320 operands[1] = gen_highpart (SImode, operands[3]);
12323 (define_insn_and_split "paritysi2_cmp"
12324 [(set (reg:CC FLAGS_REG)
12325 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12327 (clobber (match_scratch:SI 0 "=r"))
12328 (clobber (match_scratch:HI 1 "=&Q"))]
12331 "&& reload_completed"
12333 [(set (match_dup 1)
12334 (xor:HI (match_dup 1) (match_dup 3)))
12335 (clobber (reg:CC FLAGS_REG))])
12337 [(set (reg:CC FLAGS_REG)
12338 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12339 (clobber (match_dup 1))])]
12341 operands[3] = gen_lowpart (HImode, operands[2]);
12343 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12344 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12347 (define_insn "*parityhi2_cmp"
12348 [(set (reg:CC FLAGS_REG)
12349 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12351 (clobber (match_scratch:HI 0 "=Q"))]
12353 "xor{b}\t{%h0, %b0|%b0, %h0}"
12354 [(set_attr "length" "2")
12355 (set_attr "mode" "HI")])
12357 ;; Thread-local storage patterns for ELF.
12359 ;; Note that these code sequences must appear exactly as shown
12360 ;; in order to allow linker relaxation.
12362 (define_insn "*tls_global_dynamic_32_gnu"
12363 [(set (match_operand:SI 0 "register_operand" "=a")
12365 [(match_operand:SI 1 "register_operand" "b")
12366 (match_operand:SI 2 "tls_symbolic_operand" "")
12367 (match_operand:SI 3 "constant_call_address_operand" "z")]
12369 (clobber (match_scratch:SI 4 "=d"))
12370 (clobber (match_scratch:SI 5 "=c"))
12371 (clobber (reg:CC FLAGS_REG))]
12372 "!TARGET_64BIT && TARGET_GNU_TLS"
12375 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12376 if (TARGET_SUN_TLS)
12377 #ifdef HAVE_AS_IX86_TLSGDPLT
12378 return "call\t%a2@tlsgdplt";
12380 return "call\t%p3@plt";
12382 return "call\t%P3";
12384 [(set_attr "type" "multi")
12385 (set_attr "length" "12")])
12387 (define_expand "tls_global_dynamic_32"
12389 [(set (match_operand:SI 0 "register_operand" "")
12390 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12391 (match_operand:SI 1 "tls_symbolic_operand" "")
12392 (match_operand:SI 3 "constant_call_address_operand" "")]
12394 (clobber (match_scratch:SI 4 ""))
12395 (clobber (match_scratch:SI 5 ""))
12396 (clobber (reg:CC FLAGS_REG))])])
12398 (define_insn "*tls_global_dynamic_64"
12399 [(set (match_operand:DI 0 "register_operand" "=a")
12401 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12402 (match_operand:DI 3 "" "")))
12403 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12407 fputs (ASM_BYTE "0x66\n", asm_out_file);
12409 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12410 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12411 fputs ("\trex64\n", asm_out_file);
12412 if (TARGET_SUN_TLS)
12413 return "call\t%p2@plt";
12414 return "call\t%P2";
12416 [(set_attr "type" "multi")
12417 (set_attr "length" "16")])
12419 (define_expand "tls_global_dynamic_64"
12421 [(set (match_operand:DI 0 "register_operand" "")
12423 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12425 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12428 (define_insn "*tls_local_dynamic_base_32_gnu"
12429 [(set (match_operand:SI 0 "register_operand" "=a")
12431 [(match_operand:SI 1 "register_operand" "b")
12432 (match_operand:SI 2 "constant_call_address_operand" "z")]
12433 UNSPEC_TLS_LD_BASE))
12434 (clobber (match_scratch:SI 3 "=d"))
12435 (clobber (match_scratch:SI 4 "=c"))
12436 (clobber (reg:CC FLAGS_REG))]
12437 "!TARGET_64BIT && TARGET_GNU_TLS"
12440 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12441 if (TARGET_SUN_TLS)
12442 #ifdef HAVE_AS_IX86_TLSLDMPLT
12443 return "call\t%&@tlsldmplt";
12445 return "call\t%p2@plt";
12447 return "call\t%P2";
12449 [(set_attr "type" "multi")
12450 (set_attr "length" "11")])
12452 (define_expand "tls_local_dynamic_base_32"
12454 [(set (match_operand:SI 0 "register_operand" "")
12456 [(match_operand:SI 1 "register_operand" "")
12457 (match_operand:SI 2 "constant_call_address_operand" "")]
12458 UNSPEC_TLS_LD_BASE))
12459 (clobber (match_scratch:SI 3 ""))
12460 (clobber (match_scratch:SI 4 ""))
12461 (clobber (reg:CC FLAGS_REG))])])
12463 (define_insn "*tls_local_dynamic_base_64"
12464 [(set (match_operand:DI 0 "register_operand" "=a")
12466 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12467 (match_operand:DI 2 "" "")))
12468 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12472 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12473 if (TARGET_SUN_TLS)
12474 return "call\t%p1@plt";
12475 return "call\t%P1";
12477 [(set_attr "type" "multi")
12478 (set_attr "length" "12")])
12480 (define_expand "tls_local_dynamic_base_64"
12482 [(set (match_operand:DI 0 "register_operand" "")
12484 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12486 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12488 ;; Local dynamic of a single variable is a lose. Show combine how
12489 ;; to convert that back to global dynamic.
12491 (define_insn_and_split "*tls_local_dynamic_32_once"
12492 [(set (match_operand:SI 0 "register_operand" "=a")
12494 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12495 (match_operand:SI 2 "constant_call_address_operand" "z")]
12496 UNSPEC_TLS_LD_BASE)
12497 (const:SI (unspec:SI
12498 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12500 (clobber (match_scratch:SI 4 "=d"))
12501 (clobber (match_scratch:SI 5 "=c"))
12502 (clobber (reg:CC FLAGS_REG))]
12507 [(set (match_dup 0)
12508 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12510 (clobber (match_dup 4))
12511 (clobber (match_dup 5))
12512 (clobber (reg:CC FLAGS_REG))])])
12514 ;; Segment register for the thread base ptr load
12515 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12517 ;; Load and add the thread base pointer from %<tp_seg>:0.
12518 (define_insn "*load_tp_<mode>"
12519 [(set (match_operand:P 0 "register_operand" "=r")
12520 (unspec:P [(const_int 0)] UNSPEC_TP))]
12522 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12523 [(set_attr "type" "imov")
12524 (set_attr "modrm" "0")
12525 (set_attr "length" "7")
12526 (set_attr "memory" "load")
12527 (set_attr "imm_disp" "false")])
12529 (define_insn "*add_tp_<mode>"
12530 [(set (match_operand:P 0 "register_operand" "=r")
12531 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12532 (match_operand:P 1 "register_operand" "0")))
12533 (clobber (reg:CC FLAGS_REG))]
12535 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12536 [(set_attr "type" "alu")
12537 (set_attr "modrm" "0")
12538 (set_attr "length" "7")
12539 (set_attr "memory" "load")
12540 (set_attr "imm_disp" "false")])
12542 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12543 ;; %rax as destination of the initial executable code sequence.
12544 (define_insn "tls_initial_exec_64_sun"
12545 [(set (match_operand:DI 0 "register_operand" "=a")
12547 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12548 UNSPEC_TLS_IE_SUN))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "TARGET_64BIT && TARGET_SUN_TLS"
12553 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12554 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12556 [(set_attr "type" "multi")])
12558 ;; GNU2 TLS patterns can be split.
12560 (define_expand "tls_dynamic_gnu2_32"
12561 [(set (match_dup 3)
12562 (plus:SI (match_operand:SI 2 "register_operand" "")
12564 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12567 [(set (match_operand:SI 0 "register_operand" "")
12568 (unspec:SI [(match_dup 1) (match_dup 3)
12569 (match_dup 2) (reg:SI SP_REG)]
12571 (clobber (reg:CC FLAGS_REG))])]
12572 "!TARGET_64BIT && TARGET_GNU2_TLS"
12574 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12575 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12578 (define_insn "*tls_dynamic_lea_32"
12579 [(set (match_operand:SI 0 "register_operand" "=r")
12580 (plus:SI (match_operand:SI 1 "register_operand" "b")
12582 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12583 UNSPEC_TLSDESC))))]
12584 "!TARGET_64BIT && TARGET_GNU2_TLS"
12585 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12586 [(set_attr "type" "lea")
12587 (set_attr "mode" "SI")
12588 (set_attr "length" "6")
12589 (set_attr "length_address" "4")])
12591 (define_insn "*tls_dynamic_call_32"
12592 [(set (match_operand:SI 0 "register_operand" "=a")
12593 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12594 (match_operand:SI 2 "register_operand" "0")
12595 ;; we have to make sure %ebx still points to the GOT
12596 (match_operand:SI 3 "register_operand" "b")
12599 (clobber (reg:CC FLAGS_REG))]
12600 "!TARGET_64BIT && TARGET_GNU2_TLS"
12601 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12602 [(set_attr "type" "call")
12603 (set_attr "length" "2")
12604 (set_attr "length_address" "0")])
12606 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12607 [(set (match_operand:SI 0 "register_operand" "=&a")
12609 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12610 (match_operand:SI 4 "" "")
12611 (match_operand:SI 2 "register_operand" "b")
12614 (const:SI (unspec:SI
12615 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12617 (clobber (reg:CC FLAGS_REG))]
12618 "!TARGET_64BIT && TARGET_GNU2_TLS"
12621 [(set (match_dup 0) (match_dup 5))]
12623 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12624 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12627 (define_expand "tls_dynamic_gnu2_64"
12628 [(set (match_dup 2)
12629 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12632 [(set (match_operand:DI 0 "register_operand" "")
12633 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12635 (clobber (reg:CC FLAGS_REG))])]
12636 "TARGET_64BIT && TARGET_GNU2_TLS"
12638 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12639 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12642 (define_insn "*tls_dynamic_lea_64"
12643 [(set (match_operand:DI 0 "register_operand" "=r")
12644 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12646 "TARGET_64BIT && TARGET_GNU2_TLS"
12647 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12648 [(set_attr "type" "lea")
12649 (set_attr "mode" "DI")
12650 (set_attr "length" "7")
12651 (set_attr "length_address" "4")])
12653 (define_insn "*tls_dynamic_call_64"
12654 [(set (match_operand:DI 0 "register_operand" "=a")
12655 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12656 (match_operand:DI 2 "register_operand" "0")
12659 (clobber (reg:CC FLAGS_REG))]
12660 "TARGET_64BIT && TARGET_GNU2_TLS"
12661 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12662 [(set_attr "type" "call")
12663 (set_attr "length" "2")
12664 (set_attr "length_address" "0")])
12666 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12667 [(set (match_operand:DI 0 "register_operand" "=&a")
12669 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12670 (match_operand:DI 3 "" "")
12673 (const:DI (unspec:DI
12674 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12676 (clobber (reg:CC FLAGS_REG))]
12677 "TARGET_64BIT && TARGET_GNU2_TLS"
12680 [(set (match_dup 0) (match_dup 4))]
12682 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12683 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12686 ;; These patterns match the binary 387 instructions for addM3, subM3,
12687 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12688 ;; SFmode. The first is the normal insn, the second the same insn but
12689 ;; with one operand a conversion, and the third the same insn but with
12690 ;; the other operand a conversion. The conversion may be SFmode or
12691 ;; SImode if the target mode DFmode, but only SImode if the target mode
12694 ;; Gcc is slightly more smart about handling normal two address instructions
12695 ;; so use special patterns for add and mull.
12697 (define_insn "*fop_<mode>_comm_mixed"
12698 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12699 (match_operator:MODEF 3 "binary_fp_operator"
12700 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12701 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12702 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12703 && COMMUTATIVE_ARITH_P (operands[3])
12704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12705 "* return output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (if_then_else (eq_attr "alternative" "1,2")
12708 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12709 (const_string "ssemul")
12710 (const_string "sseadd"))
12711 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12712 (const_string "fmul")
12713 (const_string "fop"))))
12714 (set_attr "isa" "*,noavx,avx")
12715 (set_attr "prefix" "orig,orig,vex")
12716 (set_attr "mode" "<MODE>")])
12718 (define_insn "*fop_<mode>_comm_sse"
12719 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12720 (match_operator:MODEF 3 "binary_fp_operator"
12721 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12722 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12723 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12724 && COMMUTATIVE_ARITH_P (operands[3])
12725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12726 "* return output_387_binary_op (insn, operands);"
12727 [(set (attr "type")
12728 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12729 (const_string "ssemul")
12730 (const_string "sseadd")))
12731 (set_attr "isa" "noavx,avx")
12732 (set_attr "prefix" "orig,vex")
12733 (set_attr "mode" "<MODE>")])
12735 (define_insn "*fop_<mode>_comm_i387"
12736 [(set (match_operand:MODEF 0 "register_operand" "=f")
12737 (match_operator:MODEF 3 "binary_fp_operator"
12738 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12739 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12740 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12741 && COMMUTATIVE_ARITH_P (operands[3])
12742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12743 "* return output_387_binary_op (insn, operands);"
12744 [(set (attr "type")
12745 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12746 (const_string "fmul")
12747 (const_string "fop")))
12748 (set_attr "mode" "<MODE>")])
12750 (define_insn "*fop_<mode>_1_mixed"
12751 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12752 (match_operator:MODEF 3 "binary_fp_operator"
12753 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12754 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12755 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12756 && !COMMUTATIVE_ARITH_P (operands[3])
12757 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12758 "* return output_387_binary_op (insn, operands);"
12759 [(set (attr "type")
12760 (cond [(and (eq_attr "alternative" "2,3")
12761 (match_operand:MODEF 3 "mult_operator" ""))
12762 (const_string "ssemul")
12763 (and (eq_attr "alternative" "2,3")
12764 (match_operand:MODEF 3 "div_operator" ""))
12765 (const_string "ssediv")
12766 (eq_attr "alternative" "2,3")
12767 (const_string "sseadd")
12768 (match_operand:MODEF 3 "mult_operator" "")
12769 (const_string "fmul")
12770 (match_operand:MODEF 3 "div_operator" "")
12771 (const_string "fdiv")
12773 (const_string "fop")))
12774 (set_attr "isa" "*,*,noavx,avx")
12775 (set_attr "prefix" "orig,orig,orig,vex")
12776 (set_attr "mode" "<MODE>")])
12778 (define_insn "*rcpsf2_sse"
12779 [(set (match_operand:SF 0 "register_operand" "=x")
12780 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12783 "%vrcpss\t{%1, %d0|%d0, %1}"
12784 [(set_attr "type" "sse")
12785 (set_attr "atom_sse_attr" "rcp")
12786 (set_attr "prefix" "maybe_vex")
12787 (set_attr "mode" "SF")])
12789 (define_insn "*fop_<mode>_1_sse"
12790 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12791 (match_operator:MODEF 3 "binary_fp_operator"
12792 [(match_operand:MODEF 1 "register_operand" "0,x")
12793 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12794 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12795 && !COMMUTATIVE_ARITH_P (operands[3])"
12796 "* return output_387_binary_op (insn, operands);"
12797 [(set (attr "type")
12798 (cond [(match_operand:MODEF 3 "mult_operator" "")
12799 (const_string "ssemul")
12800 (match_operand:MODEF 3 "div_operator" "")
12801 (const_string "ssediv")
12803 (const_string "sseadd")))
12804 (set_attr "isa" "noavx,avx")
12805 (set_attr "prefix" "orig,vex")
12806 (set_attr "mode" "<MODE>")])
12808 ;; This pattern is not fully shadowed by the pattern above.
12809 (define_insn "*fop_<mode>_1_i387"
12810 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12811 (match_operator:MODEF 3 "binary_fp_operator"
12812 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12813 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12814 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12815 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12816 && !COMMUTATIVE_ARITH_P (operands[3])
12817 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12818 "* return output_387_binary_op (insn, operands);"
12819 [(set (attr "type")
12820 (cond [(match_operand:MODEF 3 "mult_operator" "")
12821 (const_string "fmul")
12822 (match_operand:MODEF 3 "div_operator" "")
12823 (const_string "fdiv")
12825 (const_string "fop")))
12826 (set_attr "mode" "<MODE>")])
12828 ;; ??? Add SSE splitters for these!
12829 (define_insn "*fop_<MODEF:mode>_2_i387"
12830 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12831 (match_operator:MODEF 3 "binary_fp_operator"
12833 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12834 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12835 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12836 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12837 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12838 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12839 [(set (attr "type")
12840 (cond [(match_operand:MODEF 3 "mult_operator" "")
12841 (const_string "fmul")
12842 (match_operand:MODEF 3 "div_operator" "")
12843 (const_string "fdiv")
12845 (const_string "fop")))
12846 (set_attr "fp_int_src" "true")
12847 (set_attr "mode" "<SWI24:MODE>")])
12849 (define_insn "*fop_<MODEF:mode>_3_i387"
12850 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12851 (match_operator:MODEF 3 "binary_fp_operator"
12852 [(match_operand:MODEF 1 "register_operand" "0,0")
12854 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12855 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12856 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12857 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12858 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12859 [(set (attr "type")
12860 (cond [(match_operand:MODEF 3 "mult_operator" "")
12861 (const_string "fmul")
12862 (match_operand:MODEF 3 "div_operator" "")
12863 (const_string "fdiv")
12865 (const_string "fop")))
12866 (set_attr "fp_int_src" "true")
12867 (set_attr "mode" "<MODE>")])
12869 (define_insn "*fop_df_4_i387"
12870 [(set (match_operand:DF 0 "register_operand" "=f,f")
12871 (match_operator:DF 3 "binary_fp_operator"
12873 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12874 (match_operand:DF 2 "register_operand" "0,f")]))]
12875 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12876 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (cond [(match_operand:DF 3 "mult_operator" "")
12881 (const_string "fmul")
12882 (match_operand:DF 3 "div_operator" "")
12883 (const_string "fdiv")
12885 (const_string "fop")))
12886 (set_attr "mode" "SF")])
12888 (define_insn "*fop_df_5_i387"
12889 [(set (match_operand:DF 0 "register_operand" "=f,f")
12890 (match_operator:DF 3 "binary_fp_operator"
12891 [(match_operand:DF 1 "register_operand" "0,f")
12893 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12894 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12895 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12896 "* return output_387_binary_op (insn, operands);"
12897 [(set (attr "type")
12898 (cond [(match_operand:DF 3 "mult_operator" "")
12899 (const_string "fmul")
12900 (match_operand:DF 3 "div_operator" "")
12901 (const_string "fdiv")
12903 (const_string "fop")))
12904 (set_attr "mode" "SF")])
12906 (define_insn "*fop_df_6_i387"
12907 [(set (match_operand:DF 0 "register_operand" "=f,f")
12908 (match_operator:DF 3 "binary_fp_operator"
12910 (match_operand:SF 1 "register_operand" "0,f"))
12912 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12913 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12914 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12915 "* return output_387_binary_op (insn, operands);"
12916 [(set (attr "type")
12917 (cond [(match_operand:DF 3 "mult_operator" "")
12918 (const_string "fmul")
12919 (match_operand:DF 3 "div_operator" "")
12920 (const_string "fdiv")
12922 (const_string "fop")))
12923 (set_attr "mode" "SF")])
12925 (define_insn "*fop_xf_comm_i387"
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12927 (match_operator:XF 3 "binary_fp_operator"
12928 [(match_operand:XF 1 "register_operand" "%0")
12929 (match_operand:XF 2 "register_operand" "f")]))]
12931 && COMMUTATIVE_ARITH_P (operands[3])"
12932 "* return output_387_binary_op (insn, operands);"
12933 [(set (attr "type")
12934 (if_then_else (match_operand:XF 3 "mult_operator" "")
12935 (const_string "fmul")
12936 (const_string "fop")))
12937 (set_attr "mode" "XF")])
12939 (define_insn "*fop_xf_1_i387"
12940 [(set (match_operand:XF 0 "register_operand" "=f,f")
12941 (match_operator:XF 3 "binary_fp_operator"
12942 [(match_operand:XF 1 "register_operand" "0,f")
12943 (match_operand:XF 2 "register_operand" "f,0")]))]
12945 && !COMMUTATIVE_ARITH_P (operands[3])"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (cond [(match_operand:XF 3 "mult_operator" "")
12949 (const_string "fmul")
12950 (match_operand:XF 3 "div_operator" "")
12951 (const_string "fdiv")
12953 (const_string "fop")))
12954 (set_attr "mode" "XF")])
12956 (define_insn "*fop_xf_2_i387"
12957 [(set (match_operand:XF 0 "register_operand" "=f,f")
12958 (match_operator:XF 3 "binary_fp_operator"
12960 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12961 (match_operand:XF 2 "register_operand" "0,0")]))]
12962 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12963 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (cond [(match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (match_operand:XF 3 "div_operator" "")
12968 (const_string "fdiv")
12970 (const_string "fop")))
12971 (set_attr "fp_int_src" "true")
12972 (set_attr "mode" "<MODE>")])
12974 (define_insn "*fop_xf_3_i387"
12975 [(set (match_operand:XF 0 "register_operand" "=f,f")
12976 (match_operator:XF 3 "binary_fp_operator"
12977 [(match_operand:XF 1 "register_operand" "0,0")
12979 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12980 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12981 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (cond [(match_operand:XF 3 "mult_operator" "")
12984 (const_string "fmul")
12985 (match_operand:XF 3 "div_operator" "")
12986 (const_string "fdiv")
12988 (const_string "fop")))
12989 (set_attr "fp_int_src" "true")
12990 (set_attr "mode" "<MODE>")])
12992 (define_insn "*fop_xf_4_i387"
12993 [(set (match_operand:XF 0 "register_operand" "=f,f")
12994 (match_operator:XF 3 "binary_fp_operator"
12996 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12997 (match_operand:XF 2 "register_operand" "0,f")]))]
12999 "* return output_387_binary_op (insn, operands);"
13000 [(set (attr "type")
13001 (cond [(match_operand:XF 3 "mult_operator" "")
13002 (const_string "fmul")
13003 (match_operand:XF 3 "div_operator" "")
13004 (const_string "fdiv")
13006 (const_string "fop")))
13007 (set_attr "mode" "<MODE>")])
13009 (define_insn "*fop_xf_5_i387"
13010 [(set (match_operand:XF 0 "register_operand" "=f,f")
13011 (match_operator:XF 3 "binary_fp_operator"
13012 [(match_operand:XF 1 "register_operand" "0,f")
13014 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13016 "* return output_387_binary_op (insn, operands);"
13017 [(set (attr "type")
13018 (cond [(match_operand:XF 3 "mult_operator" "")
13019 (const_string "fmul")
13020 (match_operand:XF 3 "div_operator" "")
13021 (const_string "fdiv")
13023 (const_string "fop")))
13024 (set_attr "mode" "<MODE>")])
13026 (define_insn "*fop_xf_6_i387"
13027 [(set (match_operand:XF 0 "register_operand" "=f,f")
13028 (match_operator:XF 3 "binary_fp_operator"
13030 (match_operand:MODEF 1 "register_operand" "0,f"))
13032 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13034 "* return output_387_binary_op (insn, operands);"
13035 [(set (attr "type")
13036 (cond [(match_operand:XF 3 "mult_operator" "")
13037 (const_string "fmul")
13038 (match_operand:XF 3 "div_operator" "")
13039 (const_string "fdiv")
13041 (const_string "fop")))
13042 (set_attr "mode" "<MODE>")])
13045 [(set (match_operand 0 "register_operand" "")
13046 (match_operator 3 "binary_fp_operator"
13047 [(float (match_operand:SWI24 1 "register_operand" ""))
13048 (match_operand 2 "register_operand" "")]))]
13050 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13051 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13054 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13055 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13056 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13057 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13058 GET_MODE (operands[3]),
13061 ix86_free_from_memory (GET_MODE (operands[1]));
13066 [(set (match_operand 0 "register_operand" "")
13067 (match_operator 3 "binary_fp_operator"
13068 [(match_operand 1 "register_operand" "")
13069 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13071 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13072 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13075 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13076 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13077 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13078 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13079 GET_MODE (operands[3]),
13082 ix86_free_from_memory (GET_MODE (operands[2]));
13086 ;; FPU special functions.
13088 ;; This pattern implements a no-op XFmode truncation for
13089 ;; all fancy i386 XFmode math functions.
13091 (define_insn "truncxf<mode>2_i387_noop_unspec"
13092 [(set (match_operand:MODEF 0 "register_operand" "=f")
13093 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13094 UNSPEC_TRUNC_NOOP))]
13095 "TARGET_USE_FANCY_MATH_387"
13096 "* return output_387_reg_move (insn, operands);"
13097 [(set_attr "type" "fmov")
13098 (set_attr "mode" "<MODE>")])
13100 (define_insn "sqrtxf2"
13101 [(set (match_operand:XF 0 "register_operand" "=f")
13102 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13103 "TARGET_USE_FANCY_MATH_387"
13105 [(set_attr "type" "fpspc")
13106 (set_attr "mode" "XF")
13107 (set_attr "athlon_decode" "direct")
13108 (set_attr "amdfam10_decode" "direct")
13109 (set_attr "bdver1_decode" "direct")])
13111 (define_insn "sqrt_extend<mode>xf2_i387"
13112 [(set (match_operand:XF 0 "register_operand" "=f")
13115 (match_operand:MODEF 1 "register_operand" "0"))))]
13116 "TARGET_USE_FANCY_MATH_387"
13118 [(set_attr "type" "fpspc")
13119 (set_attr "mode" "XF")
13120 (set_attr "athlon_decode" "direct")
13121 (set_attr "amdfam10_decode" "direct")
13122 (set_attr "bdver1_decode" "direct")])
13124 (define_insn "*rsqrtsf2_sse"
13125 [(set (match_operand:SF 0 "register_operand" "=x")
13126 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13129 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13130 [(set_attr "type" "sse")
13131 (set_attr "atom_sse_attr" "rcp")
13132 (set_attr "prefix" "maybe_vex")
13133 (set_attr "mode" "SF")])
13135 (define_expand "rsqrtsf2"
13136 [(set (match_operand:SF 0 "register_operand" "")
13137 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13141 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13145 (define_insn "*sqrt<mode>2_sse"
13146 [(set (match_operand:MODEF 0 "register_operand" "=x")
13148 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13149 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13150 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13151 [(set_attr "type" "sse")
13152 (set_attr "atom_sse_attr" "sqrt")
13153 (set_attr "prefix" "maybe_vex")
13154 (set_attr "mode" "<MODE>")
13155 (set_attr "athlon_decode" "*")
13156 (set_attr "amdfam10_decode" "*")
13157 (set_attr "bdver1_decode" "*")])
13159 (define_expand "sqrt<mode>2"
13160 [(set (match_operand:MODEF 0 "register_operand" "")
13162 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13163 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13166 if (<MODE>mode == SFmode
13167 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13168 && flag_finite_math_only && !flag_trapping_math
13169 && flag_unsafe_math_optimizations)
13171 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13175 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13177 rtx op0 = gen_reg_rtx (XFmode);
13178 rtx op1 = force_reg (<MODE>mode, operands[1]);
13180 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13181 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13186 (define_insn "fpremxf4_i387"
13187 [(set (match_operand:XF 0 "register_operand" "=f")
13188 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13189 (match_operand:XF 3 "register_operand" "1")]
13191 (set (match_operand:XF 1 "register_operand" "=u")
13192 (unspec:XF [(match_dup 2) (match_dup 3)]
13194 (set (reg:CCFP FPSR_REG)
13195 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13197 "TARGET_USE_FANCY_MATH_387"
13199 [(set_attr "type" "fpspc")
13200 (set_attr "mode" "XF")])
13202 (define_expand "fmodxf3"
13203 [(use (match_operand:XF 0 "register_operand" ""))
13204 (use (match_operand:XF 1 "general_operand" ""))
13205 (use (match_operand:XF 2 "general_operand" ""))]
13206 "TARGET_USE_FANCY_MATH_387"
13208 rtx label = gen_label_rtx ();
13210 rtx op1 = gen_reg_rtx (XFmode);
13211 rtx op2 = gen_reg_rtx (XFmode);
13213 emit_move_insn (op2, operands[2]);
13214 emit_move_insn (op1, operands[1]);
13216 emit_label (label);
13217 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13218 ix86_emit_fp_unordered_jump (label);
13219 LABEL_NUSES (label) = 1;
13221 emit_move_insn (operands[0], op1);
13225 (define_expand "fmod<mode>3"
13226 [(use (match_operand:MODEF 0 "register_operand" ""))
13227 (use (match_operand:MODEF 1 "general_operand" ""))
13228 (use (match_operand:MODEF 2 "general_operand" ""))]
13229 "TARGET_USE_FANCY_MATH_387"
13231 rtx (*gen_truncxf) (rtx, rtx);
13233 rtx label = gen_label_rtx ();
13235 rtx op1 = gen_reg_rtx (XFmode);
13236 rtx op2 = gen_reg_rtx (XFmode);
13238 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13241 emit_label (label);
13242 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13243 ix86_emit_fp_unordered_jump (label);
13244 LABEL_NUSES (label) = 1;
13246 /* Truncate the result properly for strict SSE math. */
13247 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13248 && !TARGET_MIX_SSE_I387)
13249 gen_truncxf = gen_truncxf<mode>2;
13251 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13253 emit_insn (gen_truncxf (operands[0], op1));
13257 (define_insn "fprem1xf4_i387"
13258 [(set (match_operand:XF 0 "register_operand" "=f")
13259 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13260 (match_operand:XF 3 "register_operand" "1")]
13262 (set (match_operand:XF 1 "register_operand" "=u")
13263 (unspec:XF [(match_dup 2) (match_dup 3)]
13265 (set (reg:CCFP FPSR_REG)
13266 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13268 "TARGET_USE_FANCY_MATH_387"
13270 [(set_attr "type" "fpspc")
13271 (set_attr "mode" "XF")])
13273 (define_expand "remainderxf3"
13274 [(use (match_operand:XF 0 "register_operand" ""))
13275 (use (match_operand:XF 1 "general_operand" ""))
13276 (use (match_operand:XF 2 "general_operand" ""))]
13277 "TARGET_USE_FANCY_MATH_387"
13279 rtx label = gen_label_rtx ();
13281 rtx op1 = gen_reg_rtx (XFmode);
13282 rtx op2 = gen_reg_rtx (XFmode);
13284 emit_move_insn (op2, operands[2]);
13285 emit_move_insn (op1, operands[1]);
13287 emit_label (label);
13288 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13289 ix86_emit_fp_unordered_jump (label);
13290 LABEL_NUSES (label) = 1;
13292 emit_move_insn (operands[0], op1);
13296 (define_expand "remainder<mode>3"
13297 [(use (match_operand:MODEF 0 "register_operand" ""))
13298 (use (match_operand:MODEF 1 "general_operand" ""))
13299 (use (match_operand:MODEF 2 "general_operand" ""))]
13300 "TARGET_USE_FANCY_MATH_387"
13302 rtx (*gen_truncxf) (rtx, rtx);
13304 rtx label = gen_label_rtx ();
13306 rtx op1 = gen_reg_rtx (XFmode);
13307 rtx op2 = gen_reg_rtx (XFmode);
13309 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13310 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13312 emit_label (label);
13314 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13315 ix86_emit_fp_unordered_jump (label);
13316 LABEL_NUSES (label) = 1;
13318 /* Truncate the result properly for strict SSE math. */
13319 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13320 && !TARGET_MIX_SSE_I387)
13321 gen_truncxf = gen_truncxf<mode>2;
13323 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13325 emit_insn (gen_truncxf (operands[0], op1));
13329 (define_insn "*sinxf2_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && flag_unsafe_math_optimizations"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")])
13338 (define_insn "*sin_extend<mode>xf2_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(float_extend:XF
13341 (match_operand:MODEF 1 "register_operand" "0"))]
13343 "TARGET_USE_FANCY_MATH_387
13344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345 || TARGET_MIX_SSE_I387)
13346 && flag_unsafe_math_optimizations"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13351 (define_insn "*cosxf2_i387"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13353 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13354 "TARGET_USE_FANCY_MATH_387
13355 && flag_unsafe_math_optimizations"
13357 [(set_attr "type" "fpspc")
13358 (set_attr "mode" "XF")])
13360 (define_insn "*cos_extend<mode>xf2_i387"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(float_extend:XF
13363 (match_operand:MODEF 1 "register_operand" "0"))]
13365 "TARGET_USE_FANCY_MATH_387
13366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13367 || TARGET_MIX_SSE_I387)
13368 && flag_unsafe_math_optimizations"
13370 [(set_attr "type" "fpspc")
13371 (set_attr "mode" "XF")])
13373 ;; When sincos pattern is defined, sin and cos builtin functions will be
13374 ;; expanded to sincos pattern with one of its outputs left unused.
13375 ;; CSE pass will figure out if two sincos patterns can be combined,
13376 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13377 ;; depending on the unused output.
13379 (define_insn "sincosxf3"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13381 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13382 UNSPEC_SINCOS_COS))
13383 (set (match_operand:XF 1 "register_operand" "=u")
13384 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385 "TARGET_USE_FANCY_MATH_387
13386 && flag_unsafe_math_optimizations"
13388 [(set_attr "type" "fpspc")
13389 (set_attr "mode" "XF")])
13392 [(set (match_operand:XF 0 "register_operand" "")
13393 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13394 UNSPEC_SINCOS_COS))
13395 (set (match_operand:XF 1 "register_operand" "")
13396 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13397 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13398 && can_create_pseudo_p ()"
13399 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13402 [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13404 UNSPEC_SINCOS_COS))
13405 (set (match_operand:XF 1 "register_operand" "")
13406 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13407 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13408 && can_create_pseudo_p ()"
13409 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13411 (define_insn "sincos_extend<mode>xf3_i387"
13412 [(set (match_operand:XF 0 "register_operand" "=f")
13413 (unspec:XF [(float_extend:XF
13414 (match_operand:MODEF 2 "register_operand" "0"))]
13415 UNSPEC_SINCOS_COS))
13416 (set (match_operand:XF 1 "register_operand" "=u")
13417 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13418 "TARGET_USE_FANCY_MATH_387
13419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13420 || TARGET_MIX_SSE_I387)
13421 && flag_unsafe_math_optimizations"
13423 [(set_attr "type" "fpspc")
13424 (set_attr "mode" "XF")])
13427 [(set (match_operand:XF 0 "register_operand" "")
13428 (unspec:XF [(float_extend:XF
13429 (match_operand:MODEF 2 "register_operand" ""))]
13430 UNSPEC_SINCOS_COS))
13431 (set (match_operand:XF 1 "register_operand" "")
13432 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13433 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13434 && can_create_pseudo_p ()"
13435 [(set (match_dup 1)
13436 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13439 [(set (match_operand:XF 0 "register_operand" "")
13440 (unspec:XF [(float_extend:XF
13441 (match_operand:MODEF 2 "register_operand" ""))]
13442 UNSPEC_SINCOS_COS))
13443 (set (match_operand:XF 1 "register_operand" "")
13444 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13445 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13446 && can_create_pseudo_p ()"
13447 [(set (match_dup 0)
13448 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13450 (define_expand "sincos<mode>3"
13451 [(use (match_operand:MODEF 0 "register_operand" ""))
13452 (use (match_operand:MODEF 1 "register_operand" ""))
13453 (use (match_operand:MODEF 2 "register_operand" ""))]
13454 "TARGET_USE_FANCY_MATH_387
13455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13456 || TARGET_MIX_SSE_I387)
13457 && flag_unsafe_math_optimizations"
13459 rtx op0 = gen_reg_rtx (XFmode);
13460 rtx op1 = gen_reg_rtx (XFmode);
13462 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13468 (define_insn "fptanxf4_i387"
13469 [(set (match_operand:XF 0 "register_operand" "=f")
13470 (match_operand:XF 3 "const_double_operand" "F"))
13471 (set (match_operand:XF 1 "register_operand" "=u")
13472 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13474 "TARGET_USE_FANCY_MATH_387
13475 && flag_unsafe_math_optimizations
13476 && standard_80387_constant_p (operands[3]) == 2"
13478 [(set_attr "type" "fpspc")
13479 (set_attr "mode" "XF")])
13481 (define_insn "fptan_extend<mode>xf4_i387"
13482 [(set (match_operand:MODEF 0 "register_operand" "=f")
13483 (match_operand:MODEF 3 "const_double_operand" "F"))
13484 (set (match_operand:XF 1 "register_operand" "=u")
13485 (unspec:XF [(float_extend:XF
13486 (match_operand:MODEF 2 "register_operand" "0"))]
13488 "TARGET_USE_FANCY_MATH_387
13489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490 || TARGET_MIX_SSE_I387)
13491 && flag_unsafe_math_optimizations
13492 && standard_80387_constant_p (operands[3]) == 2"
13494 [(set_attr "type" "fpspc")
13495 (set_attr "mode" "XF")])
13497 (define_expand "tanxf2"
13498 [(use (match_operand:XF 0 "register_operand" ""))
13499 (use (match_operand:XF 1 "register_operand" ""))]
13500 "TARGET_USE_FANCY_MATH_387
13501 && flag_unsafe_math_optimizations"
13503 rtx one = gen_reg_rtx (XFmode);
13504 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13506 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13510 (define_expand "tan<mode>2"
13511 [(use (match_operand:MODEF 0 "register_operand" ""))
13512 (use (match_operand:MODEF 1 "register_operand" ""))]
13513 "TARGET_USE_FANCY_MATH_387
13514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13515 || TARGET_MIX_SSE_I387)
13516 && flag_unsafe_math_optimizations"
13518 rtx op0 = gen_reg_rtx (XFmode);
13520 rtx one = gen_reg_rtx (<MODE>mode);
13521 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13523 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13524 operands[1], op2));
13525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13529 (define_insn "*fpatanxf3_i387"
13530 [(set (match_operand:XF 0 "register_operand" "=f")
13531 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13532 (match_operand:XF 2 "register_operand" "u")]
13534 (clobber (match_scratch:XF 3 "=2"))]
13535 "TARGET_USE_FANCY_MATH_387
13536 && flag_unsafe_math_optimizations"
13538 [(set_attr "type" "fpspc")
13539 (set_attr "mode" "XF")])
13541 (define_insn "fpatan_extend<mode>xf3_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f")
13543 (unspec:XF [(float_extend:XF
13544 (match_operand:MODEF 1 "register_operand" "0"))
13546 (match_operand:MODEF 2 "register_operand" "u"))]
13548 (clobber (match_scratch:XF 3 "=2"))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13551 || TARGET_MIX_SSE_I387)
13552 && flag_unsafe_math_optimizations"
13554 [(set_attr "type" "fpspc")
13555 (set_attr "mode" "XF")])
13557 (define_expand "atan2xf3"
13558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13559 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13560 (match_operand:XF 1 "register_operand" "")]
13562 (clobber (match_scratch:XF 3 ""))])]
13563 "TARGET_USE_FANCY_MATH_387
13564 && flag_unsafe_math_optimizations")
13566 (define_expand "atan2<mode>3"
13567 [(use (match_operand:MODEF 0 "register_operand" ""))
13568 (use (match_operand:MODEF 1 "register_operand" ""))
13569 (use (match_operand:MODEF 2 "register_operand" ""))]
13570 "TARGET_USE_FANCY_MATH_387
13571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13572 || TARGET_MIX_SSE_I387)
13573 && flag_unsafe_math_optimizations"
13575 rtx op0 = gen_reg_rtx (XFmode);
13577 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13578 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13582 (define_expand "atanxf2"
13583 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13584 (unspec:XF [(match_dup 2)
13585 (match_operand:XF 1 "register_operand" "")]
13587 (clobber (match_scratch:XF 3 ""))])]
13588 "TARGET_USE_FANCY_MATH_387
13589 && flag_unsafe_math_optimizations"
13591 operands[2] = gen_reg_rtx (XFmode);
13592 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13595 (define_expand "atan<mode>2"
13596 [(use (match_operand:MODEF 0 "register_operand" ""))
13597 (use (match_operand:MODEF 1 "register_operand" ""))]
13598 "TARGET_USE_FANCY_MATH_387
13599 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13600 || TARGET_MIX_SSE_I387)
13601 && flag_unsafe_math_optimizations"
13603 rtx op0 = gen_reg_rtx (XFmode);
13605 rtx op2 = gen_reg_rtx (<MODE>mode);
13606 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13608 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13609 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13613 (define_expand "asinxf2"
13614 [(set (match_dup 2)
13615 (mult:XF (match_operand:XF 1 "register_operand" "")
13617 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13618 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13619 (parallel [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_dup 5) (match_dup 1)]
13622 (clobber (match_scratch:XF 6 ""))])]
13623 "TARGET_USE_FANCY_MATH_387
13624 && flag_unsafe_math_optimizations"
13628 if (optimize_insn_for_size_p ())
13631 for (i = 2; i < 6; i++)
13632 operands[i] = gen_reg_rtx (XFmode);
13634 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13637 (define_expand "asin<mode>2"
13638 [(use (match_operand:MODEF 0 "register_operand" ""))
13639 (use (match_operand:MODEF 1 "general_operand" ""))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13645 rtx op0 = gen_reg_rtx (XFmode);
13646 rtx op1 = gen_reg_rtx (XFmode);
13648 if (optimize_insn_for_size_p ())
13651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13652 emit_insn (gen_asinxf2 (op0, op1));
13653 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13657 (define_expand "acosxf2"
13658 [(set (match_dup 2)
13659 (mult:XF (match_operand:XF 1 "register_operand" "")
13661 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13662 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13663 (parallel [(set (match_operand:XF 0 "register_operand" "")
13664 (unspec:XF [(match_dup 1) (match_dup 5)]
13666 (clobber (match_scratch:XF 6 ""))])]
13667 "TARGET_USE_FANCY_MATH_387
13668 && flag_unsafe_math_optimizations"
13672 if (optimize_insn_for_size_p ())
13675 for (i = 2; i < 6; i++)
13676 operands[i] = gen_reg_rtx (XFmode);
13678 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13681 (define_expand "acos<mode>2"
13682 [(use (match_operand:MODEF 0 "register_operand" ""))
13683 (use (match_operand:MODEF 1 "general_operand" ""))]
13684 "TARGET_USE_FANCY_MATH_387
13685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13686 || TARGET_MIX_SSE_I387)
13687 && flag_unsafe_math_optimizations"
13689 rtx op0 = gen_reg_rtx (XFmode);
13690 rtx op1 = gen_reg_rtx (XFmode);
13692 if (optimize_insn_for_size_p ())
13695 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13696 emit_insn (gen_acosxf2 (op0, op1));
13697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701 (define_insn "fyl2xxf3_i387"
13702 [(set (match_operand:XF 0 "register_operand" "=f")
13703 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13704 (match_operand:XF 2 "register_operand" "u")]
13706 (clobber (match_scratch:XF 3 "=2"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations"
13710 [(set_attr "type" "fpspc")
13711 (set_attr "mode" "XF")])
13713 (define_insn "fyl2x_extend<mode>xf3_i387"
13714 [(set (match_operand:XF 0 "register_operand" "=f")
13715 (unspec:XF [(float_extend:XF
13716 (match_operand:MODEF 1 "register_operand" "0"))
13717 (match_operand:XF 2 "register_operand" "u")]
13719 (clobber (match_scratch:XF 3 "=2"))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722 || TARGET_MIX_SSE_I387)
13723 && flag_unsafe_math_optimizations"
13725 [(set_attr "type" "fpspc")
13726 (set_attr "mode" "XF")])
13728 (define_expand "logxf2"
13729 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13730 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13731 (match_dup 2)] UNSPEC_FYL2X))
13732 (clobber (match_scratch:XF 3 ""))])]
13733 "TARGET_USE_FANCY_MATH_387
13734 && flag_unsafe_math_optimizations"
13736 operands[2] = gen_reg_rtx (XFmode);
13737 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13740 (define_expand "log<mode>2"
13741 [(use (match_operand:MODEF 0 "register_operand" ""))
13742 (use (match_operand:MODEF 1 "register_operand" ""))]
13743 "TARGET_USE_FANCY_MATH_387
13744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13745 || TARGET_MIX_SSE_I387)
13746 && flag_unsafe_math_optimizations"
13748 rtx op0 = gen_reg_rtx (XFmode);
13750 rtx op2 = gen_reg_rtx (XFmode);
13751 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13753 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13758 (define_expand "log10xf2"
13759 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13760 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13761 (match_dup 2)] UNSPEC_FYL2X))
13762 (clobber (match_scratch:XF 3 ""))])]
13763 "TARGET_USE_FANCY_MATH_387
13764 && flag_unsafe_math_optimizations"
13766 operands[2] = gen_reg_rtx (XFmode);
13767 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13770 (define_expand "log10<mode>2"
13771 [(use (match_operand:MODEF 0 "register_operand" ""))
13772 (use (match_operand:MODEF 1 "register_operand" ""))]
13773 "TARGET_USE_FANCY_MATH_387
13774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13775 || TARGET_MIX_SSE_I387)
13776 && flag_unsafe_math_optimizations"
13778 rtx op0 = gen_reg_rtx (XFmode);
13780 rtx op2 = gen_reg_rtx (XFmode);
13781 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13783 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13788 (define_expand "log2xf2"
13789 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13790 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13791 (match_dup 2)] UNSPEC_FYL2X))
13792 (clobber (match_scratch:XF 3 ""))])]
13793 "TARGET_USE_FANCY_MATH_387
13794 && flag_unsafe_math_optimizations"
13796 operands[2] = gen_reg_rtx (XFmode);
13797 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13800 (define_expand "log2<mode>2"
13801 [(use (match_operand:MODEF 0 "register_operand" ""))
13802 (use (match_operand:MODEF 1 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13805 || TARGET_MIX_SSE_I387)
13806 && flag_unsafe_math_optimizations"
13808 rtx op0 = gen_reg_rtx (XFmode);
13810 rtx op2 = gen_reg_rtx (XFmode);
13811 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13813 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13818 (define_insn "fyl2xp1xf3_i387"
13819 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13821 (match_operand:XF 2 "register_operand" "u")]
13823 (clobber (match_scratch:XF 3 "=2"))]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13827 [(set_attr "type" "fpspc")
13828 (set_attr "mode" "XF")])
13830 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13831 [(set (match_operand:XF 0 "register_operand" "=f")
13832 (unspec:XF [(float_extend:XF
13833 (match_operand:MODEF 1 "register_operand" "0"))
13834 (match_operand:XF 2 "register_operand" "u")]
13836 (clobber (match_scratch:XF 3 "=2"))]
13837 "TARGET_USE_FANCY_MATH_387
13838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13839 || TARGET_MIX_SSE_I387)
13840 && flag_unsafe_math_optimizations"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")])
13845 (define_expand "log1pxf2"
13846 [(use (match_operand:XF 0 "register_operand" ""))
13847 (use (match_operand:XF 1 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations"
13851 if (optimize_insn_for_size_p ())
13854 ix86_emit_i387_log1p (operands[0], operands[1]);
13858 (define_expand "log1p<mode>2"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "register_operand" ""))]
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"
13868 if (optimize_insn_for_size_p ())
13871 op0 = gen_reg_rtx (XFmode);
13873 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13875 ix86_emit_i387_log1p (op0, operands[1]);
13876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880 (define_insn "fxtractxf3_i387"
13881 [(set (match_operand:XF 0 "register_operand" "=f")
13882 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13883 UNSPEC_XTRACT_FRACT))
13884 (set (match_operand:XF 1 "register_operand" "=u")
13885 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13886 "TARGET_USE_FANCY_MATH_387
13887 && flag_unsafe_math_optimizations"
13889 [(set_attr "type" "fpspc")
13890 (set_attr "mode" "XF")])
13892 (define_insn "fxtract_extend<mode>xf3_i387"
13893 [(set (match_operand:XF 0 "register_operand" "=f")
13894 (unspec:XF [(float_extend:XF
13895 (match_operand:MODEF 2 "register_operand" "0"))]
13896 UNSPEC_XTRACT_FRACT))
13897 (set (match_operand:XF 1 "register_operand" "=u")
13898 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13899 "TARGET_USE_FANCY_MATH_387
13900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13901 || TARGET_MIX_SSE_I387)
13902 && flag_unsafe_math_optimizations"
13904 [(set_attr "type" "fpspc")
13905 (set_attr "mode" "XF")])
13907 (define_expand "logbxf2"
13908 [(parallel [(set (match_dup 2)
13909 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13910 UNSPEC_XTRACT_FRACT))
13911 (set (match_operand:XF 0 "register_operand" "")
13912 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13913 "TARGET_USE_FANCY_MATH_387
13914 && flag_unsafe_math_optimizations"
13915 "operands[2] = gen_reg_rtx (XFmode);")
13917 (define_expand "logb<mode>2"
13918 [(use (match_operand:MODEF 0 "register_operand" ""))
13919 (use (match_operand:MODEF 1 "register_operand" ""))]
13920 "TARGET_USE_FANCY_MATH_387
13921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13922 || TARGET_MIX_SSE_I387)
13923 && flag_unsafe_math_optimizations"
13925 rtx op0 = gen_reg_rtx (XFmode);
13926 rtx op1 = gen_reg_rtx (XFmode);
13928 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13933 (define_expand "ilogbxf2"
13934 [(use (match_operand:SI 0 "register_operand" ""))
13935 (use (match_operand:XF 1 "register_operand" ""))]
13936 "TARGET_USE_FANCY_MATH_387
13937 && flag_unsafe_math_optimizations"
13941 if (optimize_insn_for_size_p ())
13944 op0 = gen_reg_rtx (XFmode);
13945 op1 = gen_reg_rtx (XFmode);
13947 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13948 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13952 (define_expand "ilogb<mode>2"
13953 [(use (match_operand:SI 0 "register_operand" ""))
13954 (use (match_operand:MODEF 1 "register_operand" ""))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13957 || TARGET_MIX_SSE_I387)
13958 && flag_unsafe_math_optimizations"
13962 if (optimize_insn_for_size_p ())
13965 op0 = gen_reg_rtx (XFmode);
13966 op1 = gen_reg_rtx (XFmode);
13968 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13969 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13973 (define_insn "*f2xm1xf2_i387"
13974 [(set (match_operand:XF 0 "register_operand" "=f")
13975 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13980 [(set_attr "type" "fpspc")
13981 (set_attr "mode" "XF")])
13983 (define_insn "*fscalexf4_i387"
13984 [(set (match_operand:XF 0 "register_operand" "=f")
13985 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13986 (match_operand:XF 3 "register_operand" "1")]
13987 UNSPEC_FSCALE_FRACT))
13988 (set (match_operand:XF 1 "register_operand" "=u")
13989 (unspec:XF [(match_dup 2) (match_dup 3)]
13990 UNSPEC_FSCALE_EXP))]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13994 [(set_attr "type" "fpspc")
13995 (set_attr "mode" "XF")])
13997 (define_expand "expNcorexf3"
13998 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13999 (match_operand:XF 2 "register_operand" "")))
14000 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14001 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14002 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14003 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14004 (parallel [(set (match_operand:XF 0 "register_operand" "")
14005 (unspec:XF [(match_dup 8) (match_dup 4)]
14006 UNSPEC_FSCALE_FRACT))
14008 (unspec:XF [(match_dup 8) (match_dup 4)]
14009 UNSPEC_FSCALE_EXP))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14015 if (optimize_insn_for_size_p ())
14018 for (i = 3; i < 10; i++)
14019 operands[i] = gen_reg_rtx (XFmode);
14021 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14024 (define_expand "expxf2"
14025 [(use (match_operand:XF 0 "register_operand" ""))
14026 (use (match_operand:XF 1 "register_operand" ""))]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14032 if (optimize_insn_for_size_p ())
14035 op2 = gen_reg_rtx (XFmode);
14036 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14038 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14042 (define_expand "exp<mode>2"
14043 [(use (match_operand:MODEF 0 "register_operand" ""))
14044 (use (match_operand:MODEF 1 "general_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14047 || TARGET_MIX_SSE_I387)
14048 && flag_unsafe_math_optimizations"
14052 if (optimize_insn_for_size_p ())
14055 op0 = gen_reg_rtx (XFmode);
14056 op1 = gen_reg_rtx (XFmode);
14058 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14059 emit_insn (gen_expxf2 (op0, op1));
14060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14064 (define_expand "exp10xf2"
14065 [(use (match_operand:XF 0 "register_operand" ""))
14066 (use (match_operand:XF 1 "register_operand" ""))]
14067 "TARGET_USE_FANCY_MATH_387
14068 && flag_unsafe_math_optimizations"
14072 if (optimize_insn_for_size_p ())
14075 op2 = gen_reg_rtx (XFmode);
14076 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14078 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14082 (define_expand "exp10<mode>2"
14083 [(use (match_operand:MODEF 0 "register_operand" ""))
14084 (use (match_operand:MODEF 1 "general_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087 || TARGET_MIX_SSE_I387)
14088 && flag_unsafe_math_optimizations"
14092 if (optimize_insn_for_size_p ())
14095 op0 = gen_reg_rtx (XFmode);
14096 op1 = gen_reg_rtx (XFmode);
14098 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14099 emit_insn (gen_exp10xf2 (op0, op1));
14100 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14104 (define_expand "exp2xf2"
14105 [(use (match_operand:XF 0 "register_operand" ""))
14106 (use (match_operand:XF 1 "register_operand" ""))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14112 if (optimize_insn_for_size_p ())
14115 op2 = gen_reg_rtx (XFmode);
14116 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14118 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14122 (define_expand "exp2<mode>2"
14123 [(use (match_operand:MODEF 0 "register_operand" ""))
14124 (use (match_operand:MODEF 1 "general_operand" ""))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14127 || TARGET_MIX_SSE_I387)
14128 && flag_unsafe_math_optimizations"
14132 if (optimize_insn_for_size_p ())
14135 op0 = gen_reg_rtx (XFmode);
14136 op1 = gen_reg_rtx (XFmode);
14138 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14139 emit_insn (gen_exp2xf2 (op0, op1));
14140 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14144 (define_expand "expm1xf2"
14145 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14147 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14148 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14149 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14150 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14151 (parallel [(set (match_dup 7)
14152 (unspec:XF [(match_dup 6) (match_dup 4)]
14153 UNSPEC_FSCALE_FRACT))
14155 (unspec:XF [(match_dup 6) (match_dup 4)]
14156 UNSPEC_FSCALE_EXP))])
14157 (parallel [(set (match_dup 10)
14158 (unspec:XF [(match_dup 9) (match_dup 8)]
14159 UNSPEC_FSCALE_FRACT))
14160 (set (match_dup 11)
14161 (unspec:XF [(match_dup 9) (match_dup 8)]
14162 UNSPEC_FSCALE_EXP))])
14163 (set (match_dup 12) (minus:XF (match_dup 10)
14164 (float_extend:XF (match_dup 13))))
14165 (set (match_operand:XF 0 "register_operand" "")
14166 (plus:XF (match_dup 12) (match_dup 7)))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14172 if (optimize_insn_for_size_p ())
14175 for (i = 2; i < 13; i++)
14176 operands[i] = gen_reg_rtx (XFmode);
14179 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14181 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14184 (define_expand "expm1<mode>2"
14185 [(use (match_operand:MODEF 0 "register_operand" ""))
14186 (use (match_operand:MODEF 1 "general_operand" ""))]
14187 "TARGET_USE_FANCY_MATH_387
14188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189 || TARGET_MIX_SSE_I387)
14190 && flag_unsafe_math_optimizations"
14194 if (optimize_insn_for_size_p ())
14197 op0 = gen_reg_rtx (XFmode);
14198 op1 = gen_reg_rtx (XFmode);
14200 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14201 emit_insn (gen_expm1xf2 (op0, op1));
14202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14206 (define_expand "ldexpxf3"
14207 [(set (match_dup 3)
14208 (float:XF (match_operand:SI 2 "register_operand" "")))
14209 (parallel [(set (match_operand:XF 0 " register_operand" "")
14210 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14212 UNSPEC_FSCALE_FRACT))
14214 (unspec:XF [(match_dup 1) (match_dup 3)]
14215 UNSPEC_FSCALE_EXP))])]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14219 if (optimize_insn_for_size_p ())
14222 operands[3] = gen_reg_rtx (XFmode);
14223 operands[4] = gen_reg_rtx (XFmode);
14226 (define_expand "ldexp<mode>3"
14227 [(use (match_operand:MODEF 0 "register_operand" ""))
14228 (use (match_operand:MODEF 1 "general_operand" ""))
14229 (use (match_operand:SI 2 "register_operand" ""))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14232 || TARGET_MIX_SSE_I387)
14233 && flag_unsafe_math_optimizations"
14237 if (optimize_insn_for_size_p ())
14240 op0 = gen_reg_rtx (XFmode);
14241 op1 = gen_reg_rtx (XFmode);
14243 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14244 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14249 (define_expand "scalbxf3"
14250 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14251 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14252 (match_operand:XF 2 "register_operand" "")]
14253 UNSPEC_FSCALE_FRACT))
14255 (unspec:XF [(match_dup 1) (match_dup 2)]
14256 UNSPEC_FSCALE_EXP))])]
14257 "TARGET_USE_FANCY_MATH_387
14258 && flag_unsafe_math_optimizations"
14260 if (optimize_insn_for_size_p ())
14263 operands[3] = gen_reg_rtx (XFmode);
14266 (define_expand "scalb<mode>3"
14267 [(use (match_operand:MODEF 0 "register_operand" ""))
14268 (use (match_operand:MODEF 1 "general_operand" ""))
14269 (use (match_operand:MODEF 2 "general_operand" ""))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14277 if (optimize_insn_for_size_p ())
14280 op0 = gen_reg_rtx (XFmode);
14281 op1 = gen_reg_rtx (XFmode);
14282 op2 = gen_reg_rtx (XFmode);
14284 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14285 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14286 emit_insn (gen_scalbxf3 (op0, op1, op2));
14287 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14291 (define_expand "significandxf2"
14292 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14293 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14294 UNSPEC_XTRACT_FRACT))
14296 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14299 "operands[2] = gen_reg_rtx (XFmode);")
14301 (define_expand "significand<mode>2"
14302 [(use (match_operand:MODEF 0 "register_operand" ""))
14303 (use (match_operand:MODEF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14306 || TARGET_MIX_SSE_I387)
14307 && flag_unsafe_math_optimizations"
14309 rtx op0 = gen_reg_rtx (XFmode);
14310 rtx op1 = gen_reg_rtx (XFmode);
14312 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14318 (define_insn "sse4_1_round<mode>2"
14319 [(set (match_operand:MODEF 0 "register_operand" "=x")
14320 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14321 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14324 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14325 [(set_attr "type" "ssecvt")
14326 (set_attr "prefix_extra" "1")
14327 (set_attr "prefix" "maybe_vex")
14328 (set_attr "mode" "<MODE>")])
14330 (define_insn "rintxf2"
14331 [(set (match_operand:XF 0 "register_operand" "=f")
14332 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14334 "TARGET_USE_FANCY_MATH_387
14335 && flag_unsafe_math_optimizations"
14337 [(set_attr "type" "fpspc")
14338 (set_attr "mode" "XF")])
14340 (define_expand "rint<mode>2"
14341 [(use (match_operand:MODEF 0 "register_operand" ""))
14342 (use (match_operand:MODEF 1 "register_operand" ""))]
14343 "(TARGET_USE_FANCY_MATH_387
14344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14345 || TARGET_MIX_SSE_I387)
14346 && flag_unsafe_math_optimizations)
14347 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14348 && !flag_trapping_math)"
14350 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14351 && !flag_trapping_math)
14353 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14356 emit_insn (gen_sse4_1_round<mode>2
14357 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14359 ix86_expand_rint (operand0, operand1);
14363 rtx op0 = gen_reg_rtx (XFmode);
14364 rtx op1 = gen_reg_rtx (XFmode);
14366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367 emit_insn (gen_rintxf2 (op0, op1));
14369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14374 (define_expand "round<mode>2"
14375 [(match_operand:MODEF 0 "register_operand" "")
14376 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14378 && !flag_trapping_math && !flag_rounding_math"
14380 if (optimize_insn_for_size_p ())
14382 if (TARGET_64BIT || (<MODE>mode != DFmode))
14383 ix86_expand_round (operand0, operand1);
14385 ix86_expand_rounddf_32 (operand0, operand1);
14389 (define_insn_and_split "*fistdi2_1"
14390 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14391 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14393 "TARGET_USE_FANCY_MATH_387
14394 && can_create_pseudo_p ()"
14399 if (memory_operand (operands[0], VOIDmode))
14400 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14403 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14404 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14409 [(set_attr "type" "fpspc")
14410 (set_attr "mode" "DI")])
14412 (define_insn "fistdi2"
14413 [(set (match_operand:DI 0 "memory_operand" "=m")
14414 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14416 (clobber (match_scratch:XF 2 "=&1f"))]
14417 "TARGET_USE_FANCY_MATH_387"
14418 "* return output_fix_trunc (insn, operands, false);"
14419 [(set_attr "type" "fpspc")
14420 (set_attr "mode" "DI")])
14422 (define_insn "fistdi2_with_temp"
14423 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14424 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14426 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14427 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14428 "TARGET_USE_FANCY_MATH_387"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "DI")])
14434 [(set (match_operand:DI 0 "register_operand" "")
14435 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14437 (clobber (match_operand:DI 2 "memory_operand" ""))
14438 (clobber (match_scratch 3 ""))]
14440 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14441 (clobber (match_dup 3))])
14442 (set (match_dup 0) (match_dup 2))])
14445 [(set (match_operand:DI 0 "memory_operand" "")
14446 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14448 (clobber (match_operand:DI 2 "memory_operand" ""))
14449 (clobber (match_scratch 3 ""))]
14451 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14452 (clobber (match_dup 3))])])
14454 (define_insn_and_split "*fist<mode>2_1"
14455 [(set (match_operand:SWI24 0 "register_operand" "")
14456 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14458 "TARGET_USE_FANCY_MATH_387
14459 && can_create_pseudo_p ()"
14464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14465 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14469 [(set_attr "type" "fpspc")
14470 (set_attr "mode" "<MODE>")])
14472 (define_insn "fist<mode>2"
14473 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14474 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14476 "TARGET_USE_FANCY_MATH_387"
14477 "* return output_fix_trunc (insn, operands, false);"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "<MODE>")])
14481 (define_insn "fist<mode>2_with_temp"
14482 [(set (match_operand:SWI24 0 "register_operand" "=r")
14483 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14485 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14486 "TARGET_USE_FANCY_MATH_387"
14488 [(set_attr "type" "fpspc")
14489 (set_attr "mode" "<MODE>")])
14492 [(set (match_operand:SWI24 0 "register_operand" "")
14493 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14495 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14497 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14498 (set (match_dup 0) (match_dup 2))])
14501 [(set (match_operand:SWI24 0 "memory_operand" "")
14502 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14504 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14506 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14508 (define_expand "lrintxf<mode>2"
14509 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14510 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14512 "TARGET_USE_FANCY_MATH_387")
14514 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14515 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14516 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14517 UNSPEC_FIX_NOTRUNC))]
14518 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14519 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14521 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14522 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14523 (match_operand:MODEF 1 "register_operand" "")]
14524 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14525 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14526 && !flag_trapping_math && !flag_rounding_math"
14528 if (optimize_insn_for_size_p ())
14530 ix86_expand_lround (operand0, operand1);
14534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14535 (define_insn_and_split "frndintxf2_floor"
14536 [(set (match_operand:XF 0 "register_operand" "")
14537 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14538 UNSPEC_FRNDINT_FLOOR))
14539 (clobber (reg:CC FLAGS_REG))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations
14542 && can_create_pseudo_p ()"
14547 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14549 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14550 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14552 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14553 operands[2], operands[3]));
14556 [(set_attr "type" "frndint")
14557 (set_attr "i387_cw" "floor")
14558 (set_attr "mode" "XF")])
14560 (define_insn "frndintxf2_floor_i387"
14561 [(set (match_operand:XF 0 "register_operand" "=f")
14562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14563 UNSPEC_FRNDINT_FLOOR))
14564 (use (match_operand:HI 2 "memory_operand" "m"))
14565 (use (match_operand:HI 3 "memory_operand" "m"))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && flag_unsafe_math_optimizations"
14568 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14569 [(set_attr "type" "frndint")
14570 (set_attr "i387_cw" "floor")
14571 (set_attr "mode" "XF")])
14573 (define_expand "floorxf2"
14574 [(use (match_operand:XF 0 "register_operand" ""))
14575 (use (match_operand:XF 1 "register_operand" ""))]
14576 "TARGET_USE_FANCY_MATH_387
14577 && flag_unsafe_math_optimizations"
14579 if (optimize_insn_for_size_p ())
14581 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14585 (define_expand "floor<mode>2"
14586 [(use (match_operand:MODEF 0 "register_operand" ""))
14587 (use (match_operand:MODEF 1 "register_operand" ""))]
14588 "(TARGET_USE_FANCY_MATH_387
14589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14590 || TARGET_MIX_SSE_I387)
14591 && flag_unsafe_math_optimizations)
14592 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14593 && !flag_trapping_math)"
14595 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14596 && !flag_trapping_math
14597 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14599 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14602 emit_insn (gen_sse4_1_round<mode>2
14603 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14604 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14605 ix86_expand_floorceil (operand0, operand1, true);
14607 ix86_expand_floorceildf_32 (operand0, operand1, true);
14613 if (optimize_insn_for_size_p ())
14616 op0 = gen_reg_rtx (XFmode);
14617 op1 = gen_reg_rtx (XFmode);
14618 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14619 emit_insn (gen_frndintxf2_floor (op0, op1));
14621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14626 (define_insn_and_split "*fist<mode>2_floor_1"
14627 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14628 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14629 UNSPEC_FIST_FLOOR))
14630 (clobber (reg:CC FLAGS_REG))]
14631 "TARGET_USE_FANCY_MATH_387
14632 && flag_unsafe_math_optimizations
14633 && can_create_pseudo_p ()"
14638 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14640 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14641 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14642 if (memory_operand (operands[0], VOIDmode))
14643 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14644 operands[2], operands[3]));
14647 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14648 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14649 operands[2], operands[3],
14654 [(set_attr "type" "fistp")
14655 (set_attr "i387_cw" "floor")
14656 (set_attr "mode" "<MODE>")])
14658 (define_insn "fistdi2_floor"
14659 [(set (match_operand:DI 0 "memory_operand" "=m")
14660 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14661 UNSPEC_FIST_FLOOR))
14662 (use (match_operand:HI 2 "memory_operand" "m"))
14663 (use (match_operand:HI 3 "memory_operand" "m"))
14664 (clobber (match_scratch:XF 4 "=&1f"))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14667 "* return output_fix_trunc (insn, operands, false);"
14668 [(set_attr "type" "fistp")
14669 (set_attr "i387_cw" "floor")
14670 (set_attr "mode" "DI")])
14672 (define_insn "fistdi2_floor_with_temp"
14673 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14674 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14675 UNSPEC_FIST_FLOOR))
14676 (use (match_operand:HI 2 "memory_operand" "m,m"))
14677 (use (match_operand:HI 3 "memory_operand" "m,m"))
14678 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14679 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14680 "TARGET_USE_FANCY_MATH_387
14681 && flag_unsafe_math_optimizations"
14683 [(set_attr "type" "fistp")
14684 (set_attr "i387_cw" "floor")
14685 (set_attr "mode" "DI")])
14688 [(set (match_operand:DI 0 "register_operand" "")
14689 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14690 UNSPEC_FIST_FLOOR))
14691 (use (match_operand:HI 2 "memory_operand" ""))
14692 (use (match_operand:HI 3 "memory_operand" ""))
14693 (clobber (match_operand:DI 4 "memory_operand" ""))
14694 (clobber (match_scratch 5 ""))]
14696 [(parallel [(set (match_dup 4)
14697 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14698 (use (match_dup 2))
14699 (use (match_dup 3))
14700 (clobber (match_dup 5))])
14701 (set (match_dup 0) (match_dup 4))])
14704 [(set (match_operand:DI 0 "memory_operand" "")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14706 UNSPEC_FIST_FLOOR))
14707 (use (match_operand:HI 2 "memory_operand" ""))
14708 (use (match_operand:HI 3 "memory_operand" ""))
14709 (clobber (match_operand:DI 4 "memory_operand" ""))
14710 (clobber (match_scratch 5 ""))]
14712 [(parallel [(set (match_dup 0)
14713 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14714 (use (match_dup 2))
14715 (use (match_dup 3))
14716 (clobber (match_dup 5))])])
14718 (define_insn "fist<mode>2_floor"
14719 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14720 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14721 UNSPEC_FIST_FLOOR))
14722 (use (match_operand:HI 2 "memory_operand" "m"))
14723 (use (match_operand:HI 3 "memory_operand" "m"))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations"
14726 "* return output_fix_trunc (insn, operands, false);"
14727 [(set_attr "type" "fistp")
14728 (set_attr "i387_cw" "floor")
14729 (set_attr "mode" "<MODE>")])
14731 (define_insn "fist<mode>2_floor_with_temp"
14732 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14733 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14734 UNSPEC_FIST_FLOOR))
14735 (use (match_operand:HI 2 "memory_operand" "m,m"))
14736 (use (match_operand:HI 3 "memory_operand" "m,m"))
14737 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14738 "TARGET_USE_FANCY_MATH_387
14739 && flag_unsafe_math_optimizations"
14741 [(set_attr "type" "fistp")
14742 (set_attr "i387_cw" "floor")
14743 (set_attr "mode" "<MODE>")])
14746 [(set (match_operand:SWI24 0 "register_operand" "")
14747 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14748 UNSPEC_FIST_FLOOR))
14749 (use (match_operand:HI 2 "memory_operand" ""))
14750 (use (match_operand:HI 3 "memory_operand" ""))
14751 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14753 [(parallel [(set (match_dup 4)
14754 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14755 (use (match_dup 2))
14756 (use (match_dup 3))])
14757 (set (match_dup 0) (match_dup 4))])
14760 [(set (match_operand:SWI24 0 "memory_operand" "")
14761 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14762 UNSPEC_FIST_FLOOR))
14763 (use (match_operand:HI 2 "memory_operand" ""))
14764 (use (match_operand:HI 3 "memory_operand" ""))
14765 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14767 [(parallel [(set (match_dup 0)
14768 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14769 (use (match_dup 2))
14770 (use (match_dup 3))])])
14772 (define_expand "lfloorxf<mode>2"
14773 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14774 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14775 UNSPEC_FIST_FLOOR))
14776 (clobber (reg:CC FLAGS_REG))])]
14777 "TARGET_USE_FANCY_MATH_387
14778 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14779 && flag_unsafe_math_optimizations")
14781 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14782 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14783 (match_operand:MODEF 1 "register_operand" "")]
14784 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14785 && !flag_trapping_math"
14787 if (TARGET_64BIT && optimize_insn_for_size_p ())
14789 ix86_expand_lfloorceil (operand0, operand1, true);
14793 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14794 (define_insn_and_split "frndintxf2_ceil"
14795 [(set (match_operand:XF 0 "register_operand" "")
14796 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14797 UNSPEC_FRNDINT_CEIL))
14798 (clobber (reg:CC FLAGS_REG))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && flag_unsafe_math_optimizations
14801 && can_create_pseudo_p ()"
14806 ix86_optimize_mode_switching[I387_CEIL] = 1;
14808 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14809 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14811 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14812 operands[2], operands[3]));
14815 [(set_attr "type" "frndint")
14816 (set_attr "i387_cw" "ceil")
14817 (set_attr "mode" "XF")])
14819 (define_insn "frndintxf2_ceil_i387"
14820 [(set (match_operand:XF 0 "register_operand" "=f")
14821 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14822 UNSPEC_FRNDINT_CEIL))
14823 (use (match_operand:HI 2 "memory_operand" "m"))
14824 (use (match_operand:HI 3 "memory_operand" "m"))]
14825 "TARGET_USE_FANCY_MATH_387
14826 && flag_unsafe_math_optimizations"
14827 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14828 [(set_attr "type" "frndint")
14829 (set_attr "i387_cw" "ceil")
14830 (set_attr "mode" "XF")])
14832 (define_expand "ceilxf2"
14833 [(use (match_operand:XF 0 "register_operand" ""))
14834 (use (match_operand:XF 1 "register_operand" ""))]
14835 "TARGET_USE_FANCY_MATH_387
14836 && flag_unsafe_math_optimizations"
14838 if (optimize_insn_for_size_p ())
14840 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14844 (define_expand "ceil<mode>2"
14845 [(use (match_operand:MODEF 0 "register_operand" ""))
14846 (use (match_operand:MODEF 1 "register_operand" ""))]
14847 "(TARGET_USE_FANCY_MATH_387
14848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14849 || TARGET_MIX_SSE_I387)
14850 && flag_unsafe_math_optimizations)
14851 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14852 && !flag_trapping_math)"
14854 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14855 && !flag_trapping_math
14856 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14859 emit_insn (gen_sse4_1_round<mode>2
14860 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14861 else if (optimize_insn_for_size_p ())
14863 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14864 ix86_expand_floorceil (operand0, operand1, false);
14866 ix86_expand_floorceildf_32 (operand0, operand1, false);
14872 if (optimize_insn_for_size_p ())
14875 op0 = gen_reg_rtx (XFmode);
14876 op1 = gen_reg_rtx (XFmode);
14877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14878 emit_insn (gen_frndintxf2_ceil (op0, op1));
14880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14885 (define_insn_and_split "*fist<mode>2_ceil_1"
14886 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14887 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14889 (clobber (reg:CC FLAGS_REG))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations
14892 && can_create_pseudo_p ()"
14897 ix86_optimize_mode_switching[I387_CEIL] = 1;
14899 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14900 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14901 if (memory_operand (operands[0], VOIDmode))
14902 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14903 operands[2], operands[3]));
14906 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14907 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14908 operands[2], operands[3],
14913 [(set_attr "type" "fistp")
14914 (set_attr "i387_cw" "ceil")
14915 (set_attr "mode" "<MODE>")])
14917 (define_insn "fistdi2_ceil"
14918 [(set (match_operand:DI 0 "memory_operand" "=m")
14919 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14921 (use (match_operand:HI 2 "memory_operand" "m"))
14922 (use (match_operand:HI 3 "memory_operand" "m"))
14923 (clobber (match_scratch:XF 4 "=&1f"))]
14924 "TARGET_USE_FANCY_MATH_387
14925 && flag_unsafe_math_optimizations"
14926 "* return output_fix_trunc (insn, operands, false);"
14927 [(set_attr "type" "fistp")
14928 (set_attr "i387_cw" "ceil")
14929 (set_attr "mode" "DI")])
14931 (define_insn "fistdi2_ceil_with_temp"
14932 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14933 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14935 (use (match_operand:HI 2 "memory_operand" "m,m"))
14936 (use (match_operand:HI 3 "memory_operand" "m,m"))
14937 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14938 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "DI")])
14947 [(set (match_operand:DI 0 "register_operand" "")
14948 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14950 (use (match_operand:HI 2 "memory_operand" ""))
14951 (use (match_operand:HI 3 "memory_operand" ""))
14952 (clobber (match_operand:DI 4 "memory_operand" ""))
14953 (clobber (match_scratch 5 ""))]
14955 [(parallel [(set (match_dup 4)
14956 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14957 (use (match_dup 2))
14958 (use (match_dup 3))
14959 (clobber (match_dup 5))])
14960 (set (match_dup 0) (match_dup 4))])
14963 [(set (match_operand:DI 0 "memory_operand" "")
14964 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14966 (use (match_operand:HI 2 "memory_operand" ""))
14967 (use (match_operand:HI 3 "memory_operand" ""))
14968 (clobber (match_operand:DI 4 "memory_operand" ""))
14969 (clobber (match_scratch 5 ""))]
14971 [(parallel [(set (match_dup 0)
14972 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14973 (use (match_dup 2))
14974 (use (match_dup 3))
14975 (clobber (match_dup 5))])])
14977 (define_insn "fist<mode>2_ceil"
14978 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14979 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14981 (use (match_operand:HI 2 "memory_operand" "m"))
14982 (use (match_operand:HI 3 "memory_operand" "m"))]
14983 "TARGET_USE_FANCY_MATH_387
14984 && flag_unsafe_math_optimizations"
14985 "* return output_fix_trunc (insn, operands, false);"
14986 [(set_attr "type" "fistp")
14987 (set_attr "i387_cw" "ceil")
14988 (set_attr "mode" "<MODE>")])
14990 (define_insn "fist<mode>2_ceil_with_temp"
14991 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14992 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14994 (use (match_operand:HI 2 "memory_operand" "m,m"))
14995 (use (match_operand:HI 3 "memory_operand" "m,m"))
14996 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14997 "TARGET_USE_FANCY_MATH_387
14998 && flag_unsafe_math_optimizations"
15000 [(set_attr "type" "fistp")
15001 (set_attr "i387_cw" "ceil")
15002 (set_attr "mode" "<MODE>")])
15005 [(set (match_operand:SWI24 0 "register_operand" "")
15006 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15008 (use (match_operand:HI 2 "memory_operand" ""))
15009 (use (match_operand:HI 3 "memory_operand" ""))
15010 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15012 [(parallel [(set (match_dup 4)
15013 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15014 (use (match_dup 2))
15015 (use (match_dup 3))])
15016 (set (match_dup 0) (match_dup 4))])
15019 [(set (match_operand:SWI24 0 "memory_operand" "")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15022 (use (match_operand:HI 2 "memory_operand" ""))
15023 (use (match_operand:HI 3 "memory_operand" ""))
15024 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15026 [(parallel [(set (match_dup 0)
15027 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15028 (use (match_dup 2))
15029 (use (match_dup 3))])])
15031 (define_expand "lceilxf<mode>2"
15032 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15033 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15035 (clobber (reg:CC FLAGS_REG))])]
15036 "TARGET_USE_FANCY_MATH_387
15037 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15038 && flag_unsafe_math_optimizations")
15040 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15041 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15042 (match_operand:MODEF 1 "register_operand" "")]
15043 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15044 && !flag_trapping_math"
15046 ix86_expand_lfloorceil (operand0, operand1, false);
15050 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15051 (define_insn_and_split "frndintxf2_trunc"
15052 [(set (match_operand:XF 0 "register_operand" "")
15053 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15054 UNSPEC_FRNDINT_TRUNC))
15055 (clobber (reg:CC FLAGS_REG))]
15056 "TARGET_USE_FANCY_MATH_387
15057 && flag_unsafe_math_optimizations
15058 && can_create_pseudo_p ()"
15063 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15065 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15066 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15068 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15069 operands[2], operands[3]));
15072 [(set_attr "type" "frndint")
15073 (set_attr "i387_cw" "trunc")
15074 (set_attr "mode" "XF")])
15076 (define_insn "frndintxf2_trunc_i387"
15077 [(set (match_operand:XF 0 "register_operand" "=f")
15078 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15079 UNSPEC_FRNDINT_TRUNC))
15080 (use (match_operand:HI 2 "memory_operand" "m"))
15081 (use (match_operand:HI 3 "memory_operand" "m"))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations"
15084 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15085 [(set_attr "type" "frndint")
15086 (set_attr "i387_cw" "trunc")
15087 (set_attr "mode" "XF")])
15089 (define_expand "btruncxf2"
15090 [(use (match_operand:XF 0 "register_operand" ""))
15091 (use (match_operand:XF 1 "register_operand" ""))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations"
15095 if (optimize_insn_for_size_p ())
15097 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15101 (define_expand "btrunc<mode>2"
15102 [(use (match_operand:MODEF 0 "register_operand" ""))
15103 (use (match_operand:MODEF 1 "register_operand" ""))]
15104 "(TARGET_USE_FANCY_MATH_387
15105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15106 || TARGET_MIX_SSE_I387)
15107 && flag_unsafe_math_optimizations)
15108 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15109 && !flag_trapping_math)"
15111 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15112 && !flag_trapping_math
15113 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15116 emit_insn (gen_sse4_1_round<mode>2
15117 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15118 else if (optimize_insn_for_size_p ())
15120 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15121 ix86_expand_trunc (operand0, operand1);
15123 ix86_expand_truncdf_32 (operand0, operand1);
15129 if (optimize_insn_for_size_p ())
15132 op0 = gen_reg_rtx (XFmode);
15133 op1 = gen_reg_rtx (XFmode);
15134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15135 emit_insn (gen_frndintxf2_trunc (op0, op1));
15137 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15142 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15143 (define_insn_and_split "frndintxf2_mask_pm"
15144 [(set (match_operand:XF 0 "register_operand" "")
15145 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15146 UNSPEC_FRNDINT_MASK_PM))
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations
15150 && can_create_pseudo_p ()"
15155 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15157 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15158 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15160 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15161 operands[2], operands[3]));
15164 [(set_attr "type" "frndint")
15165 (set_attr "i387_cw" "mask_pm")
15166 (set_attr "mode" "XF")])
15168 (define_insn "frndintxf2_mask_pm_i387"
15169 [(set (match_operand:XF 0 "register_operand" "=f")
15170 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15171 UNSPEC_FRNDINT_MASK_PM))
15172 (use (match_operand:HI 2 "memory_operand" "m"))
15173 (use (match_operand:HI 3 "memory_operand" "m"))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && flag_unsafe_math_optimizations"
15176 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15177 [(set_attr "type" "frndint")
15178 (set_attr "i387_cw" "mask_pm")
15179 (set_attr "mode" "XF")])
15181 (define_expand "nearbyintxf2"
15182 [(use (match_operand:XF 0 "register_operand" ""))
15183 (use (match_operand:XF 1 "register_operand" ""))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15187 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15191 (define_expand "nearbyint<mode>2"
15192 [(use (match_operand:MODEF 0 "register_operand" ""))
15193 (use (match_operand:MODEF 1 "register_operand" ""))]
15194 "TARGET_USE_FANCY_MATH_387
15195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15196 || TARGET_MIX_SSE_I387)
15197 && flag_unsafe_math_optimizations"
15199 rtx op0 = gen_reg_rtx (XFmode);
15200 rtx op1 = gen_reg_rtx (XFmode);
15202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15203 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15205 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15209 (define_insn "fxam<mode>2_i387"
15210 [(set (match_operand:HI 0 "register_operand" "=a")
15212 [(match_operand:X87MODEF 1 "register_operand" "f")]
15214 "TARGET_USE_FANCY_MATH_387"
15215 "fxam\n\tfnstsw\t%0"
15216 [(set_attr "type" "multi")
15217 (set_attr "length" "4")
15218 (set_attr "unit" "i387")
15219 (set_attr "mode" "<MODE>")])
15221 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15222 [(set (match_operand:HI 0 "register_operand" "")
15224 [(match_operand:MODEF 1 "memory_operand" "")]
15226 "TARGET_USE_FANCY_MATH_387
15227 && can_create_pseudo_p ()"
15230 [(set (match_dup 2)(match_dup 1))
15232 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15234 operands[2] = gen_reg_rtx (<MODE>mode);
15236 MEM_VOLATILE_P (operands[1]) = 1;
15238 [(set_attr "type" "multi")
15239 (set_attr "unit" "i387")
15240 (set_attr "mode" "<MODE>")])
15242 (define_expand "isinfxf2"
15243 [(use (match_operand:SI 0 "register_operand" ""))
15244 (use (match_operand:XF 1 "register_operand" ""))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && TARGET_C99_FUNCTIONS"
15248 rtx mask = GEN_INT (0x45);
15249 rtx val = GEN_INT (0x05);
15253 rtx scratch = gen_reg_rtx (HImode);
15254 rtx res = gen_reg_rtx (QImode);
15256 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15258 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15259 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15260 cond = gen_rtx_fmt_ee (EQ, QImode,
15261 gen_rtx_REG (CCmode, FLAGS_REG),
15263 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15264 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15268 (define_expand "isinf<mode>2"
15269 [(use (match_operand:SI 0 "register_operand" ""))
15270 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15271 "TARGET_USE_FANCY_MATH_387
15272 && TARGET_C99_FUNCTIONS
15273 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15275 rtx mask = GEN_INT (0x45);
15276 rtx val = GEN_INT (0x05);
15280 rtx scratch = gen_reg_rtx (HImode);
15281 rtx res = gen_reg_rtx (QImode);
15283 /* Remove excess precision by forcing value through memory. */
15284 if (memory_operand (operands[1], VOIDmode))
15285 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15288 enum ix86_stack_slot slot = (virtuals_instantiated
15291 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15293 emit_move_insn (temp, operands[1]);
15294 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15297 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15298 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15299 cond = gen_rtx_fmt_ee (EQ, QImode,
15300 gen_rtx_REG (CCmode, FLAGS_REG),
15302 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15303 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15307 (define_expand "signbitxf2"
15308 [(use (match_operand:SI 0 "register_operand" ""))
15309 (use (match_operand:XF 1 "register_operand" ""))]
15310 "TARGET_USE_FANCY_MATH_387"
15312 rtx scratch = gen_reg_rtx (HImode);
15314 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15315 emit_insn (gen_andsi3 (operands[0],
15316 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15320 (define_insn "movmsk_df"
15321 [(set (match_operand:SI 0 "register_operand" "=r")
15323 [(match_operand:DF 1 "register_operand" "x")]
15325 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15326 "%vmovmskpd\t{%1, %0|%0, %1}"
15327 [(set_attr "type" "ssemov")
15328 (set_attr "prefix" "maybe_vex")
15329 (set_attr "mode" "DF")])
15331 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15332 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15333 (define_expand "signbitdf2"
15334 [(use (match_operand:SI 0 "register_operand" ""))
15335 (use (match_operand:DF 1 "register_operand" ""))]
15336 "TARGET_USE_FANCY_MATH_387
15337 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15339 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15341 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15342 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15346 rtx scratch = gen_reg_rtx (HImode);
15348 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15349 emit_insn (gen_andsi3 (operands[0],
15350 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15355 (define_expand "signbitsf2"
15356 [(use (match_operand:SI 0 "register_operand" ""))
15357 (use (match_operand:SF 1 "register_operand" ""))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15361 rtx scratch = gen_reg_rtx (HImode);
15363 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15364 emit_insn (gen_andsi3 (operands[0],
15365 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15369 ;; Block operation instructions
15372 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15375 [(set_attr "length" "1")
15376 (set_attr "length_immediate" "0")
15377 (set_attr "modrm" "0")])
15379 (define_expand "movmem<mode>"
15380 [(use (match_operand:BLK 0 "memory_operand" ""))
15381 (use (match_operand:BLK 1 "memory_operand" ""))
15382 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15383 (use (match_operand:SWI48 3 "const_int_operand" ""))
15384 (use (match_operand:SI 4 "const_int_operand" ""))
15385 (use (match_operand:SI 5 "const_int_operand" ""))]
15388 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15389 operands[4], operands[5]))
15395 ;; Most CPUs don't like single string operations
15396 ;; Handle this case here to simplify previous expander.
15398 (define_expand "strmov"
15399 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15400 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15401 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15402 (clobber (reg:CC FLAGS_REG))])
15403 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15404 (clobber (reg:CC FLAGS_REG))])]
15407 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15409 /* If .md ever supports :P for Pmode, these can be directly
15410 in the pattern above. */
15411 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15412 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15414 /* Can't use this if the user has appropriated esi or edi. */
15415 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15416 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15418 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15419 operands[2], operands[3],
15420 operands[5], operands[6]));
15424 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15427 (define_expand "strmov_singleop"
15428 [(parallel [(set (match_operand 1 "memory_operand" "")
15429 (match_operand 3 "memory_operand" ""))
15430 (set (match_operand 0 "register_operand" "")
15431 (match_operand 4 "" ""))
15432 (set (match_operand 2 "register_operand" "")
15433 (match_operand 5 "" ""))])]
15435 "ix86_current_function_needs_cld = 1;")
15437 (define_insn "*strmovdi_rex_1"
15438 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15439 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15440 (set (match_operand:DI 0 "register_operand" "=D")
15441 (plus:DI (match_dup 2)
15443 (set (match_operand:DI 1 "register_operand" "=S")
15444 (plus:DI (match_dup 3)
15448 [(set_attr "type" "str")
15449 (set_attr "memory" "both")
15450 (set_attr "mode" "DI")])
15452 (define_insn "*strmovsi_1"
15453 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15454 (mem:SI (match_operand:P 3 "register_operand" "1")))
15455 (set (match_operand:P 0 "register_operand" "=D")
15456 (plus:P (match_dup 2)
15458 (set (match_operand:P 1 "register_operand" "=S")
15459 (plus:P (match_dup 3)
15463 [(set_attr "type" "str")
15464 (set_attr "memory" "both")
15465 (set_attr "mode" "SI")])
15467 (define_insn "*strmovhi_1"
15468 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15469 (mem:HI (match_operand:P 3 "register_operand" "1")))
15470 (set (match_operand:P 0 "register_operand" "=D")
15471 (plus:P (match_dup 2)
15473 (set (match_operand:P 1 "register_operand" "=S")
15474 (plus:P (match_dup 3)
15478 [(set_attr "type" "str")
15479 (set_attr "memory" "both")
15480 (set_attr "mode" "HI")])
15482 (define_insn "*strmovqi_1"
15483 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15484 (mem:QI (match_operand:P 3 "register_operand" "1")))
15485 (set (match_operand:P 0 "register_operand" "=D")
15486 (plus:P (match_dup 2)
15488 (set (match_operand:P 1 "register_operand" "=S")
15489 (plus:P (match_dup 3)
15493 [(set_attr "type" "str")
15494 (set_attr "memory" "both")
15495 (set (attr "prefix_rex")
15497 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15499 (const_string "*")))
15500 (set_attr "mode" "QI")])
15502 (define_expand "rep_mov"
15503 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15504 (set (match_operand 0 "register_operand" "")
15505 (match_operand 5 "" ""))
15506 (set (match_operand 2 "register_operand" "")
15507 (match_operand 6 "" ""))
15508 (set (match_operand 1 "memory_operand" "")
15509 (match_operand 3 "memory_operand" ""))
15510 (use (match_dup 4))])]
15512 "ix86_current_function_needs_cld = 1;")
15514 (define_insn "*rep_movdi_rex64"
15515 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15516 (set (match_operand:DI 0 "register_operand" "=D")
15517 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15519 (match_operand:DI 3 "register_operand" "0")))
15520 (set (match_operand:DI 1 "register_operand" "=S")
15521 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15522 (match_operand:DI 4 "register_operand" "1")))
15523 (set (mem:BLK (match_dup 3))
15524 (mem:BLK (match_dup 4)))
15525 (use (match_dup 5))]
15528 [(set_attr "type" "str")
15529 (set_attr "prefix_rep" "1")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "DI")])
15533 (define_insn "*rep_movsi"
15534 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15535 (set (match_operand:P 0 "register_operand" "=D")
15536 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15538 (match_operand:P 3 "register_operand" "0")))
15539 (set (match_operand:P 1 "register_operand" "=S")
15540 (plus:P (ashift:P (match_dup 5) (const_int 2))
15541 (match_operand:P 4 "register_operand" "1")))
15542 (set (mem:BLK (match_dup 3))
15543 (mem:BLK (match_dup 4)))
15544 (use (match_dup 5))]
15546 "rep{%;} movs{l|d}"
15547 [(set_attr "type" "str")
15548 (set_attr "prefix_rep" "1")
15549 (set_attr "memory" "both")
15550 (set_attr "mode" "SI")])
15552 (define_insn "*rep_movqi"
15553 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15554 (set (match_operand:P 0 "register_operand" "=D")
15555 (plus:P (match_operand:P 3 "register_operand" "0")
15556 (match_operand:P 5 "register_operand" "2")))
15557 (set (match_operand:P 1 "register_operand" "=S")
15558 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15559 (set (mem:BLK (match_dup 3))
15560 (mem:BLK (match_dup 4)))
15561 (use (match_dup 5))]
15564 [(set_attr "type" "str")
15565 (set_attr "prefix_rep" "1")
15566 (set_attr "memory" "both")
15567 (set_attr "mode" "QI")])
15569 (define_expand "setmem<mode>"
15570 [(use (match_operand:BLK 0 "memory_operand" ""))
15571 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15572 (use (match_operand:QI 2 "nonmemory_operand" ""))
15573 (use (match_operand 3 "const_int_operand" ""))
15574 (use (match_operand:SI 4 "const_int_operand" ""))
15575 (use (match_operand:SI 5 "const_int_operand" ""))]
15578 if (ix86_expand_setmem (operands[0], operands[1],
15579 operands[2], operands[3],
15580 operands[4], operands[5]))
15586 ;; Most CPUs don't like single string operations
15587 ;; Handle this case here to simplify previous expander.
15589 (define_expand "strset"
15590 [(set (match_operand 1 "memory_operand" "")
15591 (match_operand 2 "register_operand" ""))
15592 (parallel [(set (match_operand 0 "register_operand" "")
15594 (clobber (reg:CC FLAGS_REG))])]
15597 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15598 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15600 /* If .md ever supports :P for Pmode, this can be directly
15601 in the pattern above. */
15602 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15603 GEN_INT (GET_MODE_SIZE (GET_MODE
15605 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15607 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15613 (define_expand "strset_singleop"
15614 [(parallel [(set (match_operand 1 "memory_operand" "")
15615 (match_operand 2 "register_operand" ""))
15616 (set (match_operand 0 "register_operand" "")
15617 (match_operand 3 "" ""))])]
15619 "ix86_current_function_needs_cld = 1;")
15621 (define_insn "*strsetdi_rex_1"
15622 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15623 (match_operand:DI 2 "register_operand" "a"))
15624 (set (match_operand:DI 0 "register_operand" "=D")
15625 (plus:DI (match_dup 1)
15629 [(set_attr "type" "str")
15630 (set_attr "memory" "store")
15631 (set_attr "mode" "DI")])
15633 (define_insn "*strsetsi_1"
15634 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15635 (match_operand:SI 2 "register_operand" "a"))
15636 (set (match_operand:P 0 "register_operand" "=D")
15637 (plus:P (match_dup 1)
15641 [(set_attr "type" "str")
15642 (set_attr "memory" "store")
15643 (set_attr "mode" "SI")])
15645 (define_insn "*strsethi_1"
15646 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15647 (match_operand:HI 2 "register_operand" "a"))
15648 (set (match_operand:P 0 "register_operand" "=D")
15649 (plus:P (match_dup 1)
15653 [(set_attr "type" "str")
15654 (set_attr "memory" "store")
15655 (set_attr "mode" "HI")])
15657 (define_insn "*strsetqi_1"
15658 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15659 (match_operand:QI 2 "register_operand" "a"))
15660 (set (match_operand:P 0 "register_operand" "=D")
15661 (plus:P (match_dup 1)
15665 [(set_attr "type" "str")
15666 (set_attr "memory" "store")
15667 (set (attr "prefix_rex")
15669 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15671 (const_string "*")))
15672 (set_attr "mode" "QI")])
15674 (define_expand "rep_stos"
15675 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15676 (set (match_operand 0 "register_operand" "")
15677 (match_operand 4 "" ""))
15678 (set (match_operand 2 "memory_operand" "") (const_int 0))
15679 (use (match_operand 3 "register_operand" ""))
15680 (use (match_dup 1))])]
15682 "ix86_current_function_needs_cld = 1;")
15684 (define_insn "*rep_stosdi_rex64"
15685 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15686 (set (match_operand:DI 0 "register_operand" "=D")
15687 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15689 (match_operand:DI 3 "register_operand" "0")))
15690 (set (mem:BLK (match_dup 3))
15692 (use (match_operand:DI 2 "register_operand" "a"))
15693 (use (match_dup 4))]
15696 [(set_attr "type" "str")
15697 (set_attr "prefix_rep" "1")
15698 (set_attr "memory" "store")
15699 (set_attr "mode" "DI")])
15701 (define_insn "*rep_stossi"
15702 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15703 (set (match_operand:P 0 "register_operand" "=D")
15704 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15706 (match_operand:P 3 "register_operand" "0")))
15707 (set (mem:BLK (match_dup 3))
15709 (use (match_operand:SI 2 "register_operand" "a"))
15710 (use (match_dup 4))]
15712 "rep{%;} stos{l|d}"
15713 [(set_attr "type" "str")
15714 (set_attr "prefix_rep" "1")
15715 (set_attr "memory" "store")
15716 (set_attr "mode" "SI")])
15718 (define_insn "*rep_stosqi"
15719 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_operand:P 3 "register_operand" "0")
15722 (match_operand:P 4 "register_operand" "1")))
15723 (set (mem:BLK (match_dup 3))
15725 (use (match_operand:QI 2 "register_operand" "a"))
15726 (use (match_dup 4))]
15729 [(set_attr "type" "str")
15730 (set_attr "prefix_rep" "1")
15731 (set_attr "memory" "store")
15732 (set (attr "prefix_rex")
15734 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15736 (const_string "*")))
15737 (set_attr "mode" "QI")])
15739 (define_expand "cmpstrnsi"
15740 [(set (match_operand:SI 0 "register_operand" "")
15741 (compare:SI (match_operand:BLK 1 "general_operand" "")
15742 (match_operand:BLK 2 "general_operand" "")))
15743 (use (match_operand 3 "general_operand" ""))
15744 (use (match_operand 4 "immediate_operand" ""))]
15747 rtx addr1, addr2, out, outlow, count, countreg, align;
15749 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15752 /* Can't use this if the user has appropriated esi or edi. */
15753 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15758 out = gen_reg_rtx (SImode);
15760 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15761 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15762 if (addr1 != XEXP (operands[1], 0))
15763 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15764 if (addr2 != XEXP (operands[2], 0))
15765 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15767 count = operands[3];
15768 countreg = ix86_zero_extend_to_Pmode (count);
15770 /* %%% Iff we are testing strict equality, we can use known alignment
15771 to good advantage. This may be possible with combine, particularly
15772 once cc0 is dead. */
15773 align = operands[4];
15775 if (CONST_INT_P (count))
15777 if (INTVAL (count) == 0)
15779 emit_move_insn (operands[0], const0_rtx);
15782 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15783 operands[1], operands[2]));
15787 rtx (*gen_cmp) (rtx, rtx);
15789 gen_cmp = (TARGET_64BIT
15790 ? gen_cmpdi_1 : gen_cmpsi_1);
15792 emit_insn (gen_cmp (countreg, countreg));
15793 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15794 operands[1], operands[2]));
15797 outlow = gen_lowpart (QImode, out);
15798 emit_insn (gen_cmpintqi (outlow));
15799 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15801 if (operands[0] != out)
15802 emit_move_insn (operands[0], out);
15807 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15809 (define_expand "cmpintqi"
15810 [(set (match_dup 1)
15811 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15813 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15814 (parallel [(set (match_operand:QI 0 "register_operand" "")
15815 (minus:QI (match_dup 1)
15817 (clobber (reg:CC FLAGS_REG))])]
15820 operands[1] = gen_reg_rtx (QImode);
15821 operands[2] = gen_reg_rtx (QImode);
15824 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15825 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15827 (define_expand "cmpstrnqi_nz_1"
15828 [(parallel [(set (reg:CC FLAGS_REG)
15829 (compare:CC (match_operand 4 "memory_operand" "")
15830 (match_operand 5 "memory_operand" "")))
15831 (use (match_operand 2 "register_operand" ""))
15832 (use (match_operand:SI 3 "immediate_operand" ""))
15833 (clobber (match_operand 0 "register_operand" ""))
15834 (clobber (match_operand 1 "register_operand" ""))
15835 (clobber (match_dup 2))])]
15837 "ix86_current_function_needs_cld = 1;")
15839 (define_insn "*cmpstrnqi_nz_1"
15840 [(set (reg:CC FLAGS_REG)
15841 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15842 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15843 (use (match_operand:P 6 "register_operand" "2"))
15844 (use (match_operand:SI 3 "immediate_operand" "i"))
15845 (clobber (match_operand:P 0 "register_operand" "=S"))
15846 (clobber (match_operand:P 1 "register_operand" "=D"))
15847 (clobber (match_operand:P 2 "register_operand" "=c"))]
15850 [(set_attr "type" "str")
15851 (set_attr "mode" "QI")
15852 (set (attr "prefix_rex")
15854 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15856 (const_string "*")))
15857 (set_attr "prefix_rep" "1")])
15859 ;; The same, but the count is not known to not be zero.
15861 (define_expand "cmpstrnqi_1"
15862 [(parallel [(set (reg:CC FLAGS_REG)
15863 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15865 (compare:CC (match_operand 4 "memory_operand" "")
15866 (match_operand 5 "memory_operand" ""))
15868 (use (match_operand:SI 3 "immediate_operand" ""))
15869 (use (reg:CC FLAGS_REG))
15870 (clobber (match_operand 0 "register_operand" ""))
15871 (clobber (match_operand 1 "register_operand" ""))
15872 (clobber (match_dup 2))])]
15874 "ix86_current_function_needs_cld = 1;")
15876 (define_insn "*cmpstrnqi_1"
15877 [(set (reg:CC FLAGS_REG)
15878 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15880 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15881 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15883 (use (match_operand:SI 3 "immediate_operand" "i"))
15884 (use (reg:CC FLAGS_REG))
15885 (clobber (match_operand:P 0 "register_operand" "=S"))
15886 (clobber (match_operand:P 1 "register_operand" "=D"))
15887 (clobber (match_operand:P 2 "register_operand" "=c"))]
15890 [(set_attr "type" "str")
15891 (set_attr "mode" "QI")
15892 (set (attr "prefix_rex")
15894 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15896 (const_string "*")))
15897 (set_attr "prefix_rep" "1")])
15899 (define_expand "strlen<mode>"
15900 [(set (match_operand:SWI48x 0 "register_operand" "")
15901 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15902 (match_operand:QI 2 "immediate_operand" "")
15903 (match_operand 3 "immediate_operand" "")]
15907 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15913 (define_expand "strlenqi_1"
15914 [(parallel [(set (match_operand 0 "register_operand" "")
15915 (match_operand 2 "" ""))
15916 (clobber (match_operand 1 "register_operand" ""))
15917 (clobber (reg:CC FLAGS_REG))])]
15919 "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*strlenqi_1"
15922 [(set (match_operand:P 0 "register_operand" "=&c")
15923 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15924 (match_operand:QI 2 "register_operand" "a")
15925 (match_operand:P 3 "immediate_operand" "i")
15926 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15927 (clobber (match_operand:P 1 "register_operand" "=D"))
15928 (clobber (reg:CC FLAGS_REG))]
15931 [(set_attr "type" "str")
15932 (set_attr "mode" "QI")
15933 (set (attr "prefix_rex")
15935 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15937 (const_string "*")))
15938 (set_attr "prefix_rep" "1")])
15940 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15941 ;; handled in combine, but it is not currently up to the task.
15942 ;; When used for their truth value, the cmpstrn* expanders generate
15951 ;; The intermediate three instructions are unnecessary.
15953 ;; This one handles cmpstrn*_nz_1...
15956 (set (reg:CC FLAGS_REG)
15957 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15958 (mem:BLK (match_operand 5 "register_operand" ""))))
15959 (use (match_operand 6 "register_operand" ""))
15960 (use (match_operand:SI 3 "immediate_operand" ""))
15961 (clobber (match_operand 0 "register_operand" ""))
15962 (clobber (match_operand 1 "register_operand" ""))
15963 (clobber (match_operand 2 "register_operand" ""))])
15964 (set (match_operand:QI 7 "register_operand" "")
15965 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15966 (set (match_operand:QI 8 "register_operand" "")
15967 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15968 (set (reg FLAGS_REG)
15969 (compare (match_dup 7) (match_dup 8)))
15971 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15973 (set (reg:CC FLAGS_REG)
15974 (compare:CC (mem:BLK (match_dup 4))
15975 (mem:BLK (match_dup 5))))
15976 (use (match_dup 6))
15977 (use (match_dup 3))
15978 (clobber (match_dup 0))
15979 (clobber (match_dup 1))
15980 (clobber (match_dup 2))])])
15982 ;; ...and this one handles cmpstrn*_1.
15985 (set (reg:CC FLAGS_REG)
15986 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15988 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15989 (mem:BLK (match_operand 5 "register_operand" "")))
15991 (use (match_operand:SI 3 "immediate_operand" ""))
15992 (use (reg:CC FLAGS_REG))
15993 (clobber (match_operand 0 "register_operand" ""))
15994 (clobber (match_operand 1 "register_operand" ""))
15995 (clobber (match_operand 2 "register_operand" ""))])
15996 (set (match_operand:QI 7 "register_operand" "")
15997 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15998 (set (match_operand:QI 8 "register_operand" "")
15999 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16000 (set (reg FLAGS_REG)
16001 (compare (match_dup 7) (match_dup 8)))
16003 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16005 (set (reg:CC FLAGS_REG)
16006 (if_then_else:CC (ne (match_dup 6)
16008 (compare:CC (mem:BLK (match_dup 4))
16009 (mem:BLK (match_dup 5)))
16011 (use (match_dup 3))
16012 (use (reg:CC FLAGS_REG))
16013 (clobber (match_dup 0))
16014 (clobber (match_dup 1))
16015 (clobber (match_dup 2))])])
16017 ;; Conditional move instructions.
16019 (define_expand "mov<mode>cc"
16020 [(set (match_operand:SWIM 0 "register_operand" "")
16021 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16022 (match_operand:SWIM 2 "general_operand" "")
16023 (match_operand:SWIM 3 "general_operand" "")))]
16025 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16027 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16028 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16029 ;; So just document what we're doing explicitly.
16031 (define_expand "x86_mov<mode>cc_0_m1"
16033 [(set (match_operand:SWI48 0 "register_operand" "")
16034 (if_then_else:SWI48
16035 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16036 [(match_operand 1 "flags_reg_operand" "")
16040 (clobber (reg:CC FLAGS_REG))])])
16042 (define_insn "*x86_mov<mode>cc_0_m1"
16043 [(set (match_operand:SWI48 0 "register_operand" "=r")
16044 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16048 (clobber (reg:CC FLAGS_REG))]
16050 "sbb{<imodesuffix>}\t%0, %0"
16051 ; Since we don't have the proper number of operands for an alu insn,
16052 ; fill in all the blanks.
16053 [(set_attr "type" "alu")
16054 (set_attr "use_carry" "1")
16055 (set_attr "pent_pair" "pu")
16056 (set_attr "memory" "none")
16057 (set_attr "imm_disp" "false")
16058 (set_attr "mode" "<MODE>")
16059 (set_attr "length_immediate" "0")])
16061 (define_insn "*x86_mov<mode>cc_0_m1_se"
16062 [(set (match_operand:SWI48 0 "register_operand" "=r")
16063 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16064 [(reg FLAGS_REG) (const_int 0)])
16067 (clobber (reg:CC FLAGS_REG))]
16069 "sbb{<imodesuffix>}\t%0, %0"
16070 [(set_attr "type" "alu")
16071 (set_attr "use_carry" "1")
16072 (set_attr "pent_pair" "pu")
16073 (set_attr "memory" "none")
16074 (set_attr "imm_disp" "false")
16075 (set_attr "mode" "<MODE>")
16076 (set_attr "length_immediate" "0")])
16078 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16079 [(set (match_operand:SWI48 0 "register_operand" "=r")
16080 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16081 [(reg FLAGS_REG) (const_int 0)])))]
16083 "sbb{<imodesuffix>}\t%0, %0"
16084 [(set_attr "type" "alu")
16085 (set_attr "use_carry" "1")
16086 (set_attr "pent_pair" "pu")
16087 (set_attr "memory" "none")
16088 (set_attr "imm_disp" "false")
16089 (set_attr "mode" "<MODE>")
16090 (set_attr "length_immediate" "0")])
16092 (define_insn "*mov<mode>cc_noc"
16093 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16094 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16095 [(reg FLAGS_REG) (const_int 0)])
16096 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16097 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16098 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16100 cmov%O2%C1\t{%2, %0|%0, %2}
16101 cmov%O2%c1\t{%3, %0|%0, %3}"
16102 [(set_attr "type" "icmov")
16103 (set_attr "mode" "<MODE>")])
16105 (define_insn_and_split "*movqicc_noc"
16106 [(set (match_operand:QI 0 "register_operand" "=r,r")
16107 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16108 [(match_operand 4 "flags_reg_operand" "")
16110 (match_operand:QI 2 "register_operand" "r,0")
16111 (match_operand:QI 3 "register_operand" "0,r")))]
16112 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16114 "&& reload_completed"
16115 [(set (match_dup 0)
16116 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16119 "operands[0] = gen_lowpart (SImode, operands[0]);
16120 operands[2] = gen_lowpart (SImode, operands[2]);
16121 operands[3] = gen_lowpart (SImode, operands[3]);"
16122 [(set_attr "type" "icmov")
16123 (set_attr "mode" "SI")])
16125 (define_expand "mov<mode>cc"
16126 [(set (match_operand:X87MODEF 0 "register_operand" "")
16127 (if_then_else:X87MODEF
16128 (match_operand 1 "ix86_fp_comparison_operator" "")
16129 (match_operand:X87MODEF 2 "register_operand" "")
16130 (match_operand:X87MODEF 3 "register_operand" "")))]
16131 "(TARGET_80387 && TARGET_CMOVE)
16132 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16133 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16135 (define_insn "*movxfcc_1"
16136 [(set (match_operand:XF 0 "register_operand" "=f,f")
16137 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16138 [(reg FLAGS_REG) (const_int 0)])
16139 (match_operand:XF 2 "register_operand" "f,0")
16140 (match_operand:XF 3 "register_operand" "0,f")))]
16141 "TARGET_80387 && TARGET_CMOVE"
16143 fcmov%F1\t{%2, %0|%0, %2}
16144 fcmov%f1\t{%3, %0|%0, %3}"
16145 [(set_attr "type" "fcmov")
16146 (set_attr "mode" "XF")])
16148 (define_insn "*movdfcc_1_rex64"
16149 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16150 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16151 [(reg FLAGS_REG) (const_int 0)])
16152 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16153 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16154 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16155 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16157 fcmov%F1\t{%2, %0|%0, %2}
16158 fcmov%f1\t{%3, %0|%0, %3}
16159 cmov%O2%C1\t{%2, %0|%0, %2}
16160 cmov%O2%c1\t{%3, %0|%0, %3}"
16161 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16162 (set_attr "mode" "DF,DF,DI,DI")])
16164 (define_insn "*movdfcc_1"
16165 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16166 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16167 [(reg FLAGS_REG) (const_int 0)])
16168 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16169 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16170 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16171 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16173 fcmov%F1\t{%2, %0|%0, %2}
16174 fcmov%f1\t{%3, %0|%0, %3}
16177 [(set_attr "type" "fcmov,fcmov,multi,multi")
16178 (set_attr "mode" "DF,DF,DI,DI")])
16181 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16182 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16183 [(match_operand 4 "flags_reg_operand" "")
16185 (match_operand:DF 2 "nonimmediate_operand" "")
16186 (match_operand:DF 3 "nonimmediate_operand" "")))]
16187 "!TARGET_64BIT && reload_completed"
16188 [(set (match_dup 2)
16189 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16193 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16197 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16198 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16201 (define_insn "*movsfcc_1_387"
16202 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16203 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16204 [(reg FLAGS_REG) (const_int 0)])
16205 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16206 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16207 "TARGET_80387 && TARGET_CMOVE
16208 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16210 fcmov%F1\t{%2, %0|%0, %2}
16211 fcmov%f1\t{%3, %0|%0, %3}
16212 cmov%O2%C1\t{%2, %0|%0, %2}
16213 cmov%O2%c1\t{%3, %0|%0, %3}"
16214 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16215 (set_attr "mode" "SF,SF,SI,SI")])
16217 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16218 ;; the scalar versions to have only XMM registers as operands.
16220 ;; XOP conditional move
16221 (define_insn "*xop_pcmov_<mode>"
16222 [(set (match_operand:MODEF 0 "register_operand" "=x")
16223 (if_then_else:MODEF
16224 (match_operand:MODEF 1 "register_operand" "x")
16225 (match_operand:MODEF 2 "register_operand" "x")
16226 (match_operand:MODEF 3 "register_operand" "x")))]
16228 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16229 [(set_attr "type" "sse4arg")])
16231 ;; These versions of the min/max patterns are intentionally ignorant of
16232 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16233 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16234 ;; are undefined in this condition, we're certain this is correct.
16236 (define_insn "<code><mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16239 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16241 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16244 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16245 [(set_attr "isa" "noavx,avx")
16246 (set_attr "prefix" "orig,vex")
16247 (set_attr "type" "sseadd")
16248 (set_attr "mode" "<MODE>")])
16250 ;; These versions of the min/max patterns implement exactly the operations
16251 ;; min = (op1 < op2 ? op1 : op2)
16252 ;; max = (!(op1 < op2) ? op1 : op2)
16253 ;; Their operands are not commutative, and thus they may be used in the
16254 ;; presence of -0.0 and NaN.
16256 (define_insn "*ieee_smin<mode>3"
16257 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16259 [(match_operand:MODEF 1 "register_operand" "0,x")
16260 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16262 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16264 min<ssemodesuffix>\t{%2, %0|%0, %2}
16265 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16266 [(set_attr "isa" "noavx,avx")
16267 (set_attr "prefix" "orig,vex")
16268 (set_attr "type" "sseadd")
16269 (set_attr "mode" "<MODE>")])
16271 (define_insn "*ieee_smax<mode>3"
16272 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16274 [(match_operand:MODEF 1 "register_operand" "0,x")
16275 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16279 max<ssemodesuffix>\t{%2, %0|%0, %2}
16280 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16281 [(set_attr "isa" "noavx,avx")
16282 (set_attr "prefix" "orig,vex")
16283 (set_attr "type" "sseadd")
16284 (set_attr "mode" "<MODE>")])
16286 ;; Make two stack loads independent:
16288 ;; fld %st(0) -> fld bb
16289 ;; fmul bb fmul %st(1), %st
16291 ;; Actually we only match the last two instructions for simplicity.
16293 [(set (match_operand 0 "fp_register_operand" "")
16294 (match_operand 1 "fp_register_operand" ""))
16296 (match_operator 2 "binary_fp_operator"
16298 (match_operand 3 "memory_operand" "")]))]
16299 "REGNO (operands[0]) != REGNO (operands[1])"
16300 [(set (match_dup 0) (match_dup 3))
16301 (set (match_dup 0) (match_dup 4))]
16303 ;; The % modifier is not operational anymore in peephole2's, so we have to
16304 ;; swap the operands manually in the case of addition and multiplication.
16305 "if (COMMUTATIVE_ARITH_P (operands[2]))
16306 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16307 GET_MODE (operands[2]),
16308 operands[0], operands[1]);
16310 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16311 GET_MODE (operands[2]),
16312 operands[1], operands[0]);")
16314 ;; Conditional addition patterns
16315 (define_expand "add<mode>cc"
16316 [(match_operand:SWI 0 "register_operand" "")
16317 (match_operand 1 "ordered_comparison_operator" "")
16318 (match_operand:SWI 2 "register_operand" "")
16319 (match_operand:SWI 3 "const_int_operand" "")]
16321 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16323 ;; Misc patterns (?)
16325 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16326 ;; Otherwise there will be nothing to keep
16328 ;; [(set (reg ebp) (reg esp))]
16329 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16330 ;; (clobber (eflags)]
16331 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16333 ;; in proper program order.
16335 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16336 [(set (match_operand:P 0 "register_operand" "=r,r")
16337 (plus:P (match_operand:P 1 "register_operand" "0,r")
16338 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16339 (clobber (reg:CC FLAGS_REG))
16340 (clobber (mem:BLK (scratch)))]
16343 switch (get_attr_type (insn))
16346 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16350 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16351 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16353 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16356 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16357 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16360 [(set (attr "type")
16361 (cond [(and (eq_attr "alternative" "0")
16362 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16363 (const_string "alu")
16364 (match_operand:<MODE> 2 "const0_operand" "")
16365 (const_string "imov")
16367 (const_string "lea")))
16368 (set (attr "length_immediate")
16369 (cond [(eq_attr "type" "imov")
16371 (and (eq_attr "type" "alu")
16372 (match_operand 2 "const128_operand" ""))
16375 (const_string "*")))
16376 (set_attr "mode" "<MODE>")])
16378 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16379 [(set (match_operand:P 0 "register_operand" "=r")
16380 (minus:P (match_operand:P 1 "register_operand" "0")
16381 (match_operand:P 2 "register_operand" "r")))
16382 (clobber (reg:CC FLAGS_REG))
16383 (clobber (mem:BLK (scratch)))]
16385 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16386 [(set_attr "type" "alu")
16387 (set_attr "mode" "<MODE>")])
16389 (define_insn "allocate_stack_worker_probe_<mode>"
16390 [(set (match_operand:P 0 "register_operand" "=a")
16391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16392 UNSPECV_STACK_PROBE))
16393 (clobber (reg:CC FLAGS_REG))]
16394 "ix86_target_stack_probe ()"
16395 "call\t___chkstk_ms"
16396 [(set_attr "type" "multi")
16397 (set_attr "length" "5")])
16399 (define_expand "allocate_stack"
16400 [(match_operand 0 "register_operand" "")
16401 (match_operand 1 "general_operand" "")]
16402 "ix86_target_stack_probe ()"
16406 #ifndef CHECK_STACK_LIMIT
16407 #define CHECK_STACK_LIMIT 0
16410 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16411 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16413 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16414 stack_pointer_rtx, 0, OPTAB_DIRECT);
16415 if (x != stack_pointer_rtx)
16416 emit_move_insn (stack_pointer_rtx, x);
16420 x = copy_to_mode_reg (Pmode, operands[1]);
16422 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16424 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16425 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16426 stack_pointer_rtx, 0, OPTAB_DIRECT);
16427 if (x != stack_pointer_rtx)
16428 emit_move_insn (stack_pointer_rtx, x);
16431 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16435 ;; Use IOR for stack probes, this is shorter.
16436 (define_expand "probe_stack"
16437 [(match_operand 0 "memory_operand" "")]
16440 rtx (*gen_ior3) (rtx, rtx, rtx);
16442 gen_ior3 = (GET_MODE (operands[0]) == DImode
16443 ? gen_iordi3 : gen_iorsi3);
16445 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16449 (define_insn "adjust_stack_and_probe<mode>"
16450 [(set (match_operand:P 0 "register_operand" "=r")
16451 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16452 UNSPECV_PROBE_STACK_RANGE))
16453 (set (reg:P SP_REG)
16454 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16455 (clobber (reg:CC FLAGS_REG))
16456 (clobber (mem:BLK (scratch)))]
16458 "* return output_adjust_stack_and_probe (operands[0]);"
16459 [(set_attr "type" "multi")])
16461 (define_insn "probe_stack_range<mode>"
16462 [(set (match_operand:P 0 "register_operand" "=r")
16463 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16464 (match_operand:P 2 "const_int_operand" "n")]
16465 UNSPECV_PROBE_STACK_RANGE))
16466 (clobber (reg:CC FLAGS_REG))]
16468 "* return output_probe_stack_range (operands[0], operands[2]);"
16469 [(set_attr "type" "multi")])
16471 (define_expand "builtin_setjmp_receiver"
16472 [(label_ref (match_operand 0 "" ""))]
16473 "!TARGET_64BIT && flag_pic"
16479 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16480 rtx label_rtx = gen_label_rtx ();
16481 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16482 xops[0] = xops[1] = picreg;
16483 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16484 ix86_expand_binary_operator (MINUS, SImode, xops);
16488 emit_insn (gen_set_got (pic_offset_table_rtx));
16492 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16495 [(set (match_operand 0 "register_operand" "")
16496 (match_operator 3 "promotable_binary_operator"
16497 [(match_operand 1 "register_operand" "")
16498 (match_operand 2 "aligned_operand" "")]))
16499 (clobber (reg:CC FLAGS_REG))]
16500 "! TARGET_PARTIAL_REG_STALL && reload_completed
16501 && ((GET_MODE (operands[0]) == HImode
16502 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16503 /* ??? next two lines just !satisfies_constraint_K (...) */
16504 || !CONST_INT_P (operands[2])
16505 || satisfies_constraint_K (operands[2])))
16506 || (GET_MODE (operands[0]) == QImode
16507 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16508 [(parallel [(set (match_dup 0)
16509 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16510 (clobber (reg:CC FLAGS_REG))])]
16511 "operands[0] = gen_lowpart (SImode, operands[0]);
16512 operands[1] = gen_lowpart (SImode, operands[1]);
16513 if (GET_CODE (operands[3]) != ASHIFT)
16514 operands[2] = gen_lowpart (SImode, operands[2]);
16515 PUT_MODE (operands[3], SImode);")
16517 ; Promote the QImode tests, as i386 has encoding of the AND
16518 ; instruction with 32-bit sign-extended immediate and thus the
16519 ; instruction size is unchanged, except in the %eax case for
16520 ; which it is increased by one byte, hence the ! optimize_size.
16522 [(set (match_operand 0 "flags_reg_operand" "")
16523 (match_operator 2 "compare_operator"
16524 [(and (match_operand 3 "aligned_operand" "")
16525 (match_operand 4 "const_int_operand" ""))
16527 (set (match_operand 1 "register_operand" "")
16528 (and (match_dup 3) (match_dup 4)))]
16529 "! TARGET_PARTIAL_REG_STALL && reload_completed
16530 && optimize_insn_for_speed_p ()
16531 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16532 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16533 /* Ensure that the operand will remain sign-extended immediate. */
16534 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16535 [(parallel [(set (match_dup 0)
16536 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16539 (and:SI (match_dup 3) (match_dup 4)))])]
16542 = gen_int_mode (INTVAL (operands[4])
16543 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16544 operands[1] = gen_lowpart (SImode, operands[1]);
16545 operands[3] = gen_lowpart (SImode, operands[3]);
16548 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16549 ; the TEST instruction with 32-bit sign-extended immediate and thus
16550 ; the instruction size would at least double, which is not what we
16551 ; want even with ! optimize_size.
16553 [(set (match_operand 0 "flags_reg_operand" "")
16554 (match_operator 1 "compare_operator"
16555 [(and (match_operand:HI 2 "aligned_operand" "")
16556 (match_operand:HI 3 "const_int_operand" ""))
16558 "! TARGET_PARTIAL_REG_STALL && reload_completed
16559 && ! TARGET_FAST_PREFIX
16560 && optimize_insn_for_speed_p ()
16561 /* Ensure that the operand will remain sign-extended immediate. */
16562 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16563 [(set (match_dup 0)
16564 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16568 = gen_int_mode (INTVAL (operands[3])
16569 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16570 operands[2] = gen_lowpart (SImode, operands[2]);
16574 [(set (match_operand 0 "register_operand" "")
16575 (neg (match_operand 1 "register_operand" "")))
16576 (clobber (reg:CC FLAGS_REG))]
16577 "! TARGET_PARTIAL_REG_STALL && reload_completed
16578 && (GET_MODE (operands[0]) == HImode
16579 || (GET_MODE (operands[0]) == QImode
16580 && (TARGET_PROMOTE_QImode
16581 || optimize_insn_for_size_p ())))"
16582 [(parallel [(set (match_dup 0)
16583 (neg:SI (match_dup 1)))
16584 (clobber (reg:CC FLAGS_REG))])]
16585 "operands[0] = gen_lowpart (SImode, operands[0]);
16586 operands[1] = gen_lowpart (SImode, operands[1]);")
16589 [(set (match_operand 0 "register_operand" "")
16590 (not (match_operand 1 "register_operand" "")))]
16591 "! TARGET_PARTIAL_REG_STALL && reload_completed
16592 && (GET_MODE (operands[0]) == HImode
16593 || (GET_MODE (operands[0]) == QImode
16594 && (TARGET_PROMOTE_QImode
16595 || optimize_insn_for_size_p ())))"
16596 [(set (match_dup 0)
16597 (not:SI (match_dup 1)))]
16598 "operands[0] = gen_lowpart (SImode, operands[0]);
16599 operands[1] = gen_lowpart (SImode, operands[1]);")
16602 [(set (match_operand 0 "register_operand" "")
16603 (if_then_else (match_operator 1 "ordered_comparison_operator"
16604 [(reg FLAGS_REG) (const_int 0)])
16605 (match_operand 2 "register_operand" "")
16606 (match_operand 3 "register_operand" "")))]
16607 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16608 && (GET_MODE (operands[0]) == HImode
16609 || (GET_MODE (operands[0]) == QImode
16610 && (TARGET_PROMOTE_QImode
16611 || optimize_insn_for_size_p ())))"
16612 [(set (match_dup 0)
16613 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16614 "operands[0] = gen_lowpart (SImode, operands[0]);
16615 operands[2] = gen_lowpart (SImode, operands[2]);
16616 operands[3] = gen_lowpart (SImode, operands[3]);")
16618 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16619 ;; transform a complex memory operation into two memory to register operations.
16621 ;; Don't push memory operands
16623 [(set (match_operand:SWI 0 "push_operand" "")
16624 (match_operand:SWI 1 "memory_operand" ""))
16625 (match_scratch:SWI 2 "<r>")]
16626 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16627 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16628 [(set (match_dup 2) (match_dup 1))
16629 (set (match_dup 0) (match_dup 2))])
16631 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16634 [(set (match_operand:SF 0 "push_operand" "")
16635 (match_operand:SF 1 "memory_operand" ""))
16636 (match_scratch:SF 2 "r")]
16637 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16638 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16639 [(set (match_dup 2) (match_dup 1))
16640 (set (match_dup 0) (match_dup 2))])
16642 ;; Don't move an immediate directly to memory when the instruction
16645 [(match_scratch:SWI124 1 "<r>")
16646 (set (match_operand:SWI124 0 "memory_operand" "")
16648 "optimize_insn_for_speed_p ()
16649 && !TARGET_USE_MOV0
16650 && TARGET_SPLIT_LONG_MOVES
16651 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16652 && peep2_regno_dead_p (0, FLAGS_REG)"
16653 [(parallel [(set (match_dup 2) (const_int 0))
16654 (clobber (reg:CC FLAGS_REG))])
16655 (set (match_dup 0) (match_dup 1))]
16656 "operands[2] = gen_lowpart (SImode, operands[1]);")
16659 [(match_scratch:SWI124 2 "<r>")
16660 (set (match_operand:SWI124 0 "memory_operand" "")
16661 (match_operand:SWI124 1 "immediate_operand" ""))]
16662 "optimize_insn_for_speed_p ()
16663 && TARGET_SPLIT_LONG_MOVES
16664 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16665 [(set (match_dup 2) (match_dup 1))
16666 (set (match_dup 0) (match_dup 2))])
16668 ;; Don't compare memory with zero, load and use a test instead.
16670 [(set (match_operand 0 "flags_reg_operand" "")
16671 (match_operator 1 "compare_operator"
16672 [(match_operand:SI 2 "memory_operand" "")
16674 (match_scratch:SI 3 "r")]
16675 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16676 [(set (match_dup 3) (match_dup 2))
16677 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16679 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16680 ;; Don't split NOTs with a displacement operand, because resulting XOR
16681 ;; will not be pairable anyway.
16683 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16684 ;; represented using a modRM byte. The XOR replacement is long decoded,
16685 ;; so this split helps here as well.
16687 ;; Note: Can't do this as a regular split because we can't get proper
16688 ;; lifetime information then.
16691 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16692 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16693 "optimize_insn_for_speed_p ()
16694 && ((TARGET_NOT_UNPAIRABLE
16695 && (!MEM_P (operands[0])
16696 || !memory_displacement_operand (operands[0], <MODE>mode)))
16697 || (TARGET_NOT_VECTORMODE
16698 && long_memory_operand (operands[0], <MODE>mode)))
16699 && peep2_regno_dead_p (0, FLAGS_REG)"
16700 [(parallel [(set (match_dup 0)
16701 (xor:SWI124 (match_dup 1) (const_int -1)))
16702 (clobber (reg:CC FLAGS_REG))])])
16704 ;; Non pairable "test imm, reg" instructions can be translated to
16705 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16706 ;; byte opcode instead of two, have a short form for byte operands),
16707 ;; so do it for other CPUs as well. Given that the value was dead,
16708 ;; this should not create any new dependencies. Pass on the sub-word
16709 ;; versions if we're concerned about partial register stalls.
16712 [(set (match_operand 0 "flags_reg_operand" "")
16713 (match_operator 1 "compare_operator"
16714 [(and:SI (match_operand:SI 2 "register_operand" "")
16715 (match_operand:SI 3 "immediate_operand" ""))
16717 "ix86_match_ccmode (insn, CCNOmode)
16718 && (true_regnum (operands[2]) != AX_REG
16719 || satisfies_constraint_K (operands[3]))
16720 && peep2_reg_dead_p (1, operands[2])"
16722 [(set (match_dup 0)
16723 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16726 (and:SI (match_dup 2) (match_dup 3)))])])
16728 ;; We don't need to handle HImode case, because it will be promoted to SImode
16729 ;; on ! TARGET_PARTIAL_REG_STALL
16732 [(set (match_operand 0 "flags_reg_operand" "")
16733 (match_operator 1 "compare_operator"
16734 [(and:QI (match_operand:QI 2 "register_operand" "")
16735 (match_operand:QI 3 "immediate_operand" ""))
16737 "! TARGET_PARTIAL_REG_STALL
16738 && ix86_match_ccmode (insn, CCNOmode)
16739 && true_regnum (operands[2]) != AX_REG
16740 && peep2_reg_dead_p (1, operands[2])"
16742 [(set (match_dup 0)
16743 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16746 (and:QI (match_dup 2) (match_dup 3)))])])
16749 [(set (match_operand 0 "flags_reg_operand" "")
16750 (match_operator 1 "compare_operator"
16753 (match_operand 2 "ext_register_operand" "")
16756 (match_operand 3 "const_int_operand" ""))
16758 "! TARGET_PARTIAL_REG_STALL
16759 && ix86_match_ccmode (insn, CCNOmode)
16760 && true_regnum (operands[2]) != AX_REG
16761 && peep2_reg_dead_p (1, operands[2])"
16762 [(parallel [(set (match_dup 0)
16771 (set (zero_extract:SI (match_dup 2)
16779 (match_dup 3)))])])
16781 ;; Don't do logical operations with memory inputs.
16783 [(match_scratch:SI 2 "r")
16784 (parallel [(set (match_operand:SI 0 "register_operand" "")
16785 (match_operator:SI 3 "arith_or_logical_operator"
16787 (match_operand:SI 1 "memory_operand" "")]))
16788 (clobber (reg:CC FLAGS_REG))])]
16789 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16790 [(set (match_dup 2) (match_dup 1))
16791 (parallel [(set (match_dup 0)
16792 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16793 (clobber (reg:CC FLAGS_REG))])])
16796 [(match_scratch:SI 2 "r")
16797 (parallel [(set (match_operand:SI 0 "register_operand" "")
16798 (match_operator:SI 3 "arith_or_logical_operator"
16799 [(match_operand:SI 1 "memory_operand" "")
16801 (clobber (reg:CC FLAGS_REG))])]
16802 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16803 [(set (match_dup 2) (match_dup 1))
16804 (parallel [(set (match_dup 0)
16805 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16806 (clobber (reg:CC FLAGS_REG))])])
16808 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16809 ;; refers to the destination of the load!
16812 [(set (match_operand:SI 0 "register_operand" "")
16813 (match_operand:SI 1 "register_operand" ""))
16814 (parallel [(set (match_dup 0)
16815 (match_operator:SI 3 "commutative_operator"
16817 (match_operand:SI 2 "memory_operand" "")]))
16818 (clobber (reg:CC FLAGS_REG))])]
16819 "REGNO (operands[0]) != REGNO (operands[1])
16820 && GENERAL_REGNO_P (REGNO (operands[0]))
16821 && GENERAL_REGNO_P (REGNO (operands[1]))"
16822 [(set (match_dup 0) (match_dup 4))
16823 (parallel [(set (match_dup 0)
16824 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16825 (clobber (reg:CC FLAGS_REG))])]
16826 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16829 [(set (match_operand 0 "register_operand" "")
16830 (match_operand 1 "register_operand" ""))
16832 (match_operator 3 "commutative_operator"
16834 (match_operand 2 "memory_operand" "")]))]
16835 "REGNO (operands[0]) != REGNO (operands[1])
16836 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16837 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16838 [(set (match_dup 0) (match_dup 2))
16840 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16842 ; Don't do logical operations with memory outputs
16844 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16845 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16846 ; the same decoder scheduling characteristics as the original.
16849 [(match_scratch:SI 2 "r")
16850 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16851 (match_operator:SI 3 "arith_or_logical_operator"
16853 (match_operand:SI 1 "nonmemory_operand" "")]))
16854 (clobber (reg:CC FLAGS_REG))])]
16855 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16856 /* Do not split stack checking probes. */
16857 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16858 [(set (match_dup 2) (match_dup 0))
16859 (parallel [(set (match_dup 2)
16860 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16861 (clobber (reg:CC FLAGS_REG))])
16862 (set (match_dup 0) (match_dup 2))])
16865 [(match_scratch:SI 2 "r")
16866 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16867 (match_operator:SI 3 "arith_or_logical_operator"
16868 [(match_operand:SI 1 "nonmemory_operand" "")
16870 (clobber (reg:CC FLAGS_REG))])]
16871 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16872 /* Do not split stack checking probes. */
16873 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16874 [(set (match_dup 2) (match_dup 0))
16875 (parallel [(set (match_dup 2)
16876 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16877 (clobber (reg:CC FLAGS_REG))])
16878 (set (match_dup 0) (match_dup 2))])
16880 ;; Attempt to use arith or logical operations with memory outputs with
16881 ;; setting of flags.
16883 [(set (match_operand:SWI 0 "register_operand" "")
16884 (match_operand:SWI 1 "memory_operand" ""))
16885 (parallel [(set (match_dup 0)
16886 (match_operator:SWI 3 "plusminuslogic_operator"
16888 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16889 (clobber (reg:CC FLAGS_REG))])
16890 (set (match_dup 1) (match_dup 0))
16891 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16892 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16893 && peep2_reg_dead_p (4, operands[0])
16894 && !reg_overlap_mentioned_p (operands[0], operands[1])
16895 && ix86_match_ccmode (peep2_next_insn (3),
16896 (GET_CODE (operands[3]) == PLUS
16897 || GET_CODE (operands[3]) == MINUS)
16898 ? CCGOCmode : CCNOmode)"
16899 [(parallel [(set (match_dup 4) (match_dup 5))
16900 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16901 (match_dup 2)]))])]
16902 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16903 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16904 copy_rtx (operands[1]),
16905 copy_rtx (operands[2]));
16906 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16907 operands[5], const0_rtx);")
16910 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16911 (match_operator:SWI 2 "plusminuslogic_operator"
16913 (match_operand:SWI 1 "memory_operand" "")]))
16914 (clobber (reg:CC FLAGS_REG))])
16915 (set (match_dup 1) (match_dup 0))
16916 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16917 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16918 && GET_CODE (operands[2]) != MINUS
16919 && peep2_reg_dead_p (3, operands[0])
16920 && !reg_overlap_mentioned_p (operands[0], operands[1])
16921 && ix86_match_ccmode (peep2_next_insn (2),
16922 GET_CODE (operands[2]) == PLUS
16923 ? CCGOCmode : CCNOmode)"
16924 [(parallel [(set (match_dup 3) (match_dup 4))
16925 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16926 (match_dup 0)]))])]
16927 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16928 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16929 copy_rtx (operands[1]),
16930 copy_rtx (operands[0]));
16931 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16932 operands[4], const0_rtx);")
16935 [(set (match_operand:SWI12 0 "register_operand" "")
16936 (match_operand:SWI12 1 "memory_operand" ""))
16937 (parallel [(set (match_operand:SI 4 "register_operand" "")
16938 (match_operator:SI 3 "plusminuslogic_operator"
16940 (match_operand:SI 2 "nonmemory_operand" "")]))
16941 (clobber (reg:CC FLAGS_REG))])
16942 (set (match_dup 1) (match_dup 0))
16943 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16944 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16945 && REG_P (operands[0]) && REG_P (operands[4])
16946 && REGNO (operands[0]) == REGNO (operands[4])
16947 && peep2_reg_dead_p (4, operands[0])
16948 && !reg_overlap_mentioned_p (operands[0], operands[1])
16949 && ix86_match_ccmode (peep2_next_insn (3),
16950 (GET_CODE (operands[3]) == PLUS
16951 || GET_CODE (operands[3]) == MINUS)
16952 ? CCGOCmode : CCNOmode)"
16953 [(parallel [(set (match_dup 4) (match_dup 5))
16954 (set (match_dup 1) (match_dup 6))])]
16955 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16956 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16957 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16958 copy_rtx (operands[1]), operands[2]);
16959 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16960 operands[5], const0_rtx);
16961 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16962 copy_rtx (operands[1]),
16963 copy_rtx (operands[2]));")
16965 ;; Attempt to always use XOR for zeroing registers.
16967 [(set (match_operand 0 "register_operand" "")
16968 (match_operand 1 "const0_operand" ""))]
16969 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16970 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16971 && GENERAL_REG_P (operands[0])
16972 && peep2_regno_dead_p (0, FLAGS_REG)"
16973 [(parallel [(set (match_dup 0) (const_int 0))
16974 (clobber (reg:CC FLAGS_REG))])]
16975 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16978 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16980 "(GET_MODE (operands[0]) == QImode
16981 || GET_MODE (operands[0]) == HImode)
16982 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16983 && peep2_regno_dead_p (0, FLAGS_REG)"
16984 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16985 (clobber (reg:CC FLAGS_REG))])])
16987 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16989 [(set (match_operand:SWI248 0 "register_operand" "")
16991 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16992 && peep2_regno_dead_p (0, FLAGS_REG)"
16993 [(parallel [(set (match_dup 0) (const_int -1))
16994 (clobber (reg:CC FLAGS_REG))])]
16996 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16997 operands[0] = gen_lowpart (SImode, operands[0]);
17000 ;; Attempt to convert simple lea to add/shift.
17001 ;; These can be created by move expanders.
17004 [(set (match_operand:SWI48 0 "register_operand" "")
17005 (plus:SWI48 (match_dup 0)
17006 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17007 "peep2_regno_dead_p (0, FLAGS_REG)"
17008 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17009 (clobber (reg:CC FLAGS_REG))])])
17012 [(set (match_operand:SI 0 "register_operand" "")
17013 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17014 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17016 && peep2_regno_dead_p (0, FLAGS_REG)
17017 && REGNO (operands[0]) == REGNO (operands[1])"
17018 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17019 (clobber (reg:CC FLAGS_REG))])]
17020 "operands[2] = gen_lowpart (SImode, operands[2]);")
17023 [(set (match_operand:SWI48 0 "register_operand" "")
17024 (mult:SWI48 (match_dup 0)
17025 (match_operand:SWI48 1 "const_int_operand" "")))]
17026 "exact_log2 (INTVAL (operands[1])) >= 0
17027 && peep2_regno_dead_p (0, FLAGS_REG)"
17028 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17029 (clobber (reg:CC FLAGS_REG))])]
17030 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17033 [(set (match_operand:SI 0 "register_operand" "")
17034 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17035 (match_operand:DI 2 "const_int_operand" "")) 0))]
17037 && exact_log2 (INTVAL (operands[2])) >= 0
17038 && REGNO (operands[0]) == REGNO (operands[1])
17039 && peep2_regno_dead_p (0, FLAGS_REG)"
17040 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17041 (clobber (reg:CC FLAGS_REG))])]
17042 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17044 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17045 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17046 ;; On many CPUs it is also faster, since special hardware to avoid esp
17047 ;; dependencies is present.
17049 ;; While some of these conversions may be done using splitters, we use
17050 ;; peepholes in order to allow combine_stack_adjustments pass to see
17051 ;; nonobfuscated RTL.
17053 ;; Convert prologue esp subtractions to push.
17054 ;; We need register to push. In order to keep verify_flow_info happy we have
17056 ;; - use scratch and clobber it in order to avoid dependencies
17057 ;; - use already live register
17058 ;; We can't use the second way right now, since there is no reliable way how to
17059 ;; verify that given register is live. First choice will also most likely in
17060 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17061 ;; call clobbered registers are dead. We may want to use base pointer as an
17062 ;; alternative when no register is available later.
17065 [(match_scratch:P 1 "r")
17066 (parallel [(set (reg:P SP_REG)
17067 (plus:P (reg:P SP_REG)
17068 (match_operand:P 0 "const_int_operand" "")))
17069 (clobber (reg:CC FLAGS_REG))
17070 (clobber (mem:BLK (scratch)))])]
17071 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17072 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17073 [(clobber (match_dup 1))
17074 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17075 (clobber (mem:BLK (scratch)))])])
17078 [(match_scratch:P 1 "r")
17079 (parallel [(set (reg:P SP_REG)
17080 (plus:P (reg:P SP_REG)
17081 (match_operand:P 0 "const_int_operand" "")))
17082 (clobber (reg:CC FLAGS_REG))
17083 (clobber (mem:BLK (scratch)))])]
17084 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17085 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17086 [(clobber (match_dup 1))
17087 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17088 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17089 (clobber (mem:BLK (scratch)))])])
17091 ;; Convert esp subtractions to push.
17093 [(match_scratch:P 1 "r")
17094 (parallel [(set (reg:P SP_REG)
17095 (plus:P (reg:P SP_REG)
17096 (match_operand:P 0 "const_int_operand" "")))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17099 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17100 [(clobber (match_dup 1))
17101 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17104 [(match_scratch:P 1 "r")
17105 (parallel [(set (reg:P SP_REG)
17106 (plus:P (reg:P SP_REG)
17107 (match_operand:P 0 "const_int_operand" "")))
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17110 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17111 [(clobber (match_dup 1))
17112 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17113 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17115 ;; Convert epilogue deallocator to pop.
17117 [(match_scratch:P 1 "r")
17118 (parallel [(set (reg:P SP_REG)
17119 (plus:P (reg:P SP_REG)
17120 (match_operand:P 0 "const_int_operand" "")))
17121 (clobber (reg:CC FLAGS_REG))
17122 (clobber (mem:BLK (scratch)))])]
17123 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17124 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17125 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17126 (clobber (mem:BLK (scratch)))])])
17128 ;; Two pops case is tricky, since pop causes dependency
17129 ;; on destination register. We use two registers if available.
17131 [(match_scratch:P 1 "r")
17132 (match_scratch:P 2 "r")
17133 (parallel [(set (reg:P SP_REG)
17134 (plus:P (reg:P SP_REG)
17135 (match_operand:P 0 "const_int_operand" "")))
17136 (clobber (reg:CC FLAGS_REG))
17137 (clobber (mem:BLK (scratch)))])]
17138 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17139 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17140 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17141 (clobber (mem:BLK (scratch)))])
17142 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17145 [(match_scratch:P 1 "r")
17146 (parallel [(set (reg:P SP_REG)
17147 (plus:P (reg:P SP_REG)
17148 (match_operand:P 0 "const_int_operand" "")))
17149 (clobber (reg:CC FLAGS_REG))
17150 (clobber (mem:BLK (scratch)))])]
17151 "optimize_insn_for_size_p ()
17152 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17153 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17154 (clobber (mem:BLK (scratch)))])
17155 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17157 ;; Convert esp additions to pop.
17159 [(match_scratch:P 1 "r")
17160 (parallel [(set (reg:P SP_REG)
17161 (plus:P (reg:P SP_REG)
17162 (match_operand:P 0 "const_int_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))])]
17164 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17165 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17167 ;; Two pops case is tricky, since pop causes dependency
17168 ;; on destination register. We use two registers if available.
17170 [(match_scratch:P 1 "r")
17171 (match_scratch:P 2 "r")
17172 (parallel [(set (reg:P SP_REG)
17173 (plus:P (reg:P SP_REG)
17174 (match_operand:P 0 "const_int_operand" "")))
17175 (clobber (reg:CC FLAGS_REG))])]
17176 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17177 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17178 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17181 [(match_scratch:P 1 "r")
17182 (parallel [(set (reg:P SP_REG)
17183 (plus:P (reg:P SP_REG)
17184 (match_operand:P 0 "const_int_operand" "")))
17185 (clobber (reg:CC FLAGS_REG))])]
17186 "optimize_insn_for_size_p ()
17187 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17188 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17189 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17191 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17192 ;; required and register dies. Similarly for 128 to -128.
17194 [(set (match_operand 0 "flags_reg_operand" "")
17195 (match_operator 1 "compare_operator"
17196 [(match_operand 2 "register_operand" "")
17197 (match_operand 3 "const_int_operand" "")]))]
17198 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17199 && incdec_operand (operands[3], GET_MODE (operands[3])))
17200 || (!TARGET_FUSE_CMP_AND_BRANCH
17201 && INTVAL (operands[3]) == 128))
17202 && ix86_match_ccmode (insn, CCGCmode)
17203 && peep2_reg_dead_p (1, operands[2])"
17204 [(parallel [(set (match_dup 0)
17205 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17206 (clobber (match_dup 2))])])
17208 ;; Convert imul by three, five and nine into lea
17211 [(set (match_operand:SWI48 0 "register_operand" "")
17212 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17213 (match_operand:SWI48 2 "const359_operand" "")))
17214 (clobber (reg:CC FLAGS_REG))])]
17215 "!TARGET_PARTIAL_REG_STALL
17216 || <MODE>mode == SImode
17217 || optimize_function_for_size_p (cfun)"
17218 [(set (match_dup 0)
17219 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17221 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17225 [(set (match_operand:SWI48 0 "register_operand" "")
17226 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17227 (match_operand:SWI48 2 "const359_operand" "")))
17228 (clobber (reg:CC FLAGS_REG))])]
17229 "optimize_insn_for_speed_p ()
17230 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17231 [(set (match_dup 0) (match_dup 1))
17233 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17235 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17237 ;; imul $32bit_imm, mem, reg is vector decoded, while
17238 ;; imul $32bit_imm, reg, reg is direct decoded.
17240 [(match_scratch:SWI48 3 "r")
17241 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17242 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17243 (match_operand:SWI48 2 "immediate_operand" "")))
17244 (clobber (reg:CC FLAGS_REG))])]
17245 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17246 && !satisfies_constraint_K (operands[2])"
17247 [(set (match_dup 3) (match_dup 1))
17248 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17249 (clobber (reg:CC FLAGS_REG))])])
17252 [(match_scratch:SI 3 "r")
17253 (parallel [(set (match_operand:DI 0 "register_operand" "")
17255 (mult:SI (match_operand:SI 1 "memory_operand" "")
17256 (match_operand:SI 2 "immediate_operand" ""))))
17257 (clobber (reg:CC FLAGS_REG))])]
17259 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17260 && !satisfies_constraint_K (operands[2])"
17261 [(set (match_dup 3) (match_dup 1))
17262 (parallel [(set (match_dup 0)
17263 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17264 (clobber (reg:CC FLAGS_REG))])])
17266 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17267 ;; Convert it into imul reg, reg
17268 ;; It would be better to force assembler to encode instruction using long
17269 ;; immediate, but there is apparently no way to do so.
17271 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17273 (match_operand:SWI248 1 "nonimmediate_operand" "")
17274 (match_operand:SWI248 2 "const_int_operand" "")))
17275 (clobber (reg:CC FLAGS_REG))])
17276 (match_scratch:SWI248 3 "r")]
17277 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17278 && satisfies_constraint_K (operands[2])"
17279 [(set (match_dup 3) (match_dup 2))
17280 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17281 (clobber (reg:CC FLAGS_REG))])]
17283 if (!rtx_equal_p (operands[0], operands[1]))
17284 emit_move_insn (operands[0], operands[1]);
17287 ;; After splitting up read-modify operations, array accesses with memory
17288 ;; operands might end up in form:
17290 ;; movl 4(%esp), %edx
17292 ;; instead of pre-splitting:
17294 ;; addl 4(%esp), %eax
17296 ;; movl 4(%esp), %edx
17297 ;; leal (%edx,%eax,4), %eax
17300 [(match_scratch:P 5 "r")
17301 (parallel [(set (match_operand 0 "register_operand" "")
17302 (ashift (match_operand 1 "register_operand" "")
17303 (match_operand 2 "const_int_operand" "")))
17304 (clobber (reg:CC FLAGS_REG))])
17305 (parallel [(set (match_operand 3 "register_operand" "")
17306 (plus (match_dup 0)
17307 (match_operand 4 "x86_64_general_operand" "")))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17310 /* Validate MODE for lea. */
17311 && ((!TARGET_PARTIAL_REG_STALL
17312 && (GET_MODE (operands[0]) == QImode
17313 || GET_MODE (operands[0]) == HImode))
17314 || GET_MODE (operands[0]) == SImode
17315 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17316 && (rtx_equal_p (operands[0], operands[3])
17317 || peep2_reg_dead_p (2, operands[0]))
17318 /* We reorder load and the shift. */
17319 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17320 [(set (match_dup 5) (match_dup 4))
17321 (set (match_dup 0) (match_dup 1))]
17323 enum machine_mode op1mode = GET_MODE (operands[1]);
17324 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17325 int scale = 1 << INTVAL (operands[2]);
17326 rtx index = gen_lowpart (Pmode, operands[1]);
17327 rtx base = gen_lowpart (Pmode, operands[5]);
17328 rtx dest = gen_lowpart (mode, operands[3]);
17330 operands[1] = gen_rtx_PLUS (Pmode, base,
17331 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17332 operands[5] = base;
17334 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17335 if (op1mode != Pmode)
17336 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17337 operands[0] = dest;
17340 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17341 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17342 ;; caught for use by garbage collectors and the like. Using an insn that
17343 ;; maps to SIGILL makes it more likely the program will rightfully die.
17344 ;; Keeping with tradition, "6" is in honor of #UD.
17345 (define_insn "trap"
17346 [(trap_if (const_int 1) (const_int 6))]
17348 { return ASM_SHORT "0x0b0f"; }
17349 [(set_attr "length" "2")])
17351 (define_expand "prefetch"
17352 [(prefetch (match_operand 0 "address_operand" "")
17353 (match_operand:SI 1 "const_int_operand" "")
17354 (match_operand:SI 2 "const_int_operand" ""))]
17355 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17357 int rw = INTVAL (operands[1]);
17358 int locality = INTVAL (operands[2]);
17360 gcc_assert (rw == 0 || rw == 1);
17361 gcc_assert (locality >= 0 && locality <= 3);
17362 gcc_assert (GET_MODE (operands[0]) == Pmode
17363 || GET_MODE (operands[0]) == VOIDmode);
17365 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17366 supported by SSE counterpart or the SSE prefetch is not available
17367 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17369 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17370 operands[2] = GEN_INT (3);
17372 operands[1] = const0_rtx;
17375 (define_insn "*prefetch_sse_<mode>"
17376 [(prefetch (match_operand:P 0 "address_operand" "p")
17378 (match_operand:SI 1 "const_int_operand" ""))]
17379 "TARGET_PREFETCH_SSE"
17381 static const char * const patterns[4] = {
17382 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17385 int locality = INTVAL (operands[1]);
17386 gcc_assert (locality >= 0 && locality <= 3);
17388 return patterns[locality];
17390 [(set_attr "type" "sse")
17391 (set_attr "atom_sse_attr" "prefetch")
17392 (set (attr "length_address")
17393 (symbol_ref "memory_address_length (operands[0])"))
17394 (set_attr "memory" "none")])
17396 (define_insn "*prefetch_3dnow_<mode>"
17397 [(prefetch (match_operand:P 0 "address_operand" "p")
17398 (match_operand:SI 1 "const_int_operand" "n")
17402 if (INTVAL (operands[1]) == 0)
17403 return "prefetch\t%a0";
17405 return "prefetchw\t%a0";
17407 [(set_attr "type" "mmx")
17408 (set (attr "length_address")
17409 (symbol_ref "memory_address_length (operands[0])"))
17410 (set_attr "memory" "none")])
17412 (define_expand "stack_protect_set"
17413 [(match_operand 0 "memory_operand" "")
17414 (match_operand 1 "memory_operand" "")]
17417 rtx (*insn)(rtx, rtx);
17419 #ifdef TARGET_THREAD_SSP_OFFSET
17420 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17421 insn = (TARGET_64BIT
17422 ? gen_stack_tls_protect_set_di
17423 : gen_stack_tls_protect_set_si);
17425 insn = (TARGET_64BIT
17426 ? gen_stack_protect_set_di
17427 : gen_stack_protect_set_si);
17430 emit_insn (insn (operands[0], operands[1]));
17434 (define_insn "stack_protect_set_<mode>"
17435 [(set (match_operand:P 0 "memory_operand" "=m")
17436 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17437 (set (match_scratch:P 2 "=&r") (const_int 0))
17438 (clobber (reg:CC FLAGS_REG))]
17440 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17441 [(set_attr "type" "multi")])
17443 (define_insn "stack_tls_protect_set_<mode>"
17444 [(set (match_operand:P 0 "memory_operand" "=m")
17445 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17446 UNSPEC_SP_TLS_SET))
17447 (set (match_scratch:P 2 "=&r") (const_int 0))
17448 (clobber (reg:CC FLAGS_REG))]
17450 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17451 [(set_attr "type" "multi")])
17453 (define_expand "stack_protect_test"
17454 [(match_operand 0 "memory_operand" "")
17455 (match_operand 1 "memory_operand" "")
17456 (match_operand 2 "" "")]
17459 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17461 rtx (*insn)(rtx, rtx, rtx);
17463 #ifdef TARGET_THREAD_SSP_OFFSET
17464 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17465 insn = (TARGET_64BIT
17466 ? gen_stack_tls_protect_test_di
17467 : gen_stack_tls_protect_test_si);
17469 insn = (TARGET_64BIT
17470 ? gen_stack_protect_test_di
17471 : gen_stack_protect_test_si);
17474 emit_insn (insn (flags, operands[0], operands[1]));
17476 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17477 flags, const0_rtx, operands[2]));
17481 (define_insn "stack_protect_test_<mode>"
17482 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17483 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17484 (match_operand:P 2 "memory_operand" "m")]
17486 (clobber (match_scratch:P 3 "=&r"))]
17488 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17489 [(set_attr "type" "multi")])
17491 (define_insn "stack_tls_protect_test_<mode>"
17492 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17493 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17494 (match_operand:P 2 "const_int_operand" "i")]
17495 UNSPEC_SP_TLS_TEST))
17496 (clobber (match_scratch:P 3 "=r"))]
17498 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17499 [(set_attr "type" "multi")])
17501 (define_insn "sse4_2_crc32<mode>"
17502 [(set (match_operand:SI 0 "register_operand" "=r")
17504 [(match_operand:SI 1 "register_operand" "0")
17505 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17507 "TARGET_SSE4_2 || TARGET_CRC32"
17508 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17509 [(set_attr "type" "sselog1")
17510 (set_attr "prefix_rep" "1")
17511 (set_attr "prefix_extra" "1")
17512 (set (attr "prefix_data16")
17513 (if_then_else (match_operand:HI 2 "" "")
17515 (const_string "*")))
17516 (set (attr "prefix_rex")
17517 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17519 (const_string "*")))
17520 (set_attr "mode" "SI")])
17522 (define_insn "sse4_2_crc32di"
17523 [(set (match_operand:DI 0 "register_operand" "=r")
17525 [(match_operand:DI 1 "register_operand" "0")
17526 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17528 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17529 "crc32{q}\t{%2, %0|%0, %2}"
17530 [(set_attr "type" "sselog1")
17531 (set_attr "prefix_rep" "1")
17532 (set_attr "prefix_extra" "1")
17533 (set_attr "mode" "DI")])
17535 (define_expand "rdpmc"
17536 [(match_operand:DI 0 "register_operand" "")
17537 (match_operand:SI 1 "register_operand" "")]
17540 rtx reg = gen_reg_rtx (DImode);
17543 /* Force operand 1 into ECX. */
17544 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17545 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17546 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17551 rtvec vec = rtvec_alloc (2);
17552 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17553 rtx upper = gen_reg_rtx (DImode);
17554 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17555 gen_rtvec (1, const0_rtx),
17557 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17558 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17560 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17561 NULL, 1, OPTAB_DIRECT);
17562 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17566 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17567 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17571 (define_insn "*rdpmc"
17572 [(set (match_operand:DI 0 "register_operand" "=A")
17573 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17577 [(set_attr "type" "other")
17578 (set_attr "length" "2")])
17580 (define_insn "*rdpmc_rex64"
17581 [(set (match_operand:DI 0 "register_operand" "=a")
17582 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17584 (set (match_operand:DI 1 "register_operand" "=d")
17585 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17588 [(set_attr "type" "other")
17589 (set_attr "length" "2")])
17591 (define_expand "rdtsc"
17592 [(set (match_operand:DI 0 "register_operand" "")
17593 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17598 rtvec vec = rtvec_alloc (2);
17599 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17600 rtx upper = gen_reg_rtx (DImode);
17601 rtx lower = gen_reg_rtx (DImode);
17602 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17603 gen_rtvec (1, const0_rtx),
17605 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17606 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17608 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17609 NULL, 1, OPTAB_DIRECT);
17610 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17612 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17617 (define_insn "*rdtsc"
17618 [(set (match_operand:DI 0 "register_operand" "=A")
17619 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17622 [(set_attr "type" "other")
17623 (set_attr "length" "2")])
17625 (define_insn "*rdtsc_rex64"
17626 [(set (match_operand:DI 0 "register_operand" "=a")
17627 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17628 (set (match_operand:DI 1 "register_operand" "=d")
17629 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17632 [(set_attr "type" "other")
17633 (set_attr "length" "2")])
17635 (define_expand "rdtscp"
17636 [(match_operand:DI 0 "register_operand" "")
17637 (match_operand:SI 1 "memory_operand" "")]
17640 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17641 gen_rtvec (1, const0_rtx),
17643 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17644 gen_rtvec (1, const0_rtx),
17646 rtx reg = gen_reg_rtx (DImode);
17647 rtx tmp = gen_reg_rtx (SImode);
17651 rtvec vec = rtvec_alloc (3);
17652 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17653 rtx upper = gen_reg_rtx (DImode);
17654 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17655 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17656 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17658 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17659 NULL, 1, OPTAB_DIRECT);
17660 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17665 rtvec vec = rtvec_alloc (2);
17666 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17668 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17671 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17672 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17676 (define_insn "*rdtscp"
17677 [(set (match_operand:DI 0 "register_operand" "=A")
17678 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17679 (set (match_operand:SI 1 "register_operand" "=c")
17680 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17683 [(set_attr "type" "other")
17684 (set_attr "length" "3")])
17686 (define_insn "*rdtscp_rex64"
17687 [(set (match_operand:DI 0 "register_operand" "=a")
17688 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17689 (set (match_operand:DI 1 "register_operand" "=d")
17690 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17691 (set (match_operand:SI 2 "register_operand" "=c")
17692 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17695 [(set_attr "type" "other")
17696 (set_attr "length" "3")])
17698 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17700 ;; LWP instructions
17702 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17704 (define_expand "lwp_llwpcb"
17705 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17706 UNSPECV_LLWP_INTRINSIC)]
17709 (define_insn "*lwp_llwpcb<mode>1"
17710 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17711 UNSPECV_LLWP_INTRINSIC)]
17714 [(set_attr "type" "lwp")
17715 (set_attr "mode" "<MODE>")
17716 (set_attr "length" "5")])
17718 (define_expand "lwp_slwpcb"
17719 [(set (match_operand 0 "register_operand" "=r")
17720 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17725 insn = (TARGET_64BIT
17727 : gen_lwp_slwpcbsi);
17729 emit_insn (insn (operands[0]));
17733 (define_insn "lwp_slwpcb<mode>"
17734 [(set (match_operand:P 0 "register_operand" "=r")
17735 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17738 [(set_attr "type" "lwp")
17739 (set_attr "mode" "<MODE>")
17740 (set_attr "length" "5")])
17742 (define_expand "lwp_lwpval<mode>3"
17743 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17744 (match_operand:SI 2 "nonimmediate_operand" "rm")
17745 (match_operand:SI 3 "const_int_operand" "i")]
17746 UNSPECV_LWPVAL_INTRINSIC)]
17748 "/* Avoid unused variable warning. */
17751 (define_insn "*lwp_lwpval<mode>3_1"
17752 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17753 (match_operand:SI 1 "nonimmediate_operand" "rm")
17754 (match_operand:SI 2 "const_int_operand" "i")]
17755 UNSPECV_LWPVAL_INTRINSIC)]
17757 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17758 [(set_attr "type" "lwp")
17759 (set_attr "mode" "<MODE>")
17760 (set (attr "length")
17761 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17763 (define_expand "lwp_lwpins<mode>3"
17764 [(set (reg:CCC FLAGS_REG)
17765 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17766 (match_operand:SI 2 "nonimmediate_operand" "rm")
17767 (match_operand:SI 3 "const_int_operand" "i")]
17768 UNSPECV_LWPINS_INTRINSIC))
17769 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17770 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17773 (define_insn "*lwp_lwpins<mode>3_1"
17774 [(set (reg:CCC FLAGS_REG)
17775 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17776 (match_operand:SI 1 "nonimmediate_operand" "rm")
17777 (match_operand:SI 2 "const_int_operand" "i")]
17778 UNSPECV_LWPINS_INTRINSIC))]
17780 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17781 [(set_attr "type" "lwp")
17782 (set_attr "mode" "<MODE>")
17783 (set (attr "length")
17784 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17786 (define_insn "rdfsbase<mode>"
17787 [(set (match_operand:SWI48 0 "register_operand" "=r")
17788 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17789 "TARGET_64BIT && TARGET_FSGSBASE"
17791 [(set_attr "type" "other")
17792 (set_attr "prefix_extra" "2")])
17794 (define_insn "rdgsbase<mode>"
17795 [(set (match_operand:SWI48 0 "register_operand" "=r")
17796 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17797 "TARGET_64BIT && TARGET_FSGSBASE"
17799 [(set_attr "type" "other")
17800 (set_attr "prefix_extra" "2")])
17802 (define_insn "wrfsbase<mode>"
17803 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17805 "TARGET_64BIT && TARGET_FSGSBASE"
17807 [(set_attr "type" "other")
17808 (set_attr "prefix_extra" "2")])
17810 (define_insn "wrgsbase<mode>"
17811 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17813 "TARGET_64BIT && TARGET_FSGSBASE"
17815 [(set_attr "type" "other")
17816 (set_attr "prefix_extra" "2")])
17818 (define_insn "rdrand<mode>_1"
17819 [(set (match_operand:SWI248 0 "register_operand" "=r")
17820 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17821 (set (reg:CCC FLAGS_REG)
17822 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17825 [(set_attr "type" "other")
17826 (set_attr "prefix_extra" "1")])
17828 (define_expand "pause"
17829 [(set (match_dup 0)
17830 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17833 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17834 MEM_VOLATILE_P (operands[0]) = 1;
17837 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17838 ;; They have the same encoding.
17839 (define_insn "*pause"
17840 [(set (match_operand:BLK 0 "" "")
17841 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17844 [(set_attr "length" "2")
17845 (set_attr "memory" "unknown")])
17849 (include "sync.md")