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
245 ;; For RDRAND support
252 ;; For __atomic support
256 (define_c_enum "unspecv" [
259 UNSPECV_PROBE_STACK_RANGE
282 UNSPECV_LLWP_INTRINSIC
283 UNSPECV_SLWP_INTRINSIC
284 UNSPECV_LWPVAL_INTRINSIC
285 UNSPECV_LWPINS_INTRINSIC
290 UNSPECV_SPLIT_STACK_RETURN
293 ;; Constants to represent rounding modes in the ROUND instruction
302 ;; Constants to represent pcomtrue/pcomfalse variants
312 ;; Constants used in the XOP pperm instruction
314 [(PPERM_SRC 0x00) /* copy source */
315 (PPERM_INVERT 0x20) /* invert source */
316 (PPERM_REVERSE 0x40) /* bit reverse source */
317 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
318 (PPERM_ZERO 0x80) /* all 0's */
319 (PPERM_ONES 0xa0) /* all 1's */
320 (PPERM_SIGN 0xc0) /* propagate sign bit */
321 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
322 (PPERM_SRC1 0x00) /* use first source byte */
323 (PPERM_SRC2 0x10) /* use second source byte */
326 ;; Registers by name.
379 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
382 ;; In C guard expressions, put expressions which may be compile-time
383 ;; constants first. This allows for better optimization. For
384 ;; example, write "TARGET_64BIT && reload_completed", not
385 ;; "reload_completed && TARGET_64BIT".
389 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
390 atom,generic64,amdfam10,bdver1,bdver2,btver1"
391 (const (symbol_ref "ix86_schedule")))
393 ;; A basic instruction type. Refinements due to arguments to be
394 ;; provided in other attributes.
397 alu,alu1,negnot,imov,imovx,lea,
398 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
399 icmp,test,ibr,setcc,icmov,
400 push,pop,call,callv,leave,
402 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
403 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
404 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
405 ssemuladd,sse4arg,lwp,
406 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
407 (const_string "other"))
409 ;; Main data type used by the insn
411 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
412 (const_string "unknown"))
414 ;; The CPU unit operations uses.
415 (define_attr "unit" "integer,i387,sse,mmx,unknown"
416 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
417 (const_string "i387")
418 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
419 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
420 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
422 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
424 (eq_attr "type" "other")
425 (const_string "unknown")]
426 (const_string "integer")))
428 ;; The (bounding maximum) length of an instruction immediate.
429 (define_attr "length_immediate" ""
430 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
433 (eq_attr "unit" "i387,sse,mmx")
435 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
436 rotate,rotatex,rotate1,imul,icmp,push,pop")
437 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
438 (eq_attr "type" "imov,test")
439 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
440 (eq_attr "type" "call")
441 (if_then_else (match_operand 0 "constant_call_address_operand" "")
444 (eq_attr "type" "callv")
445 (if_then_else (match_operand 1 "constant_call_address_operand" "")
448 ;; We don't know the size before shorten_branches. Expect
449 ;; the instruction to fit for better scheduling.
450 (eq_attr "type" "ibr")
453 (symbol_ref "/* Update immediate_length and other attributes! */
454 gcc_unreachable (),1")))
456 ;; The (bounding maximum) length of an instruction address.
457 (define_attr "length_address" ""
458 (cond [(eq_attr "type" "str,other,multi,fxch")
460 (and (eq_attr "type" "call")
461 (match_operand 0 "constant_call_address_operand" ""))
463 (and (eq_attr "type" "callv")
464 (match_operand 1 "constant_call_address_operand" ""))
467 (symbol_ref "ix86_attr_length_address_default (insn)")))
469 ;; Set when length prefix is used.
470 (define_attr "prefix_data16" ""
471 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
473 (eq_attr "mode" "HI")
475 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
480 ;; Set when string REP prefix is used.
481 (define_attr "prefix_rep" ""
482 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
484 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
489 ;; Set when 0f opcode prefix is used.
490 (define_attr "prefix_0f" ""
492 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
493 (eq_attr "unit" "sse,mmx"))
497 ;; Set when REX opcode prefix is used.
498 (define_attr "prefix_rex" ""
499 (cond [(not (match_test "TARGET_64BIT"))
501 (and (eq_attr "mode" "DI")
502 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
503 (eq_attr "unit" "!mmx")))
505 (and (eq_attr "mode" "QI")
506 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
508 (match_test "x86_extended_reg_mentioned_p (insn)")
510 (and (eq_attr "type" "imovx")
511 (match_operand:QI 1 "ext_QIreg_operand" ""))
516 ;; There are also additional prefixes in 3DNOW, SSSE3.
517 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
518 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
519 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
520 (define_attr "prefix_extra" ""
521 (cond [(eq_attr "type" "ssemuladd,sse4arg")
523 (eq_attr "type" "sseiadd1,ssecvt1")
528 ;; Prefix used: original, VEX or maybe VEX.
529 (define_attr "prefix" "orig,vex,maybe_vex"
530 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
532 (const_string "orig")))
534 ;; VEX W bit is used.
535 (define_attr "prefix_vex_w" "" (const_int 0))
537 ;; The length of VEX prefix
538 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
539 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
540 ;; still prefix_0f 1, with prefix_extra 1.
541 (define_attr "length_vex" ""
542 (if_then_else (and (eq_attr "prefix_0f" "1")
543 (eq_attr "prefix_extra" "0"))
544 (if_then_else (eq_attr "prefix_vex_w" "1")
545 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
546 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
547 (if_then_else (eq_attr "prefix_vex_w" "1")
548 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
549 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
551 ;; Set when modrm byte is used.
552 (define_attr "modrm" ""
553 (cond [(eq_attr "type" "str,leave")
555 (eq_attr "unit" "i387")
557 (and (eq_attr "type" "incdec")
558 (and (not (match_test "TARGET_64BIT"))
559 (ior (match_operand:SI 1 "register_operand" "")
560 (match_operand:HI 1 "register_operand" ""))))
562 (and (eq_attr "type" "push")
563 (not (match_operand 1 "memory_operand" "")))
565 (and (eq_attr "type" "pop")
566 (not (match_operand 0 "memory_operand" "")))
568 (and (eq_attr "type" "imov")
569 (and (not (eq_attr "mode" "DI"))
570 (ior (and (match_operand 0 "register_operand" "")
571 (match_operand 1 "immediate_operand" ""))
572 (ior (and (match_operand 0 "ax_reg_operand" "")
573 (match_operand 1 "memory_displacement_only_operand" ""))
574 (and (match_operand 0 "memory_displacement_only_operand" "")
575 (match_operand 1 "ax_reg_operand" ""))))))
577 (and (eq_attr "type" "call")
578 (match_operand 0 "constant_call_address_operand" ""))
580 (and (eq_attr "type" "callv")
581 (match_operand 1 "constant_call_address_operand" ""))
583 (and (eq_attr "type" "alu,alu1,icmp,test")
584 (match_operand 0 "ax_reg_operand" ""))
585 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
589 ;; The (bounding maximum) length of an instruction in bytes.
590 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
591 ;; Later we may want to split them and compute proper length as for
593 (define_attr "length" ""
594 (cond [(eq_attr "type" "other,multi,fistp,frndint")
596 (eq_attr "type" "fcmp")
598 (eq_attr "unit" "i387")
600 (plus (attr "prefix_data16")
601 (attr "length_address")))
602 (ior (eq_attr "prefix" "vex")
603 (and (eq_attr "prefix" "maybe_vex")
604 (match_test "TARGET_AVX")))
605 (plus (attr "length_vex")
606 (plus (attr "length_immediate")
608 (attr "length_address"))))]
609 (plus (plus (attr "modrm")
610 (plus (attr "prefix_0f")
611 (plus (attr "prefix_rex")
612 (plus (attr "prefix_extra")
614 (plus (attr "prefix_rep")
615 (plus (attr "prefix_data16")
616 (plus (attr "length_immediate")
617 (attr "length_address")))))))
619 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
620 ;; `store' if there is a simple memory reference therein, or `unknown'
621 ;; if the instruction is complex.
623 (define_attr "memory" "none,load,store,both,unknown"
624 (cond [(eq_attr "type" "other,multi,str,lwp")
625 (const_string "unknown")
626 (eq_attr "type" "lea,fcmov,fpspc")
627 (const_string "none")
628 (eq_attr "type" "fistp,leave")
629 (const_string "both")
630 (eq_attr "type" "frndint")
631 (const_string "load")
632 (eq_attr "type" "push")
633 (if_then_else (match_operand 1 "memory_operand" "")
634 (const_string "both")
635 (const_string "store"))
636 (eq_attr "type" "pop")
637 (if_then_else (match_operand 0 "memory_operand" "")
638 (const_string "both")
639 (const_string "load"))
640 (eq_attr "type" "setcc")
641 (if_then_else (match_operand 0 "memory_operand" "")
642 (const_string "store")
643 (const_string "none"))
644 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
645 (if_then_else (ior (match_operand 0 "memory_operand" "")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "load")
648 (const_string "none"))
649 (eq_attr "type" "ibr")
650 (if_then_else (match_operand 0 "memory_operand" "")
651 (const_string "load")
652 (const_string "none"))
653 (eq_attr "type" "call")
654 (if_then_else (match_operand 0 "constant_call_address_operand" "")
655 (const_string "none")
656 (const_string "load"))
657 (eq_attr "type" "callv")
658 (if_then_else (match_operand 1 "constant_call_address_operand" "")
659 (const_string "none")
660 (const_string "load"))
661 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
662 (match_operand 1 "memory_operand" ""))
663 (const_string "both")
664 (and (match_operand 0 "memory_operand" "")
665 (match_operand 1 "memory_operand" ""))
666 (const_string "both")
667 (match_operand 0 "memory_operand" "")
668 (const_string "store")
669 (match_operand 1 "memory_operand" "")
670 (const_string "load")
672 "!alu1,negnot,ishift1,
673 imov,imovx,icmp,test,bitmanip,
675 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
676 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
677 (match_operand 2 "memory_operand" ""))
678 (const_string "load")
679 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
680 (match_operand 3 "memory_operand" ""))
681 (const_string "load")
683 (const_string "none")))
685 ;; Indicates if an instruction has both an immediate and a displacement.
687 (define_attr "imm_disp" "false,true,unknown"
688 (cond [(eq_attr "type" "other,multi")
689 (const_string "unknown")
690 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
691 (and (match_operand 0 "memory_displacement_operand" "")
692 (match_operand 1 "immediate_operand" "")))
693 (const_string "true")
694 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
695 (and (match_operand 0 "memory_displacement_operand" "")
696 (match_operand 2 "immediate_operand" "")))
697 (const_string "true")
699 (const_string "false")))
701 ;; Indicates if an FP operation has an integer source.
703 (define_attr "fp_int_src" "false,true"
704 (const_string "false"))
706 ;; Defines rounding mode of an FP operation.
708 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
709 (const_string "any"))
711 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
712 (define_attr "use_carry" "0,1" (const_string "0"))
714 ;; Define attribute to indicate unaligned ssemov insns
715 (define_attr "movu" "0,1" (const_string "0"))
717 ;; Used to control the "enabled" attribute on a per-instruction basis.
718 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
719 (const_string "base"))
721 (define_attr "enabled" ""
722 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
723 (eq_attr "isa" "sse2_noavx")
724 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
725 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
726 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
727 (eq_attr "isa" "sse4_noavx")
728 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
729 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
730 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
731 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
735 ;; Describe a user's asm statement.
736 (define_asm_attributes
737 [(set_attr "length" "128")
738 (set_attr "type" "multi")])
740 (define_code_iterator plusminus [plus minus])
742 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
744 ;; Base name for define_insn
745 (define_code_attr plusminus_insn
746 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
747 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
749 ;; Base name for insn mnemonic.
750 (define_code_attr plusminus_mnemonic
751 [(plus "add") (ss_plus "adds") (us_plus "addus")
752 (minus "sub") (ss_minus "subs") (us_minus "subus")])
753 (define_code_attr plusminus_carry_mnemonic
754 [(plus "adc") (minus "sbb")])
756 ;; Mark commutative operators as such in constraints.
757 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
758 (minus "") (ss_minus "") (us_minus "")])
760 ;; Mapping of max and min
761 (define_code_iterator maxmin [smax smin umax umin])
763 ;; Mapping of signed max and min
764 (define_code_iterator smaxmin [smax smin])
766 ;; Mapping of unsigned max and min
767 (define_code_iterator umaxmin [umax umin])
769 ;; Base name for integer and FP insn mnemonic
770 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
771 (umax "maxu") (umin "minu")])
772 (define_code_attr maxmin_float [(smax "max") (smin "min")])
774 ;; Mapping of logic operators
775 (define_code_iterator any_logic [and ior xor])
776 (define_code_iterator any_or [ior xor])
778 ;; Base name for insn mnemonic.
779 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
781 ;; Mapping of logic-shift operators
782 (define_code_iterator any_lshift [ashift lshiftrt])
784 ;; Mapping of shift-right operators
785 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
787 ;; Base name for define_insn
788 (define_code_attr shift_insn
789 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
791 ;; Base name for insn mnemonic.
792 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
793 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
795 ;; Mapping of rotate operators
796 (define_code_iterator any_rotate [rotate rotatert])
798 ;; Base name for define_insn
799 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
801 ;; Base name for insn mnemonic.
802 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
804 ;; Mapping of abs neg operators
805 (define_code_iterator absneg [abs neg])
807 ;; Base name for x87 insn mnemonic.
808 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
810 ;; Used in signed and unsigned widening multiplications.
811 (define_code_iterator any_extend [sign_extend zero_extend])
813 ;; Prefix for insn menmonic.
814 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
816 ;; Prefix for define_insn
817 (define_code_attr u [(sign_extend "") (zero_extend "u")])
818 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
820 ;; All integer modes.
821 (define_mode_iterator SWI1248x [QI HI SI DI])
823 ;; All integer modes without QImode.
824 (define_mode_iterator SWI248x [HI SI DI])
826 ;; All integer modes without QImode and HImode.
827 (define_mode_iterator SWI48x [SI DI])
829 ;; All integer modes without SImode and DImode.
830 (define_mode_iterator SWI12 [QI HI])
832 ;; All integer modes without DImode.
833 (define_mode_iterator SWI124 [QI HI SI])
835 ;; All integer modes without QImode and DImode.
836 (define_mode_iterator SWI24 [HI SI])
838 ;; Single word integer modes.
839 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
841 ;; Single word integer modes without QImode.
842 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
844 ;; Single word integer modes without QImode and HImode.
845 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
847 ;; All math-dependant single and double word integer modes.
848 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
849 (HI "TARGET_HIMODE_MATH")
850 SI DI (TI "TARGET_64BIT")])
852 ;; Math-dependant single word integer modes.
853 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
854 (HI "TARGET_HIMODE_MATH")
855 SI (DI "TARGET_64BIT")])
857 ;; Math-dependant integer modes without DImode.
858 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
859 (HI "TARGET_HIMODE_MATH")
862 ;; Math-dependant single word integer modes without QImode.
863 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
864 SI (DI "TARGET_64BIT")])
866 ;; Double word integer modes.
867 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
868 (TI "TARGET_64BIT")])
870 ;; Double word integer modes as mode attribute.
871 (define_mode_attr DWI [(SI "DI") (DI "TI")])
872 (define_mode_attr dwi [(SI "di") (DI "ti")])
874 ;; Half mode for double word integer modes.
875 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
876 (DI "TARGET_64BIT")])
878 ;; Instruction suffix for integer modes.
879 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
881 ;; Pointer size prefix for integer modes (Intel asm dialect)
882 (define_mode_attr iptrsize [(QI "BYTE")
887 ;; Register class for integer modes.
888 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
890 ;; Immediate operand constraint for integer modes.
891 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
893 ;; General operand constraint for word modes.
894 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
896 ;; Immediate operand constraint for double integer modes.
897 (define_mode_attr di [(SI "nF") (DI "e")])
899 ;; Immediate operand constraint for shifts.
900 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
902 ;; General operand predicate for integer modes.
903 (define_mode_attr general_operand
904 [(QI "general_operand")
905 (HI "general_operand")
906 (SI "x86_64_general_operand")
907 (DI "x86_64_general_operand")
908 (TI "x86_64_general_operand")])
910 ;; General sign/zero extend operand predicate for integer modes.
911 (define_mode_attr general_szext_operand
912 [(QI "general_operand")
913 (HI "general_operand")
914 (SI "x86_64_szext_general_operand")
915 (DI "x86_64_szext_general_operand")])
917 ;; Immediate operand predicate for integer modes.
918 (define_mode_attr immediate_operand
919 [(QI "immediate_operand")
920 (HI "immediate_operand")
921 (SI "x86_64_immediate_operand")
922 (DI "x86_64_immediate_operand")])
924 ;; Nonmemory operand predicate for integer modes.
925 (define_mode_attr nonmemory_operand
926 [(QI "nonmemory_operand")
927 (HI "nonmemory_operand")
928 (SI "x86_64_nonmemory_operand")
929 (DI "x86_64_nonmemory_operand")])
931 ;; Operand predicate for shifts.
932 (define_mode_attr shift_operand
933 [(QI "nonimmediate_operand")
934 (HI "nonimmediate_operand")
935 (SI "nonimmediate_operand")
936 (DI "shiftdi_operand")
937 (TI "register_operand")])
939 ;; Operand predicate for shift argument.
940 (define_mode_attr shift_immediate_operand
941 [(QI "const_1_to_31_operand")
942 (HI "const_1_to_31_operand")
943 (SI "const_1_to_31_operand")
944 (DI "const_1_to_63_operand")])
946 ;; Input operand predicate for arithmetic left shifts.
947 (define_mode_attr ashl_input_operand
948 [(QI "nonimmediate_operand")
949 (HI "nonimmediate_operand")
950 (SI "nonimmediate_operand")
951 (DI "ashldi_input_operand")
952 (TI "reg_or_pm1_operand")])
954 ;; SSE and x87 SFmode and DFmode floating point modes
955 (define_mode_iterator MODEF [SF DF])
957 ;; All x87 floating point modes
958 (define_mode_iterator X87MODEF [SF DF XF])
960 ;; SSE instruction suffix for various modes
961 (define_mode_attr ssemodesuffix
963 (V8SF "ps") (V4DF "pd")
964 (V4SF "ps") (V2DF "pd")
965 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
966 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
968 ;; SSE vector suffix for floating point modes
969 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
971 ;; SSE vector mode corresponding to a scalar mode
972 (define_mode_attr ssevecmode
973 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
975 ;; Instruction suffix for REX 64bit operators.
976 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
978 ;; This mode iterator allows :P to be used for patterns that operate on
979 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
980 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
982 ;; This mode iterator allows :PTR to be used for patterns that operate on
983 ;; ptr_mode sized quantities.
984 (define_mode_iterator PTR
985 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
987 ;; Scheduling descriptions
989 (include "pentium.md")
992 (include "athlon.md")
993 (include "bdver1.md")
999 ;; Operand and operator predicates and constraints
1001 (include "predicates.md")
1002 (include "constraints.md")
1005 ;; Compare and branch/compare and store instructions.
1007 (define_expand "cbranch<mode>4"
1008 [(set (reg:CC FLAGS_REG)
1009 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1010 (match_operand:SDWIM 2 "<general_operand>" "")))
1011 (set (pc) (if_then_else
1012 (match_operator 0 "ordered_comparison_operator"
1013 [(reg:CC FLAGS_REG) (const_int 0)])
1014 (label_ref (match_operand 3 "" ""))
1018 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1019 operands[1] = force_reg (<MODE>mode, operands[1]);
1020 ix86_expand_branch (GET_CODE (operands[0]),
1021 operands[1], operands[2], operands[3]);
1025 (define_expand "cstore<mode>4"
1026 [(set (reg:CC FLAGS_REG)
1027 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1028 (match_operand:SWIM 3 "<general_operand>" "")))
1029 (set (match_operand:QI 0 "register_operand" "")
1030 (match_operator 1 "ordered_comparison_operator"
1031 [(reg:CC FLAGS_REG) (const_int 0)]))]
1034 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1035 operands[2] = force_reg (<MODE>mode, operands[2]);
1036 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1037 operands[2], operands[3]);
1041 (define_expand "cmp<mode>_1"
1042 [(set (reg:CC FLAGS_REG)
1043 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1044 (match_operand:SWI48 1 "<general_operand>" "")))])
1046 (define_insn "*cmp<mode>_ccno_1"
1047 [(set (reg FLAGS_REG)
1048 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1049 (match_operand:SWI 1 "const0_operand" "")))]
1050 "ix86_match_ccmode (insn, CCNOmode)"
1052 test{<imodesuffix>}\t%0, %0
1053 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1054 [(set_attr "type" "test,icmp")
1055 (set_attr "length_immediate" "0,1")
1056 (set_attr "mode" "<MODE>")])
1058 (define_insn "*cmp<mode>_1"
1059 [(set (reg FLAGS_REG)
1060 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1061 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1062 "ix86_match_ccmode (insn, CCmode)"
1063 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "<MODE>")])
1067 (define_insn "*cmp<mode>_minus_1"
1068 [(set (reg FLAGS_REG)
1070 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1071 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1073 "ix86_match_ccmode (insn, CCGOCmode)"
1074 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "<MODE>")])
1078 (define_insn "*cmpqi_ext_1"
1079 [(set (reg FLAGS_REG)
1081 (match_operand:QI 0 "general_operand" "Qm")
1084 (match_operand 1 "ext_register_operand" "Q")
1086 (const_int 8)) 0)))]
1087 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %0|%0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1092 (define_insn "*cmpqi_ext_1_rex64"
1093 [(set (reg FLAGS_REG)
1095 (match_operand:QI 0 "register_operand" "Q")
1098 (match_operand 1 "ext_register_operand" "Q")
1100 (const_int 8)) 0)))]
1101 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%h1, %0|%0, %h1}"
1103 [(set_attr "type" "icmp")
1104 (set_attr "mode" "QI")])
1106 (define_insn "*cmpqi_ext_2"
1107 [(set (reg FLAGS_REG)
1111 (match_operand 0 "ext_register_operand" "Q")
1114 (match_operand:QI 1 "const0_operand" "")))]
1115 "ix86_match_ccmode (insn, CCNOmode)"
1117 [(set_attr "type" "test")
1118 (set_attr "length_immediate" "0")
1119 (set_attr "mode" "QI")])
1121 (define_expand "cmpqi_ext_3"
1122 [(set (reg:CC FLAGS_REG)
1126 (match_operand 0 "ext_register_operand" "")
1129 (match_operand:QI 1 "immediate_operand" "")))])
1131 (define_insn "*cmpqi_ext_3_insn"
1132 [(set (reg FLAGS_REG)
1136 (match_operand 0 "ext_register_operand" "Q")
1139 (match_operand:QI 1 "general_operand" "Qmn")))]
1140 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1141 "cmp{b}\t{%1, %h0|%h0, %1}"
1142 [(set_attr "type" "icmp")
1143 (set_attr "modrm" "1")
1144 (set_attr "mode" "QI")])
1146 (define_insn "*cmpqi_ext_3_insn_rex64"
1147 [(set (reg FLAGS_REG)
1151 (match_operand 0 "ext_register_operand" "Q")
1154 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1155 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1156 "cmp{b}\t{%1, %h0|%h0, %1}"
1157 [(set_attr "type" "icmp")
1158 (set_attr "modrm" "1")
1159 (set_attr "mode" "QI")])
1161 (define_insn "*cmpqi_ext_4"
1162 [(set (reg FLAGS_REG)
1166 (match_operand 0 "ext_register_operand" "Q")
1171 (match_operand 1 "ext_register_operand" "Q")
1173 (const_int 8)) 0)))]
1174 "ix86_match_ccmode (insn, CCmode)"
1175 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1176 [(set_attr "type" "icmp")
1177 (set_attr "mode" "QI")])
1179 ;; These implement float point compares.
1180 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1181 ;; which would allow mix and match FP modes on the compares. Which is what
1182 ;; the old patterns did, but with many more of them.
1184 (define_expand "cbranchxf4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1187 (match_operand:XF 2 "nonmemory_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1192 (label_ref (match_operand 3 "" ""))
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstorexf4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1204 (match_operand:XF 3 "nonmemory_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1216 (define_expand "cbranch<mode>4"
1217 [(set (reg:CC FLAGS_REG)
1218 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1219 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1220 (set (pc) (if_then_else
1221 (match_operator 0 "ix86_fp_comparison_operator"
1224 (label_ref (match_operand 3 "" ""))
1226 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1228 ix86_expand_branch (GET_CODE (operands[0]),
1229 operands[1], operands[2], operands[3]);
1233 (define_expand "cstore<mode>4"
1234 [(set (reg:CC FLAGS_REG)
1235 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1236 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1237 (set (match_operand:QI 0 "register_operand" "")
1238 (match_operator 1 "ix86_fp_comparison_operator"
1241 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1243 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244 operands[2], operands[3]);
1248 (define_expand "cbranchcc4"
1249 [(set (pc) (if_then_else
1250 (match_operator 0 "comparison_operator"
1251 [(match_operand 1 "flags_reg_operand" "")
1252 (match_operand 2 "const0_operand" "")])
1253 (label_ref (match_operand 3 "" ""))
1257 ix86_expand_branch (GET_CODE (operands[0]),
1258 operands[1], operands[2], operands[3]);
1262 (define_expand "cstorecc4"
1263 [(set (match_operand:QI 0 "register_operand" "")
1264 (match_operator 1 "comparison_operator"
1265 [(match_operand 2 "flags_reg_operand" "")
1266 (match_operand 3 "const0_operand" "")]))]
1269 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1270 operands[2], operands[3]);
1275 ;; FP compares, step 1:
1276 ;; Set the FP condition codes.
1278 ;; CCFPmode compare with exceptions
1279 ;; CCFPUmode compare with no exceptions
1281 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1282 ;; used to manage the reg stack popping would not be preserved.
1284 (define_insn "*cmpfp_0"
1285 [(set (match_operand:HI 0 "register_operand" "=a")
1288 (match_operand 1 "register_operand" "f")
1289 (match_operand 2 "const0_operand" ""))]
1291 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1292 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1293 "* return output_fp_compare (insn, operands, false, false);"
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn_and_split "*cmpfp_0_cc"
1305 [(set (reg:CCFP FLAGS_REG)
1307 (match_operand 1 "register_operand" "f")
1308 (match_operand 2 "const0_operand" "")))
1309 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1310 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1311 && TARGET_SAHF && !TARGET_CMOVE
1312 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1314 "&& reload_completed"
1317 [(compare:CCFP (match_dup 1)(match_dup 2))]
1319 (set (reg:CC FLAGS_REG)
1320 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1322 [(set_attr "type" "multi")
1323 (set_attr "unit" "i387")
1325 (cond [(match_operand:SF 1 "" "")
1327 (match_operand:DF 1 "" "")
1330 (const_string "XF")))])
1332 (define_insn "*cmpfp_xf"
1333 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (match_operand:XF 1 "register_operand" "f")
1337 (match_operand:XF 2 "register_operand" "f"))]
1340 "* return output_fp_compare (insn, operands, false, false);"
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1343 (set_attr "mode" "XF")])
1345 (define_insn_and_split "*cmpfp_xf_cc"
1346 [(set (reg:CCFP FLAGS_REG)
1348 (match_operand:XF 1 "register_operand" "f")
1349 (match_operand:XF 2 "register_operand" "f")))
1350 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352 && TARGET_SAHF && !TARGET_CMOVE"
1354 "&& reload_completed"
1357 [(compare:CCFP (match_dup 1)(match_dup 2))]
1359 (set (reg:CC FLAGS_REG)
1360 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1362 [(set_attr "type" "multi")
1363 (set_attr "unit" "i387")
1364 (set_attr "mode" "XF")])
1366 (define_insn "*cmpfp_<mode>"
1367 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (match_operand:MODEF 1 "register_operand" "f")
1371 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1374 "* return output_fp_compare (insn, operands, false, false);"
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1377 (set_attr "mode" "<MODE>")])
1379 (define_insn_and_split "*cmpfp_<mode>_cc"
1380 [(set (reg:CCFP FLAGS_REG)
1382 (match_operand:MODEF 1 "register_operand" "f")
1383 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1386 && TARGET_SAHF && !TARGET_CMOVE"
1388 "&& reload_completed"
1391 [(compare:CCFP (match_dup 1)(match_dup 2))]
1393 (set (reg:CC FLAGS_REG)
1394 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1396 [(set_attr "type" "multi")
1397 (set_attr "unit" "i387")
1398 (set_attr "mode" "<MODE>")])
1400 (define_insn "*cmpfp_u"
1401 [(set (match_operand:HI 0 "register_operand" "=a")
1404 (match_operand 1 "register_operand" "f")
1405 (match_operand 2 "register_operand" "f"))]
1407 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1409 "* return output_fp_compare (insn, operands, false, true);"
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1413 (cond [(match_operand:SF 1 "" "")
1415 (match_operand:DF 1 "" "")
1418 (const_string "XF")))])
1420 (define_insn_and_split "*cmpfp_u_cc"
1421 [(set (reg:CCFPU FLAGS_REG)
1423 (match_operand 1 "register_operand" "f")
1424 (match_operand 2 "register_operand" "f")))
1425 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1426 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1427 && TARGET_SAHF && !TARGET_CMOVE
1428 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1430 "&& reload_completed"
1433 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1435 (set (reg:CC FLAGS_REG)
1436 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1438 [(set_attr "type" "multi")
1439 (set_attr "unit" "i387")
1441 (cond [(match_operand:SF 1 "" "")
1443 (match_operand:DF 1 "" "")
1446 (const_string "XF")))])
1448 (define_insn "*cmpfp_<mode>"
1449 [(set (match_operand:HI 0 "register_operand" "=a")
1452 (match_operand 1 "register_operand" "f")
1453 (match_operator 3 "float_operator"
1454 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1457 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1458 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1459 "* return output_fp_compare (insn, operands, false, false);"
1460 [(set_attr "type" "multi")
1461 (set_attr "unit" "i387")
1462 (set_attr "fp_int_src" "true")
1463 (set_attr "mode" "<MODE>")])
1465 (define_insn_and_split "*cmpfp_<mode>_cc"
1466 [(set (reg:CCFP FLAGS_REG)
1468 (match_operand 1 "register_operand" "f")
1469 (match_operator 3 "float_operator"
1470 [(match_operand:SWI24 2 "memory_operand" "m")])))
1471 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1473 && TARGET_SAHF && !TARGET_CMOVE
1474 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1475 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1477 "&& reload_completed"
1482 (match_op_dup 3 [(match_dup 2)]))]
1484 (set (reg:CC FLAGS_REG)
1485 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1487 [(set_attr "type" "multi")
1488 (set_attr "unit" "i387")
1489 (set_attr "fp_int_src" "true")
1490 (set_attr "mode" "<MODE>")])
1492 ;; FP compares, step 2
1493 ;; Move the fpsw to ax.
1495 (define_insn "x86_fnstsw_1"
1496 [(set (match_operand:HI 0 "register_operand" "=a")
1497 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1500 [(set (attr "length")
1501 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1502 (set_attr "mode" "SI")
1503 (set_attr "unit" "i387")])
1505 ;; FP compares, step 3
1506 ;; Get ax into flags, general case.
1508 (define_insn "x86_sahf_1"
1509 [(set (reg:CC FLAGS_REG)
1510 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1514 #ifndef HAVE_AS_IX86_SAHF
1516 return ASM_BYTE "0x9e";
1521 [(set_attr "length" "1")
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "direct")
1525 (set_attr "mode" "SI")])
1527 ;; Pentium Pro can do steps 1 through 3 in one go.
1528 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1529 ;; (these i387 instructions set flags directly)
1530 (define_insn "*cmpfp_i_mixed"
1531 [(set (reg:CCFP FLAGS_REG)
1532 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1533 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1534 "TARGET_MIX_SSE_I387
1535 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537 "* return output_fp_compare (insn, operands, true, false);"
1538 [(set_attr "type" "fcmp,ssecomi")
1539 (set_attr "prefix" "orig,maybe_vex")
1541 (if_then_else (match_operand:SF 1 "" "")
1543 (const_string "DF")))
1544 (set (attr "prefix_rep")
1545 (if_then_else (eq_attr "type" "ssecomi")
1547 (const_string "*")))
1548 (set (attr "prefix_data16")
1549 (cond [(eq_attr "type" "fcmp")
1551 (eq_attr "mode" "DF")
1554 (const_string "0")))
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "amdfam10_decode" "direct")
1557 (set_attr "bdver1_decode" "double")])
1559 (define_insn "*cmpfp_i_sse"
1560 [(set (reg:CCFP FLAGS_REG)
1561 (compare:CCFP (match_operand 0 "register_operand" "x")
1562 (match_operand 1 "nonimmediate_operand" "xm")))]
1564 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1565 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1566 "* return output_fp_compare (insn, operands, true, false);"
1567 [(set_attr "type" "ssecomi")
1568 (set_attr "prefix" "maybe_vex")
1570 (if_then_else (match_operand:SF 1 "" "")
1572 (const_string "DF")))
1573 (set_attr "prefix_rep" "0")
1574 (set (attr "prefix_data16")
1575 (if_then_else (eq_attr "mode" "DF")
1577 (const_string "0")))
1578 (set_attr "athlon_decode" "vector")
1579 (set_attr "amdfam10_decode" "direct")
1580 (set_attr "bdver1_decode" "double")])
1582 (define_insn "*cmpfp_i_i387"
1583 [(set (reg:CCFP FLAGS_REG)
1584 (compare:CCFP (match_operand 0 "register_operand" "f")
1585 (match_operand 1 "register_operand" "f")))]
1586 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1588 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1589 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1590 "* return output_fp_compare (insn, operands, true, false);"
1591 [(set_attr "type" "fcmp")
1593 (cond [(match_operand:SF 1 "" "")
1595 (match_operand:DF 1 "" "")
1598 (const_string "XF")))
1599 (set_attr "athlon_decode" "vector")
1600 (set_attr "amdfam10_decode" "direct")
1601 (set_attr "bdver1_decode" "double")])
1603 (define_insn "*cmpfp_iu_mixed"
1604 [(set (reg:CCFPU FLAGS_REG)
1605 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1606 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1607 "TARGET_MIX_SSE_I387
1608 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1609 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1610 "* return output_fp_compare (insn, operands, true, true);"
1611 [(set_attr "type" "fcmp,ssecomi")
1612 (set_attr "prefix" "orig,maybe_vex")
1614 (if_then_else (match_operand:SF 1 "" "")
1616 (const_string "DF")))
1617 (set (attr "prefix_rep")
1618 (if_then_else (eq_attr "type" "ssecomi")
1620 (const_string "*")))
1621 (set (attr "prefix_data16")
1622 (cond [(eq_attr "type" "fcmp")
1624 (eq_attr "mode" "DF")
1627 (const_string "0")))
1628 (set_attr "athlon_decode" "vector")
1629 (set_attr "amdfam10_decode" "direct")
1630 (set_attr "bdver1_decode" "double")])
1632 (define_insn "*cmpfp_iu_sse"
1633 [(set (reg:CCFPU FLAGS_REG)
1634 (compare:CCFPU (match_operand 0 "register_operand" "x")
1635 (match_operand 1 "nonimmediate_operand" "xm")))]
1637 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1638 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1639 "* return output_fp_compare (insn, operands, true, true);"
1640 [(set_attr "type" "ssecomi")
1641 (set_attr "prefix" "maybe_vex")
1643 (if_then_else (match_operand:SF 1 "" "")
1645 (const_string "DF")))
1646 (set_attr "prefix_rep" "0")
1647 (set (attr "prefix_data16")
1648 (if_then_else (eq_attr "mode" "DF")
1650 (const_string "0")))
1651 (set_attr "athlon_decode" "vector")
1652 (set_attr "amdfam10_decode" "direct")
1653 (set_attr "bdver1_decode" "double")])
1655 (define_insn "*cmpfp_iu_387"
1656 [(set (reg:CCFPU FLAGS_REG)
1657 (compare:CCFPU (match_operand 0 "register_operand" "f")
1658 (match_operand 1 "register_operand" "f")))]
1659 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1661 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1662 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1663 "* return output_fp_compare (insn, operands, true, true);"
1664 [(set_attr "type" "fcmp")
1666 (cond [(match_operand:SF 1 "" "")
1668 (match_operand:DF 1 "" "")
1671 (const_string "XF")))
1672 (set_attr "athlon_decode" "vector")
1673 (set_attr "amdfam10_decode" "direct")
1674 (set_attr "bdver1_decode" "direct")])
1676 ;; Push/pop instructions.
1678 (define_insn "*push<mode>2"
1679 [(set (match_operand:DWI 0 "push_operand" "=<")
1680 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1683 [(set_attr "type" "multi")
1684 (set_attr "mode" "<MODE>")])
1687 [(set (match_operand:TI 0 "push_operand" "")
1688 (match_operand:TI 1 "general_operand" ""))]
1689 "TARGET_64BIT && reload_completed
1690 && !SSE_REG_P (operands[1])"
1692 "ix86_split_long_move (operands); DONE;")
1694 (define_insn "*pushdi2_rex64"
1695 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1696 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1701 [(set_attr "type" "push,multi")
1702 (set_attr "mode" "DI")])
1704 ;; Convert impossible pushes of immediate to existing instructions.
1705 ;; First try to get scratch register and go through it. In case this
1706 ;; fails, push sign extended lower part first and then overwrite
1707 ;; upper part by 32bit move.
1709 [(match_scratch:DI 2 "r")
1710 (set (match_operand:DI 0 "push_operand" "")
1711 (match_operand:DI 1 "immediate_operand" ""))]
1712 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1713 && !x86_64_immediate_operand (operands[1], DImode)"
1714 [(set (match_dup 2) (match_dup 1))
1715 (set (match_dup 0) (match_dup 2))])
1717 ;; We need to define this as both peepholer and splitter for case
1718 ;; peephole2 pass is not run.
1719 ;; "&& 1" is needed to keep it from matching the previous pattern.
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "immediate_operand" ""))]
1723 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1724 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1725 [(set (match_dup 0) (match_dup 1))
1726 (set (match_dup 2) (match_dup 3))]
1728 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1730 operands[1] = gen_lowpart (DImode, operands[2]);
1731 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1736 [(set (match_operand:DI 0 "push_operand" "")
1737 (match_operand:DI 1 "immediate_operand" ""))]
1738 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1739 ? epilogue_completed : reload_completed)
1740 && !symbolic_operand (operands[1], DImode)
1741 && !x86_64_immediate_operand (operands[1], DImode)"
1742 [(set (match_dup 0) (match_dup 1))
1743 (set (match_dup 2) (match_dup 3))]
1745 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1747 operands[1] = gen_lowpart (DImode, operands[2]);
1748 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1753 [(set (match_operand:DI 0 "push_operand" "")
1754 (match_operand:DI 1 "general_operand" ""))]
1755 "!TARGET_64BIT && reload_completed
1756 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1758 "ix86_split_long_move (operands); DONE;")
1760 (define_insn "*pushsi2"
1761 [(set (match_operand:SI 0 "push_operand" "=<")
1762 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1765 [(set_attr "type" "push")
1766 (set_attr "mode" "SI")])
1768 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1769 ;; "push a byte/word". But actually we use pushl, which has the effect
1770 ;; of rounding the amount pushed up to a word.
1772 ;; For TARGET_64BIT we always round up to 8 bytes.
1773 (define_insn "*push<mode>2_rex64"
1774 [(set (match_operand:SWI124 0 "push_operand" "=X")
1775 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1778 [(set_attr "type" "push")
1779 (set_attr "mode" "DI")])
1781 (define_insn "*push<mode>2"
1782 [(set (match_operand:SWI12 0 "push_operand" "=X")
1783 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1786 [(set_attr "type" "push")
1787 (set_attr "mode" "SI")])
1789 (define_insn "*push<mode>2_prologue"
1790 [(set (match_operand:P 0 "push_operand" "=<")
1791 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1792 (clobber (mem:BLK (scratch)))]
1794 "push{<imodesuffix>}\t%1"
1795 [(set_attr "type" "push")
1796 (set_attr "mode" "<MODE>")])
1798 (define_insn "*pop<mode>1"
1799 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1800 (match_operand:P 1 "pop_operand" ">"))]
1802 "pop{<imodesuffix>}\t%0"
1803 [(set_attr "type" "pop")
1804 (set_attr "mode" "<MODE>")])
1806 (define_insn "*pop<mode>1_epilogue"
1807 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1808 (match_operand:P 1 "pop_operand" ">"))
1809 (clobber (mem:BLK (scratch)))]
1811 "pop{<imodesuffix>}\t%0"
1812 [(set_attr "type" "pop")
1813 (set_attr "mode" "<MODE>")])
1815 ;; Move instructions.
1817 (define_expand "movoi"
1818 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1819 (match_operand:OI 1 "general_operand" ""))]
1821 "ix86_expand_move (OImode, operands); DONE;")
1823 (define_expand "movti"
1824 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1825 (match_operand:TI 1 "nonimmediate_operand" ""))]
1826 "TARGET_64BIT || TARGET_SSE"
1829 ix86_expand_move (TImode, operands);
1830 else if (push_operand (operands[0], TImode))
1831 ix86_expand_push (TImode, operands[1]);
1833 ix86_expand_vector_move (TImode, operands);
1837 ;; This expands to what emit_move_complex would generate if we didn't
1838 ;; have a movti pattern. Having this avoids problems with reload on
1839 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1840 ;; to have around all the time.
1841 (define_expand "movcdi"
1842 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1843 (match_operand:CDI 1 "general_operand" ""))]
1846 if (push_operand (operands[0], CDImode))
1847 emit_move_complex_push (CDImode, operands[0], operands[1]);
1849 emit_move_complex_parts (operands[0], operands[1]);
1853 (define_expand "mov<mode>"
1854 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1855 (match_operand:SWI1248x 1 "general_operand" ""))]
1857 "ix86_expand_move (<MODE>mode, operands); DONE;")
1859 (define_insn "*mov<mode>_xor"
1860 [(set (match_operand:SWI48 0 "register_operand" "=r")
1861 (match_operand:SWI48 1 "const0_operand" ""))
1862 (clobber (reg:CC FLAGS_REG))]
1865 [(set_attr "type" "alu1")
1866 (set_attr "mode" "SI")
1867 (set_attr "length_immediate" "0")])
1869 (define_insn "*mov<mode>_or"
1870 [(set (match_operand:SWI48 0 "register_operand" "=r")
1871 (match_operand:SWI48 1 "const_int_operand" ""))
1872 (clobber (reg:CC FLAGS_REG))]
1874 && operands[1] == constm1_rtx"
1875 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1876 [(set_attr "type" "alu1")
1877 (set_attr "mode" "<MODE>")
1878 (set_attr "length_immediate" "1")])
1880 (define_insn "*movoi_internal_avx"
1881 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1882 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1883 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885 switch (which_alternative)
1888 return standard_sse_constant_opcode (insn, operands[1]);
1891 if (misaligned_operand (operands[0], OImode)
1892 || misaligned_operand (operands[1], OImode))
1893 return "vmovdqu\t{%1, %0|%0, %1}";
1895 return "vmovdqa\t{%1, %0|%0, %1}";
1900 [(set_attr "type" "sselog1,ssemov,ssemov")
1901 (set_attr "prefix" "vex")
1902 (set_attr "mode" "OI")])
1904 (define_insn "*movti_internal_rex64"
1905 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1906 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1907 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1909 switch (which_alternative)
1915 return standard_sse_constant_opcode (insn, operands[1]);
1918 /* TDmode values are passed as TImode on the stack. Moving them
1919 to stack may result in unaligned memory access. */
1920 if (misaligned_operand (operands[0], TImode)
1921 || misaligned_operand (operands[1], TImode))
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vmovups\t{%1, %0|%0, %1}";
1926 return "%vmovdqu\t{%1, %0|%0, %1}";
1930 if (get_attr_mode (insn) == MODE_V4SF)
1931 return "%vmovaps\t{%1, %0|%0, %1}";
1933 return "%vmovdqa\t{%1, %0|%0, %1}";
1939 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1940 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1942 (cond [(eq_attr "alternative" "2,3")
1944 (match_test "optimize_function_for_size_p (cfun)")
1945 (const_string "V4SF")
1946 (const_string "TI"))
1947 (eq_attr "alternative" "4")
1949 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1950 (match_test "optimize_function_for_size_p (cfun)"))
1951 (const_string "V4SF")
1952 (const_string "TI"))]
1953 (const_string "DI")))])
1956 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1957 (match_operand:TI 1 "general_operand" ""))]
1959 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1961 "ix86_split_long_move (operands); DONE;")
1963 (define_insn "*movti_internal_sse"
1964 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1965 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1966 "TARGET_SSE && !TARGET_64BIT
1967 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 switch (which_alternative)
1972 return standard_sse_constant_opcode (insn, operands[1]);
1975 /* TDmode values are passed as TImode on the stack. Moving them
1976 to stack may result in unaligned memory access. */
1977 if (misaligned_operand (operands[0], TImode)
1978 || misaligned_operand (operands[1], TImode))
1980 if (get_attr_mode (insn) == MODE_V4SF)
1981 return "%vmovups\t{%1, %0|%0, %1}";
1983 return "%vmovdqu\t{%1, %0|%0, %1}";
1987 if (get_attr_mode (insn) == MODE_V4SF)
1988 return "%vmovaps\t{%1, %0|%0, %1}";
1990 return "%vmovdqa\t{%1, %0|%0, %1}";
1996 [(set_attr "type" "sselog1,ssemov,ssemov")
1997 (set_attr "prefix" "maybe_vex")
1999 (cond [(ior (not (match_test "TARGET_SSE2"))
2000 (match_test "optimize_function_for_size_p (cfun)"))
2001 (const_string "V4SF")
2002 (and (eq_attr "alternative" "2")
2003 (match_test "TARGET_SSE_TYPELESS_STORES"))
2004 (const_string "V4SF")]
2005 (const_string "TI")))])
2007 (define_insn "*movdi_internal_rex64"
2008 [(set (match_operand:DI 0 "nonimmediate_operand"
2009 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2010 (match_operand:DI 1 "general_operand"
2011 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2012 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2014 switch (get_attr_type (insn))
2017 if (SSE_REG_P (operands[0]))
2018 return "movq2dq\t{%1, %0|%0, %1}";
2020 return "movdq2q\t{%1, %0|%0, %1}";
2023 if (get_attr_mode (insn) == MODE_TI)
2024 return "%vmovdqa\t{%1, %0|%0, %1}";
2025 /* Handle broken assemblers that require movd instead of movq. */
2026 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2027 return "%vmovd\t{%1, %0|%0, %1}";
2029 return "%vmovq\t{%1, %0|%0, %1}";
2032 /* Handle broken assemblers that require movd instead of movq. */
2033 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2034 return "movd\t{%1, %0|%0, %1}";
2036 return "movq\t{%1, %0|%0, %1}";
2039 return standard_sse_constant_opcode (insn, operands[1]);
2042 return "pxor\t%0, %0";
2048 return "lea{q}\t{%a1, %0|%0, %a1}";
2051 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2052 if (get_attr_mode (insn) == MODE_SI)
2053 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2054 else if (which_alternative == 2)
2055 return "movabs{q}\t{%1, %0|%0, %1}";
2056 else if (ix86_use_lea_for_mov (insn, operands))
2057 return "lea{q}\t{%a1, %0|%0, %a1}";
2059 return "mov{q}\t{%1, %0|%0, %1}";
2063 (cond [(eq_attr "alternative" "4")
2064 (const_string "multi")
2065 (eq_attr "alternative" "5")
2066 (const_string "mmx")
2067 (eq_attr "alternative" "6,7,8,9")
2068 (const_string "mmxmov")
2069 (eq_attr "alternative" "10")
2070 (const_string "sselog1")
2071 (eq_attr "alternative" "11,12,13,14,15")
2072 (const_string "ssemov")
2073 (eq_attr "alternative" "16,17")
2074 (const_string "ssecvt")
2075 (match_operand 1 "pic_32bit_operand" "")
2076 (const_string "lea")
2078 (const_string "imov")))
2081 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2083 (const_string "*")))
2084 (set (attr "length_immediate")
2086 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2088 (const_string "*")))
2089 (set (attr "prefix_rex")
2090 (if_then_else (eq_attr "alternative" "8,9")
2092 (const_string "*")))
2093 (set (attr "prefix_data16")
2094 (if_then_else (eq_attr "alternative" "11")
2096 (const_string "*")))
2097 (set (attr "prefix")
2098 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2099 (const_string "maybe_vex")
2100 (const_string "orig")))
2101 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2103 ;; Reload patterns to support multi-word load/store
2104 ;; with non-offsetable address.
2105 (define_expand "reload_noff_store"
2106 [(parallel [(match_operand 0 "memory_operand" "=m")
2107 (match_operand 1 "register_operand" "r")
2108 (match_operand:DI 2 "register_operand" "=&r")])]
2111 rtx mem = operands[0];
2112 rtx addr = XEXP (mem, 0);
2114 emit_move_insn (operands[2], addr);
2115 mem = replace_equiv_address_nv (mem, operands[2]);
2117 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2121 (define_expand "reload_noff_load"
2122 [(parallel [(match_operand 0 "register_operand" "=r")
2123 (match_operand 1 "memory_operand" "m")
2124 (match_operand:DI 2 "register_operand" "=r")])]
2127 rtx mem = operands[1];
2128 rtx addr = XEXP (mem, 0);
2130 emit_move_insn (operands[2], addr);
2131 mem = replace_equiv_address_nv (mem, operands[2]);
2133 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2137 ;; Convert impossible stores of immediate to existing instructions.
2138 ;; First try to get scratch register and go through it. In case this
2139 ;; fails, move by 32bit parts.
2141 [(match_scratch:DI 2 "r")
2142 (set (match_operand:DI 0 "memory_operand" "")
2143 (match_operand:DI 1 "immediate_operand" ""))]
2144 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2145 && !x86_64_immediate_operand (operands[1], DImode)"
2146 [(set (match_dup 2) (match_dup 1))
2147 (set (match_dup 0) (match_dup 2))])
2149 ;; We need to define this as both peepholer and splitter for case
2150 ;; peephole2 pass is not run.
2151 ;; "&& 1" is needed to keep it from matching the previous pattern.
2153 [(set (match_operand:DI 0 "memory_operand" "")
2154 (match_operand:DI 1 "immediate_operand" ""))]
2155 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2156 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2157 [(set (match_dup 2) (match_dup 3))
2158 (set (match_dup 4) (match_dup 5))]
2159 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2162 [(set (match_operand:DI 0 "memory_operand" "")
2163 (match_operand:DI 1 "immediate_operand" ""))]
2164 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2165 ? epilogue_completed : reload_completed)
2166 && !symbolic_operand (operands[1], DImode)
2167 && !x86_64_immediate_operand (operands[1], DImode)"
2168 [(set (match_dup 2) (match_dup 3))
2169 (set (match_dup 4) (match_dup 5))]
2170 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2172 (define_insn "*movdi_internal"
2173 [(set (match_operand:DI 0 "nonimmediate_operand"
2174 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2175 (match_operand:DI 1 "general_operand"
2176 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2177 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2179 switch (get_attr_type (insn))
2182 if (SSE_REG_P (operands[0]))
2183 return "movq2dq\t{%1, %0|%0, %1}";
2185 return "movdq2q\t{%1, %0|%0, %1}";
2188 switch (get_attr_mode (insn))
2191 return "%vmovdqa\t{%1, %0|%0, %1}";
2193 return "%vmovq\t{%1, %0|%0, %1}";
2195 return "movaps\t{%1, %0|%0, %1}";
2197 return "movlps\t{%1, %0|%0, %1}";
2203 return "movq\t{%1, %0|%0, %1}";
2206 return standard_sse_constant_opcode (insn, operands[1]);
2209 return "pxor\t%0, %0";
2219 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2220 (const_string "sse2")
2221 (eq_attr "alternative" "9,10,11,12")
2222 (const_string "noavx")
2224 (const_string "*")))
2226 (cond [(eq_attr "alternative" "0,1")
2227 (const_string "multi")
2228 (eq_attr "alternative" "2")
2229 (const_string "mmx")
2230 (eq_attr "alternative" "3,4")
2231 (const_string "mmxmov")
2232 (eq_attr "alternative" "5,9")
2233 (const_string "sselog1")
2234 (eq_attr "alternative" "13,14")
2235 (const_string "ssecvt")
2237 (const_string "ssemov")))
2238 (set (attr "prefix")
2239 (if_then_else (eq_attr "alternative" "5,6,7,8")
2240 (const_string "maybe_vex")
2241 (const_string "orig")))
2242 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2245 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2246 (match_operand:DI 1 "general_operand" ""))]
2247 "!TARGET_64BIT && reload_completed
2248 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2249 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2251 "ix86_split_long_move (operands); DONE;")
2253 (define_insn "*movsi_internal"
2254 [(set (match_operand:SI 0 "nonimmediate_operand"
2255 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2256 (match_operand:SI 1 "general_operand"
2257 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2258 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2260 switch (get_attr_type (insn))
2263 return standard_sse_constant_opcode (insn, operands[1]);
2266 switch (get_attr_mode (insn))
2269 return "%vmovdqa\t{%1, %0|%0, %1}";
2271 return "%vmovaps\t{%1, %0|%0, %1}";
2273 return "%vmovd\t{%1, %0|%0, %1}";
2275 return "%vmovss\t{%1, %0|%0, %1}";
2281 return "pxor\t%0, %0";
2284 if (get_attr_mode (insn) == MODE_DI)
2285 return "movq\t{%1, %0|%0, %1}";
2286 return "movd\t{%1, %0|%0, %1}";
2289 return "lea{l}\t{%a1, %0|%0, %a1}";
2292 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2293 if (ix86_use_lea_for_mov (insn, operands))
2294 return "lea{l}\t{%a1, %0|%0, %a1}";
2296 return "mov{l}\t{%1, %0|%0, %1}";
2300 (cond [(eq_attr "alternative" "2")
2301 (const_string "mmx")
2302 (eq_attr "alternative" "3,4,5")
2303 (const_string "mmxmov")
2304 (eq_attr "alternative" "6")
2305 (const_string "sselog1")
2306 (eq_attr "alternative" "7,8,9,10,11")
2307 (const_string "ssemov")
2308 (match_operand 1 "pic_32bit_operand" "")
2309 (const_string "lea")
2311 (const_string "imov")))
2312 (set (attr "prefix")
2313 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2314 (const_string "orig")
2315 (const_string "maybe_vex")))
2316 (set (attr "prefix_data16")
2317 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2319 (const_string "*")))
2321 (cond [(eq_attr "alternative" "2,3")
2323 (eq_attr "alternative" "6,7")
2325 (not (match_test "TARGET_SSE2"))
2326 (const_string "V4SF")
2327 (const_string "TI"))
2328 (and (eq_attr "alternative" "8,9,10,11")
2329 (not (match_test "TARGET_SSE2")))
2332 (const_string "SI")))])
2334 (define_insn "*movhi_internal"
2335 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2336 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2337 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2339 switch (get_attr_type (insn))
2342 /* movzwl is faster than movw on p2 due to partial word stalls,
2343 though not as fast as an aligned movl. */
2344 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2346 if (get_attr_mode (insn) == MODE_SI)
2347 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2349 return "mov{w}\t{%1, %0|%0, %1}";
2353 (cond [(match_test "optimize_function_for_size_p (cfun)")
2354 (const_string "imov")
2355 (and (eq_attr "alternative" "0")
2356 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2357 (not (match_test "TARGET_HIMODE_MATH"))))
2358 (const_string "imov")
2359 (and (eq_attr "alternative" "1,2")
2360 (match_operand:HI 1 "aligned_operand" ""))
2361 (const_string "imov")
2362 (and (match_test "TARGET_MOVX")
2363 (eq_attr "alternative" "0,2"))
2364 (const_string "imovx")
2366 (const_string "imov")))
2368 (cond [(eq_attr "type" "imovx")
2370 (and (eq_attr "alternative" "1,2")
2371 (match_operand:HI 1 "aligned_operand" ""))
2373 (and (eq_attr "alternative" "0")
2374 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2375 (not (match_test "TARGET_HIMODE_MATH"))))
2378 (const_string "HI")))])
2380 ;; Situation is quite tricky about when to choose full sized (SImode) move
2381 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2382 ;; partial register dependency machines (such as AMD Athlon), where QImode
2383 ;; moves issue extra dependency and for partial register stalls machines
2384 ;; that don't use QImode patterns (and QImode move cause stall on the next
2387 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2388 ;; register stall machines with, where we use QImode instructions, since
2389 ;; partial register stall can be caused there. Then we use movzx.
2390 (define_insn "*movqi_internal"
2391 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2392 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2393 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2395 switch (get_attr_type (insn))
2398 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2399 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2401 if (get_attr_mode (insn) == MODE_SI)
2402 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2404 return "mov{b}\t{%1, %0|%0, %1}";
2408 (cond [(and (eq_attr "alternative" "5")
2409 (not (match_operand:QI 1 "aligned_operand" "")))
2410 (const_string "imovx")
2411 (match_test "optimize_function_for_size_p (cfun)")
2412 (const_string "imov")
2413 (and (eq_attr "alternative" "3")
2414 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2415 (not (match_test "TARGET_QIMODE_MATH"))))
2416 (const_string "imov")
2417 (eq_attr "alternative" "3,5")
2418 (const_string "imovx")
2419 (and (match_test "TARGET_MOVX")
2420 (eq_attr "alternative" "2"))
2421 (const_string "imovx")
2423 (const_string "imov")))
2425 (cond [(eq_attr "alternative" "3,4,5")
2427 (eq_attr "alternative" "6")
2429 (eq_attr "type" "imovx")
2431 (and (eq_attr "type" "imov")
2432 (and (eq_attr "alternative" "0,1")
2433 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2434 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2435 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2437 ;; Avoid partial register stalls when not using QImode arithmetic
2438 (and (eq_attr "type" "imov")
2439 (and (eq_attr "alternative" "0,1")
2440 (and (match_test "TARGET_PARTIAL_REG_STALL")
2441 (not (match_test "TARGET_QIMODE_MATH")))))
2444 (const_string "QI")))])
2446 ;; Stores and loads of ax to arbitrary constant address.
2447 ;; We fake an second form of instruction to force reload to load address
2448 ;; into register when rax is not available
2449 (define_insn "*movabs<mode>_1"
2450 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2451 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2452 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2454 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2455 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2456 [(set_attr "type" "imov")
2457 (set_attr "modrm" "0,*")
2458 (set_attr "length_address" "8,0")
2459 (set_attr "length_immediate" "0,*")
2460 (set_attr "memory" "store")
2461 (set_attr "mode" "<MODE>")])
2463 (define_insn "*movabs<mode>_2"
2464 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2465 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2466 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2468 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2469 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2470 [(set_attr "type" "imov")
2471 (set_attr "modrm" "0,*")
2472 (set_attr "length_address" "8,0")
2473 (set_attr "length_immediate" "0")
2474 (set_attr "memory" "load")
2475 (set_attr "mode" "<MODE>")])
2477 (define_insn "*swap<mode>"
2478 [(set (match_operand:SWI48 0 "register_operand" "+r")
2479 (match_operand:SWI48 1 "register_operand" "+r"))
2483 "xchg{<imodesuffix>}\t%1, %0"
2484 [(set_attr "type" "imov")
2485 (set_attr "mode" "<MODE>")
2486 (set_attr "pent_pair" "np")
2487 (set_attr "athlon_decode" "vector")
2488 (set_attr "amdfam10_decode" "double")
2489 (set_attr "bdver1_decode" "double")])
2491 (define_insn "*swap<mode>_1"
2492 [(set (match_operand:SWI12 0 "register_operand" "+r")
2493 (match_operand:SWI12 1 "register_operand" "+r"))
2496 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2498 [(set_attr "type" "imov")
2499 (set_attr "mode" "SI")
2500 (set_attr "pent_pair" "np")
2501 (set_attr "athlon_decode" "vector")
2502 (set_attr "amdfam10_decode" "double")
2503 (set_attr "bdver1_decode" "double")])
2505 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2506 ;; is disabled for AMDFAM10
2507 (define_insn "*swap<mode>_2"
2508 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2509 (match_operand:SWI12 1 "register_operand" "+<r>"))
2512 "TARGET_PARTIAL_REG_STALL"
2513 "xchg{<imodesuffix>}\t%1, %0"
2514 [(set_attr "type" "imov")
2515 (set_attr "mode" "<MODE>")
2516 (set_attr "pent_pair" "np")
2517 (set_attr "athlon_decode" "vector")])
2519 (define_expand "movstrict<mode>"
2520 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2521 (match_operand:SWI12 1 "general_operand" ""))]
2524 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2526 if (GET_CODE (operands[0]) == SUBREG
2527 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2529 /* Don't generate memory->memory moves, go through a register */
2530 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2531 operands[1] = force_reg (<MODE>mode, operands[1]);
2534 (define_insn "*movstrict<mode>_1"
2535 [(set (strict_low_part
2536 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2537 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2538 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2540 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2541 [(set_attr "type" "imov")
2542 (set_attr "mode" "<MODE>")])
2544 (define_insn "*movstrict<mode>_xor"
2545 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2546 (match_operand:SWI12 1 "const0_operand" ""))
2547 (clobber (reg:CC FLAGS_REG))]
2549 "xor{<imodesuffix>}\t%0, %0"
2550 [(set_attr "type" "alu1")
2551 (set_attr "mode" "<MODE>")
2552 (set_attr "length_immediate" "0")])
2554 (define_insn "*mov<mode>_extv_1"
2555 [(set (match_operand:SWI24 0 "register_operand" "=R")
2556 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2560 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2561 [(set_attr "type" "imovx")
2562 (set_attr "mode" "SI")])
2564 (define_insn "*movqi_extv_1_rex64"
2565 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2566 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2571 switch (get_attr_type (insn))
2574 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2576 return "mov{b}\t{%h1, %0|%0, %h1}";
2580 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2581 (match_test "TARGET_MOVX"))
2582 (const_string "imovx")
2583 (const_string "imov")))
2585 (if_then_else (eq_attr "type" "imovx")
2587 (const_string "QI")))])
2589 (define_insn "*movqi_extv_1"
2590 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2591 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2596 switch (get_attr_type (insn))
2599 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2601 return "mov{b}\t{%h1, %0|%0, %h1}";
2605 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2606 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2607 (match_test "TARGET_MOVX")))
2608 (const_string "imovx")
2609 (const_string "imov")))
2611 (if_then_else (eq_attr "type" "imovx")
2613 (const_string "QI")))])
2615 (define_insn "*mov<mode>_extzv_1"
2616 [(set (match_operand:SWI48 0 "register_operand" "=R")
2617 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2621 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2622 [(set_attr "type" "imovx")
2623 (set_attr "mode" "SI")])
2625 (define_insn "*movqi_extzv_2_rex64"
2626 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2628 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2633 switch (get_attr_type (insn))
2636 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2638 return "mov{b}\t{%h1, %0|%0, %h1}";
2642 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2643 (match_test "TARGET_MOVX"))
2644 (const_string "imovx")
2645 (const_string "imov")))
2647 (if_then_else (eq_attr "type" "imovx")
2649 (const_string "QI")))])
2651 (define_insn "*movqi_extzv_2"
2652 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2654 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2659 switch (get_attr_type (insn))
2662 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2664 return "mov{b}\t{%h1, %0|%0, %h1}";
2668 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2669 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2670 (match_test "TARGET_MOVX")))
2671 (const_string "imovx")
2672 (const_string "imov")))
2674 (if_then_else (eq_attr "type" "imovx")
2676 (const_string "QI")))])
2678 (define_expand "mov<mode>_insv_1"
2679 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2682 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2684 (define_insn "*mov<mode>_insv_1_rex64"
2685 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2688 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2690 "mov{b}\t{%b1, %h0|%h0, %b1}"
2691 [(set_attr "type" "imov")
2692 (set_attr "mode" "QI")])
2694 (define_insn "*movsi_insv_1"
2695 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2698 (match_operand:SI 1 "general_operand" "Qmn"))]
2700 "mov{b}\t{%b1, %h0|%h0, %b1}"
2701 [(set_attr "type" "imov")
2702 (set_attr "mode" "QI")])
2704 (define_insn "*movqi_insv_2"
2705 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2708 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2711 "mov{b}\t{%h1, %h0|%h0, %h1}"
2712 [(set_attr "type" "imov")
2713 (set_attr "mode" "QI")])
2715 ;; Floating point push instructions.
2717 (define_insn "*pushtf"
2718 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2719 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2722 /* This insn should be already split before reg-stack. */
2725 [(set_attr "type" "multi")
2726 (set_attr "unit" "sse,*,*")
2727 (set_attr "mode" "TF,SI,SI")])
2729 ;; %%% Kill this when call knows how to work this out.
2731 [(set (match_operand:TF 0 "push_operand" "")
2732 (match_operand:TF 1 "sse_reg_operand" ""))]
2733 "TARGET_SSE2 && reload_completed"
2734 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2735 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2737 (define_insn "*pushxf"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740 "optimize_function_for_speed_p (cfun)"
2742 /* This insn should be already split before reg-stack. */
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2749 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2750 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2751 ;; Pushing using integer instructions is longer except for constants
2752 ;; and direct memory references (assuming that any given constant is pushed
2753 ;; only once, but this ought to be handled elsewhere).
2755 (define_insn "*pushxf_nointeger"
2756 [(set (match_operand:XF 0 "push_operand" "=<,<")
2757 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2758 "optimize_function_for_size_p (cfun)"
2760 /* This insn should be already split before reg-stack. */
2763 [(set_attr "type" "multi")
2764 (set_attr "unit" "i387,*")
2765 (set_attr "mode" "XF,SI")])
2767 ;; %%% Kill this when call knows how to work this out.
2769 [(set (match_operand:XF 0 "push_operand" "")
2770 (match_operand:XF 1 "fp_register_operand" ""))]
2772 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2773 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2774 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2776 (define_insn "*pushdf_rex64"
2777 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2778 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2781 /* This insn should be already split before reg-stack. */
2784 [(set_attr "type" "multi")
2785 (set_attr "unit" "i387,*,*")
2786 (set_attr "mode" "DF,DI,DF")])
2788 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2789 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2790 ;; On the average, pushdf using integers can be still shorter.
2792 (define_insn "*pushdf"
2793 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2794 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2797 /* This insn should be already split before reg-stack. */
2800 [(set_attr "isa" "*,*,sse2")
2801 (set_attr "type" "multi")
2802 (set_attr "unit" "i387,*,*")
2803 (set_attr "mode" "DF,DI,DF")])
2805 ;; %%% Kill this when call knows how to work this out.
2807 [(set (match_operand:DF 0 "push_operand" "")
2808 (match_operand:DF 1 "any_fp_register_operand" ""))]
2810 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2811 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2813 (define_insn "*pushsf_rex64"
2814 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2815 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2818 /* Anything else should be already split before reg-stack. */
2819 gcc_assert (which_alternative == 1);
2820 return "push{q}\t%q1";
2822 [(set_attr "type" "multi,push,multi")
2823 (set_attr "unit" "i387,*,*")
2824 (set_attr "mode" "SF,DI,SF")])
2826 (define_insn "*pushsf"
2827 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2828 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2831 /* Anything else should be already split before reg-stack. */
2832 gcc_assert (which_alternative == 1);
2833 return "push{l}\t%1";
2835 [(set_attr "type" "multi,push,multi")
2836 (set_attr "unit" "i387,*,*")
2837 (set_attr "mode" "SF,SI,SF")])
2839 ;; %%% Kill this when call knows how to work this out.
2841 [(set (match_operand:SF 0 "push_operand" "")
2842 (match_operand:SF 1 "any_fp_register_operand" ""))]
2844 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2845 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2846 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2849 [(set (match_operand:SF 0 "push_operand" "")
2850 (match_operand:SF 1 "memory_operand" ""))]
2852 && (operands[2] = find_constant_src (insn))"
2853 [(set (match_dup 0) (match_dup 2))])
2856 [(set (match_operand 0 "push_operand" "")
2857 (match_operand 1 "general_operand" ""))]
2859 && (GET_MODE (operands[0]) == TFmode
2860 || GET_MODE (operands[0]) == XFmode
2861 || GET_MODE (operands[0]) == DFmode)
2862 && !ANY_FP_REG_P (operands[1])"
2864 "ix86_split_long_move (operands); DONE;")
2866 ;; Floating point move instructions.
2868 (define_expand "movtf"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2870 (match_operand:TF 1 "nonimmediate_operand" ""))]
2873 ix86_expand_move (TFmode, operands);
2877 (define_expand "mov<mode>"
2878 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2879 (match_operand:X87MODEF 1 "general_operand" ""))]
2881 "ix86_expand_move (<MODE>mode, operands); DONE;")
2883 (define_insn "*movtf_internal"
2884 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2885 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2887 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888 && (!can_create_pseudo_p ()
2889 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890 || GET_CODE (operands[1]) != CONST_DOUBLE
2891 || (optimize_function_for_size_p (cfun)
2892 && standard_sse_constant_p (operands[1])
2893 && !memory_operand (operands[0], TFmode))
2894 || (!TARGET_MEMORY_MISMATCH_STALL
2895 && memory_operand (operands[0], TFmode)))"
2897 switch (which_alternative)
2901 /* Handle misaligned load/store since we
2902 don't have movmisaligntf pattern. */
2903 if (misaligned_operand (operands[0], TFmode)
2904 || misaligned_operand (operands[1], TFmode))
2906 if (get_attr_mode (insn) == MODE_V4SF)
2907 return "%vmovups\t{%1, %0|%0, %1}";
2909 return "%vmovdqu\t{%1, %0|%0, %1}";
2913 if (get_attr_mode (insn) == MODE_V4SF)
2914 return "%vmovaps\t{%1, %0|%0, %1}";
2916 return "%vmovdqa\t{%1, %0|%0, %1}";
2920 return standard_sse_constant_opcode (insn, operands[1]);
2930 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2931 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2933 (cond [(eq_attr "alternative" "0,2")
2935 (match_test "optimize_function_for_size_p (cfun)")
2936 (const_string "V4SF")
2937 (const_string "TI"))
2938 (eq_attr "alternative" "1")
2940 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2941 (match_test "optimize_function_for_size_p (cfun)"))
2942 (const_string "V4SF")
2943 (const_string "TI"))]
2944 (const_string "DI")))])
2946 ;; Possible store forwarding (partial memory) stall in alternative 4.
2947 (define_insn "*movxf_internal"
2948 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2949 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2950 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2951 && (!can_create_pseudo_p ()
2952 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2953 || GET_CODE (operands[1]) != CONST_DOUBLE
2954 || (optimize_function_for_size_p (cfun)
2955 && standard_80387_constant_p (operands[1]) > 0
2956 && !memory_operand (operands[0], XFmode))
2957 || (!TARGET_MEMORY_MISMATCH_STALL
2958 && memory_operand (operands[0], XFmode)))"
2960 switch (which_alternative)
2964 return output_387_reg_move (insn, operands);
2967 return standard_80387_constant_opcode (operands[1]);
2977 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2978 (set_attr "mode" "XF,XF,XF,SI,SI")])
2980 (define_insn "*movdf_internal_rex64"
2981 [(set (match_operand:DF 0 "nonimmediate_operand"
2982 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2983 (match_operand:DF 1 "general_operand"
2984 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2985 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2986 && (!can_create_pseudo_p ()
2987 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2988 || GET_CODE (operands[1]) != CONST_DOUBLE
2989 || (optimize_function_for_size_p (cfun)
2990 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2991 && standard_80387_constant_p (operands[1]) > 0)
2992 || (TARGET_SSE2 && TARGET_SSE_MATH
2993 && standard_sse_constant_p (operands[1]))))
2994 || memory_operand (operands[0], DFmode))"
2996 switch (which_alternative)
3000 return output_387_reg_move (insn, operands);
3003 return standard_80387_constant_opcode (operands[1]);
3007 return "mov{q}\t{%1, %0|%0, %1}";
3010 return "movabs{q}\t{%1, %0|%0, %1}";
3016 return standard_sse_constant_opcode (insn, operands[1]);
3021 switch (get_attr_mode (insn))
3024 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3025 return "%vmovapd\t{%1, %0|%0, %1}";
3027 return "%vmovaps\t{%1, %0|%0, %1}";
3030 return "%vmovq\t{%1, %0|%0, %1}";
3032 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3033 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3034 return "%vmovsd\t{%1, %0|%0, %1}";
3036 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3038 return "%vmovlps\t{%1, %d0|%d0, %1}";
3045 /* Handle broken assemblers that require movd instead of movq. */
3046 return "%vmovd\t{%1, %0|%0, %1}";
3053 (cond [(eq_attr "alternative" "0,1,2")
3054 (const_string "fmov")
3055 (eq_attr "alternative" "3,4,5")
3056 (const_string "imov")
3057 (eq_attr "alternative" "6")
3058 (const_string "multi")
3059 (eq_attr "alternative" "7")
3060 (const_string "sselog1")
3062 (const_string "ssemov")))
3065 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3067 (const_string "*")))
3068 (set (attr "length_immediate")
3070 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3072 (const_string "*")))
3073 (set (attr "prefix")
3074 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3075 (const_string "orig")
3076 (const_string "maybe_vex")))
3077 (set (attr "prefix_data16")
3078 (if_then_else (eq_attr "mode" "V1DF")
3080 (const_string "*")))
3082 (cond [(eq_attr "alternative" "0,1,2")
3084 (eq_attr "alternative" "3,4,5,6,11,12")
3087 /* xorps is one byte shorter. */
3088 (eq_attr "alternative" "7")
3089 (cond [(match_test "optimize_function_for_size_p (cfun)")
3090 (const_string "V4SF")
3091 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3094 (const_string "V2DF"))
3096 /* For architectures resolving dependencies on
3097 whole SSE registers use APD move to break dependency
3098 chains, otherwise use short move to avoid extra work.
3100 movaps encodes one byte shorter. */
3101 (eq_attr "alternative" "8")
3103 [(match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "V4SF")
3105 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3106 (const_string "V2DF")
3108 (const_string "DF"))
3109 /* For architectures resolving dependencies on register
3110 parts we may avoid extra work to zero out upper part
3112 (eq_attr "alternative" "9")
3114 (match_test "TARGET_SSE_SPLIT_REGS")
3115 (const_string "V1DF")
3116 (const_string "DF"))
3118 (const_string "DF")))])
3120 ;; Possible store forwarding (partial memory) stall in alternative 4.
3121 (define_insn "*movdf_internal"
3122 [(set (match_operand:DF 0 "nonimmediate_operand"
3123 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3124 (match_operand:DF 1 "general_operand"
3125 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3126 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3127 && (!can_create_pseudo_p ()
3128 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3129 || GET_CODE (operands[1]) != CONST_DOUBLE
3130 || (optimize_function_for_size_p (cfun)
3131 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3132 && standard_80387_constant_p (operands[1]) > 0)
3133 || (TARGET_SSE2 && TARGET_SSE_MATH
3134 && standard_sse_constant_p (operands[1])))
3135 && !memory_operand (operands[0], DFmode))
3136 || (!TARGET_MEMORY_MISMATCH_STALL
3137 && memory_operand (operands[0], DFmode)))"
3139 switch (which_alternative)
3143 return output_387_reg_move (insn, operands);
3146 return standard_80387_constant_opcode (operands[1]);
3154 return standard_sse_constant_opcode (insn, operands[1]);
3162 switch (get_attr_mode (insn))
3165 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3166 return "%vmovapd\t{%1, %0|%0, %1}";
3168 return "%vmovaps\t{%1, %0|%0, %1}";
3171 return "%vmovq\t{%1, %0|%0, %1}";
3173 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3174 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3175 return "%vmovsd\t{%1, %0|%0, %1}";
3177 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3179 return "%vmovlps\t{%1, %d0|%d0, %1}";
3189 (if_then_else (eq_attr "alternative" "5,6,7,8")
3190 (const_string "sse2")
3191 (const_string "*")))
3193 (cond [(eq_attr "alternative" "0,1,2")
3194 (const_string "fmov")
3195 (eq_attr "alternative" "3,4")
3196 (const_string "multi")
3197 (eq_attr "alternative" "5,9")
3198 (const_string "sselog1")
3200 (const_string "ssemov")))
3201 (set (attr "prefix")
3202 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3203 (const_string "orig")
3204 (const_string "maybe_vex")))
3205 (set (attr "prefix_data16")
3206 (if_then_else (eq_attr "mode" "V1DF")
3208 (const_string "*")))
3210 (cond [(eq_attr "alternative" "0,1,2")
3212 (eq_attr "alternative" "3,4")
3215 /* For SSE1, we have many fewer alternatives. */
3216 (not (match_test "TARGET_SSE2"))
3218 (eq_attr "alternative" "5,6,9,10")
3219 (const_string "V4SF")
3220 (const_string "V2SF"))
3222 /* xorps is one byte shorter. */
3223 (eq_attr "alternative" "5,9")
3224 (cond [(match_test "optimize_function_for_size_p (cfun)")
3225 (const_string "V4SF")
3226 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3229 (const_string "V2DF"))
3231 /* For architectures resolving dependencies on
3232 whole SSE registers use APD move to break dependency
3233 chains, otherwise use short move to avoid extra work.
3235 movaps encodes one byte shorter. */
3236 (eq_attr "alternative" "6,10")
3238 [(match_test "optimize_function_for_size_p (cfun)")
3239 (const_string "V4SF")
3240 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3241 (const_string "V2DF")
3243 (const_string "DF"))
3244 /* For architectures resolving dependencies on register
3245 parts we may avoid extra work to zero out upper part
3247 (eq_attr "alternative" "7,11")
3249 (match_test "TARGET_SSE_SPLIT_REGS")
3250 (const_string "V1DF")
3251 (const_string "DF"))
3253 (const_string "DF")))])
3255 (define_insn "*movsf_internal"
3256 [(set (match_operand:SF 0 "nonimmediate_operand"
3257 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3258 (match_operand:SF 1 "general_operand"
3259 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3260 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3261 && (!can_create_pseudo_p ()
3262 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3263 || GET_CODE (operands[1]) != CONST_DOUBLE
3264 || (optimize_function_for_size_p (cfun)
3265 && ((!TARGET_SSE_MATH
3266 && standard_80387_constant_p (operands[1]) > 0)
3268 && standard_sse_constant_p (operands[1]))))
3269 || memory_operand (operands[0], SFmode))"
3271 switch (which_alternative)
3275 return output_387_reg_move (insn, operands);
3278 return standard_80387_constant_opcode (operands[1]);
3282 return "mov{l}\t{%1, %0|%0, %1}";
3285 return standard_sse_constant_opcode (insn, operands[1]);
3288 if (get_attr_mode (insn) == MODE_V4SF)
3289 return "%vmovaps\t{%1, %0|%0, %1}";
3291 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3295 return "%vmovss\t{%1, %0|%0, %1}";
3301 return "movd\t{%1, %0|%0, %1}";
3304 return "movq\t{%1, %0|%0, %1}";
3308 return "%vmovd\t{%1, %0|%0, %1}";
3315 (cond [(eq_attr "alternative" "0,1,2")
3316 (const_string "fmov")
3317 (eq_attr "alternative" "3,4")
3318 (const_string "multi")
3319 (eq_attr "alternative" "5")
3320 (const_string "sselog1")
3321 (eq_attr "alternative" "9,10,11,14,15")
3322 (const_string "mmxmov")
3324 (const_string "ssemov")))
3325 (set (attr "prefix")
3326 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3327 (const_string "maybe_vex")
3328 (const_string "orig")))
3330 (cond [(eq_attr "alternative" "3,4,9,10")
3332 (eq_attr "alternative" "5")
3334 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3335 (match_test "TARGET_SSE2"))
3336 (not (match_test "optimize_function_for_size_p (cfun)")))
3338 (const_string "V4SF"))
3339 /* For architectures resolving dependencies on
3340 whole SSE registers use APS move to break dependency
3341 chains, otherwise use short move to avoid extra work.
3343 Do the same for architectures resolving dependencies on
3344 the parts. While in DF mode it is better to always handle
3345 just register parts, the SF mode is different due to lack
3346 of instructions to load just part of the register. It is
3347 better to maintain the whole registers in single format
3348 to avoid problems on using packed logical operations. */
3349 (eq_attr "alternative" "6")
3351 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3352 (match_test "TARGET_SSE_SPLIT_REGS"))
3353 (const_string "V4SF")
3354 (const_string "SF"))
3355 (eq_attr "alternative" "11")
3356 (const_string "DI")]
3357 (const_string "SF")))])
3360 [(set (match_operand 0 "any_fp_register_operand" "")
3361 (match_operand 1 "memory_operand" ""))]
3363 && (GET_MODE (operands[0]) == TFmode
3364 || GET_MODE (operands[0]) == XFmode
3365 || GET_MODE (operands[0]) == DFmode
3366 || GET_MODE (operands[0]) == SFmode)
3367 && (operands[2] = find_constant_src (insn))"
3368 [(set (match_dup 0) (match_dup 2))]
3370 rtx c = operands[2];
3371 int r = REGNO (operands[0]);
3373 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3374 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3379 [(set (match_operand 0 "any_fp_register_operand" "")
3380 (float_extend (match_operand 1 "memory_operand" "")))]
3382 && (GET_MODE (operands[0]) == TFmode
3383 || GET_MODE (operands[0]) == XFmode
3384 || GET_MODE (operands[0]) == DFmode)
3385 && (operands[2] = find_constant_src (insn))"
3386 [(set (match_dup 0) (match_dup 2))]
3388 rtx c = operands[2];
3389 int r = REGNO (operands[0]);
3391 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3392 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3396 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3398 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3399 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3401 && (standard_80387_constant_p (operands[1]) == 8
3402 || standard_80387_constant_p (operands[1]) == 9)"
3403 [(set (match_dup 0)(match_dup 1))
3405 (neg:X87MODEF (match_dup 0)))]
3409 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3410 if (real_isnegzero (&r))
3411 operands[1] = CONST0_RTX (<MODE>mode);
3413 operands[1] = CONST1_RTX (<MODE>mode);
3417 [(set (match_operand 0 "nonimmediate_operand" "")
3418 (match_operand 1 "general_operand" ""))]
3420 && (GET_MODE (operands[0]) == TFmode
3421 || GET_MODE (operands[0]) == XFmode
3422 || GET_MODE (operands[0]) == DFmode)
3423 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3425 "ix86_split_long_move (operands); DONE;")
3427 (define_insn "swapxf"
3428 [(set (match_operand:XF 0 "register_operand" "+f")
3429 (match_operand:XF 1 "register_operand" "+f"))
3434 if (STACK_TOP_P (operands[0]))
3439 [(set_attr "type" "fxch")
3440 (set_attr "mode" "XF")])
3442 (define_insn "*swap<mode>"
3443 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3444 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3447 "TARGET_80387 || reload_completed"
3449 if (STACK_TOP_P (operands[0]))
3454 [(set_attr "type" "fxch")
3455 (set_attr "mode" "<MODE>")])
3457 ;; Zero extension instructions
3459 (define_expand "zero_extendsidi2"
3460 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3461 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3466 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3471 (define_insn "*zero_extendsidi2_rex64"
3472 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3474 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3477 mov\t{%k1, %k0|%k0, %k1}
3479 movd\t{%1, %0|%0, %1}
3480 movd\t{%1, %0|%0, %1}
3481 %vmovd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}"
3483 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3484 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3485 (set_attr "prefix_0f" "0,*,*,*,*,*")
3486 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3489 [(set (match_operand:DI 0 "memory_operand" "")
3490 (zero_extend:DI (match_dup 0)))]
3492 [(set (match_dup 4) (const_int 0))]
3493 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3495 ;; %%% Kill me once multi-word ops are sane.
3496 (define_insn "zero_extendsidi2_1"
3497 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3499 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3500 (clobber (reg:CC FLAGS_REG))]
3506 movd\t{%1, %0|%0, %1}
3507 movd\t{%1, %0|%0, %1}
3508 %vmovd\t{%1, %0|%0, %1}
3509 %vmovd\t{%1, %0|%0, %1}"
3510 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3511 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3512 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3513 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3516 [(set (match_operand:DI 0 "register_operand" "")
3517 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3518 (clobber (reg:CC FLAGS_REG))]
3519 "!TARGET_64BIT && reload_completed
3520 && true_regnum (operands[0]) == true_regnum (operands[1])"
3521 [(set (match_dup 4) (const_int 0))]
3522 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3525 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3526 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_64BIT && reload_completed
3529 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3530 [(set (match_dup 3) (match_dup 1))
3531 (set (match_dup 4) (const_int 0))]
3532 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3534 (define_insn "zero_extend<mode>di2"
3535 [(set (match_operand:DI 0 "register_operand" "=r")
3537 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3540 [(set_attr "type" "imovx")
3541 (set_attr "mode" "SI")])
3543 (define_expand "zero_extendhisi2"
3544 [(set (match_operand:SI 0 "register_operand" "")
3545 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3548 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 operands[1] = force_reg (HImode, operands[1]);
3551 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3556 (define_insn_and_split "zero_extendhisi2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3558 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3562 "&& reload_completed"
3563 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3564 (clobber (reg:CC FLAGS_REG))])]
3566 [(set_attr "type" "alu1")
3567 (set_attr "mode" "SI")])
3569 (define_insn "*zero_extendhisi2_movzwl"
3570 [(set (match_operand:SI 0 "register_operand" "=r")
3571 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3572 "!TARGET_ZERO_EXTEND_WITH_AND
3573 || optimize_function_for_size_p (cfun)"
3574 "movz{wl|x}\t{%1, %0|%0, %1}"
3575 [(set_attr "type" "imovx")
3576 (set_attr "mode" "SI")])
3578 (define_expand "zero_extendqi<mode>2"
3580 [(set (match_operand:SWI24 0 "register_operand" "")
3581 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3582 (clobber (reg:CC FLAGS_REG))])])
3584 (define_insn "*zero_extendqi<mode>2_and"
3585 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3586 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3587 (clobber (reg:CC FLAGS_REG))]
3588 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3590 [(set_attr "type" "alu1")
3591 (set_attr "mode" "<MODE>")])
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3596 [(set (match_operand:SWI24 0 "register_operand" "")
3597 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC FLAGS_REG))]
3600 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3601 && ANY_QI_REG_P (operands[0])
3602 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3603 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3606 operands[2] = gen_lowpart (QImode, operands[0]);
3607 ix86_expand_clear (operands[0]);
3610 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3611 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3612 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3613 (clobber (reg:CC FLAGS_REG))]
3614 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3616 [(set_attr "type" "imovx,alu1")
3617 (set_attr "mode" "<MODE>")])
3619 ;; For the movzbl case strip only the clobber
3621 [(set (match_operand:SWI24 0 "register_operand" "")
3622 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3623 (clobber (reg:CC FLAGS_REG))]
3625 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3626 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3628 (zero_extend:SWI24 (match_dup 1)))])
3630 ; zero extend to SImode to avoid partial register stalls
3631 (define_insn "*zero_extendqi<mode>2_movzbl"
3632 [(set (match_operand:SWI24 0 "register_operand" "=r")
3633 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3635 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3636 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3637 [(set_attr "type" "imovx")
3638 (set_attr "mode" "SI")])
3640 ;; Rest is handled by single and.
3642 [(set (match_operand:SWI24 0 "register_operand" "")
3643 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3644 (clobber (reg:CC FLAGS_REG))]
3646 && true_regnum (operands[0]) == true_regnum (operands[1])"
3647 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3648 (clobber (reg:CC FLAGS_REG))])])
3650 ;; Sign extension instructions
3652 (define_expand "extendsidi2"
3653 [(set (match_operand:DI 0 "register_operand" "")
3654 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3659 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3664 (define_insn "*extendsidi2_rex64"
3665 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3670 movs{lq|x}\t{%1, %0|%0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "DI")
3673 (set_attr "prefix_0f" "0")
3674 (set_attr "modrm" "0,1")])
3676 (define_insn "extendsidi2_1"
3677 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3678 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3679 (clobber (reg:CC FLAGS_REG))
3680 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3684 ;; Extend to memory case when source register does die.
3686 [(set (match_operand:DI 0 "memory_operand" "")
3687 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3688 (clobber (reg:CC FLAGS_REG))
3689 (clobber (match_operand:SI 2 "register_operand" ""))]
3691 && dead_or_set_p (insn, operands[1])
3692 && !reg_mentioned_p (operands[1], operands[0]))"
3693 [(set (match_dup 3) (match_dup 1))
3694 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3695 (clobber (reg:CC FLAGS_REG))])
3696 (set (match_dup 4) (match_dup 1))]
3697 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3699 ;; Extend to memory case when source register does not die.
3701 [(set (match_operand:DI 0 "memory_operand" "")
3702 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))
3704 (clobber (match_operand:SI 2 "register_operand" ""))]
3708 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3710 emit_move_insn (operands[3], operands[1]);
3712 /* Generate a cltd if possible and doing so it profitable. */
3713 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3714 && true_regnum (operands[1]) == AX_REG
3715 && true_regnum (operands[2]) == DX_REG)
3717 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3721 emit_move_insn (operands[2], operands[1]);
3722 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3724 emit_move_insn (operands[4], operands[2]);
3728 ;; Extend to register case. Optimize case where source and destination
3729 ;; registers match and cases where we can use cltd.
3731 [(set (match_operand:DI 0 "register_operand" "")
3732 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3733 (clobber (reg:CC FLAGS_REG))
3734 (clobber (match_scratch:SI 2 ""))]
3738 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3740 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3741 emit_move_insn (operands[3], operands[1]);
3743 /* Generate a cltd if possible and doing so it profitable. */
3744 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3745 && true_regnum (operands[3]) == AX_REG
3746 && true_regnum (operands[4]) == DX_REG)
3748 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3752 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3753 emit_move_insn (operands[4], operands[1]);
3755 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3759 (define_insn "extend<mode>di2"
3760 [(set (match_operand:DI 0 "register_operand" "=r")
3762 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3764 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "DI")])
3768 (define_insn "extendhisi2"
3769 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3770 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3773 switch (get_attr_prefix_0f (insn))
3776 return "{cwtl|cwde}";
3778 return "movs{wl|x}\t{%1, %0|%0, %1}";
3781 [(set_attr "type" "imovx")
3782 (set_attr "mode" "SI")
3783 (set (attr "prefix_0f")
3784 ;; movsx is short decodable while cwtl is vector decoded.
3785 (if_then_else (and (eq_attr "cpu" "!k6")
3786 (eq_attr "alternative" "0"))
3788 (const_string "1")))
3790 (if_then_else (eq_attr "prefix_0f" "0")
3792 (const_string "1")))])
3794 (define_insn "*extendhisi2_zext"
3795 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3798 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3801 switch (get_attr_prefix_0f (insn))
3804 return "{cwtl|cwde}";
3806 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3809 [(set_attr "type" "imovx")
3810 (set_attr "mode" "SI")
3811 (set (attr "prefix_0f")
3812 ;; movsx is short decodable while cwtl is vector decoded.
3813 (if_then_else (and (eq_attr "cpu" "!k6")
3814 (eq_attr "alternative" "0"))
3816 (const_string "1")))
3818 (if_then_else (eq_attr "prefix_0f" "0")
3820 (const_string "1")))])
3822 (define_insn "extendqisi2"
3823 [(set (match_operand:SI 0 "register_operand" "=r")
3824 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3826 "movs{bl|x}\t{%1, %0|%0, %1}"
3827 [(set_attr "type" "imovx")
3828 (set_attr "mode" "SI")])
3830 (define_insn "*extendqisi2_zext"
3831 [(set (match_operand:DI 0 "register_operand" "=r")
3833 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3835 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "SI")])
3839 (define_insn "extendqihi2"
3840 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3841 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3844 switch (get_attr_prefix_0f (insn))
3847 return "{cbtw|cbw}";
3849 return "movs{bw|x}\t{%1, %0|%0, %1}";
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "HI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3859 (const_string "1")))
3861 (if_then_else (eq_attr "prefix_0f" "0")
3863 (const_string "1")))])
3865 ;; Conversions between float and double.
3867 ;; These are all no-ops in the model used for the 80387.
3868 ;; So just emit moves.
3870 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3872 [(set (match_operand:DF 0 "push_operand" "")
3873 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3875 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3876 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3879 [(set (match_operand:XF 0 "push_operand" "")
3880 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3882 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3883 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3884 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3886 (define_expand "extendsfdf2"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3888 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3889 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3891 /* ??? Needed for compress_float_constant since all fp constants
3892 are TARGET_LEGITIMATE_CONSTANT_P. */
3893 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3896 && standard_80387_constant_p (operands[1]) > 0)
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3903 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3907 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3909 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3911 We do the conversion post reload to avoid producing of 128bit spills
3912 that might lead to ICE on 32bit target. The sequence unlikely combine
3915 [(set (match_operand:DF 0 "register_operand" "")
3917 (match_operand:SF 1 "nonimmediate_operand" "")))]
3918 "TARGET_USE_VECTOR_FP_CONVERTS
3919 && optimize_insn_for_speed_p ()
3920 && reload_completed && SSE_REG_P (operands[0])"
3925 (parallel [(const_int 0) (const_int 1)]))))]
3927 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3928 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3929 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3930 Try to avoid move when unpacking can be done in source. */
3931 if (REG_P (operands[1]))
3933 /* If it is unsafe to overwrite upper half of source, we need
3934 to move to destination and unpack there. */
3935 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3936 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3937 && true_regnum (operands[0]) != true_regnum (operands[1]))
3939 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3940 emit_move_insn (tmp, operands[1]);
3943 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3944 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3948 emit_insn (gen_vec_setv4sf_0 (operands[3],
3949 CONST0_RTX (V4SFmode), operands[1]));
3952 (define_insn "*extendsfdf2_mixed"
3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3955 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3956 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3958 switch (which_alternative)
3962 return output_387_reg_move (insn, operands);
3965 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3971 [(set_attr "type" "fmov,fmov,ssecvt")
3972 (set_attr "prefix" "orig,orig,maybe_vex")
3973 (set_attr "mode" "SF,XF,DF")])
3975 (define_insn "*extendsfdf2_sse"
3976 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3977 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3978 "TARGET_SSE2 && TARGET_SSE_MATH"
3979 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3980 [(set_attr "type" "ssecvt")
3981 (set_attr "prefix" "maybe_vex")
3982 (set_attr "mode" "DF")])
3984 (define_insn "*extendsfdf2_i387"
3985 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3986 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3988 "* return output_387_reg_move (insn, operands);"
3989 [(set_attr "type" "fmov")
3990 (set_attr "mode" "SF,XF")])
3992 (define_expand "extend<mode>xf2"
3993 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3994 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3997 /* ??? Needed for compress_float_constant since all fp constants
3998 are TARGET_LEGITIMATE_CONSTANT_P. */
3999 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4001 if (standard_80387_constant_p (operands[1]) > 0)
4003 operands[1] = simplify_const_unary_operation
4004 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4005 emit_move_insn_1 (operands[0], operands[1]);
4008 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4012 (define_insn "*extend<mode>xf2_i387"
4013 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4015 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4017 "* return output_387_reg_move (insn, operands);"
4018 [(set_attr "type" "fmov")
4019 (set_attr "mode" "<MODE>,XF")])
4021 ;; %%% This seems bad bad news.
4022 ;; This cannot output into an f-reg because there is no way to be sure
4023 ;; of truncating in that case. Otherwise this is just like a simple move
4024 ;; insn. So we pretend we can output to a reg in order to get better
4025 ;; register preferencing, but we really use a stack slot.
4027 ;; Conversion from DFmode to SFmode.
4029 (define_expand "truncdfsf2"
4030 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4032 (match_operand:DF 1 "nonimmediate_operand" "")))]
4033 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4035 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4037 else if (flag_unsafe_math_optimizations)
4041 enum ix86_stack_slot slot = (virtuals_instantiated
4044 rtx temp = assign_386_stack_local (SFmode, slot);
4045 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4050 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4052 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4054 We do the conversion post reload to avoid producing of 128bit spills
4055 that might lead to ICE on 32bit target. The sequence unlikely combine
4058 [(set (match_operand:SF 0 "register_operand" "")
4060 (match_operand:DF 1 "nonimmediate_operand" "")))]
4061 "TARGET_USE_VECTOR_FP_CONVERTS
4062 && optimize_insn_for_speed_p ()
4063 && reload_completed && SSE_REG_P (operands[0])"
4066 (float_truncate:V2SF
4070 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4071 operands[3] = CONST0_RTX (V2SFmode);
4072 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4073 /* Use movsd for loading from memory, unpcklpd for registers.
4074 Try to avoid move when unpacking can be done in source, or SSE3
4075 movddup is available. */
4076 if (REG_P (operands[1]))
4079 && true_regnum (operands[0]) != true_regnum (operands[1])
4080 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4081 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4083 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4084 emit_move_insn (tmp, operands[1]);
4087 else if (!TARGET_SSE3)
4088 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4089 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4092 emit_insn (gen_sse2_loadlpd (operands[4],
4093 CONST0_RTX (V2DFmode), operands[1]));
4096 (define_expand "truncdfsf2_with_temp"
4097 [(parallel [(set (match_operand:SF 0 "" "")
4098 (float_truncate:SF (match_operand:DF 1 "" "")))
4099 (clobber (match_operand:SF 2 "" ""))])])
4101 (define_insn "*truncdfsf_fast_mixed"
4102 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4104 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4105 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4107 switch (which_alternative)
4110 return output_387_reg_move (insn, operands);
4112 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4117 [(set_attr "type" "fmov,ssecvt")
4118 (set_attr "prefix" "orig,maybe_vex")
4119 (set_attr "mode" "SF")])
4121 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4122 ;; because nothing we do here is unsafe.
4123 (define_insn "*truncdfsf_fast_sse"
4124 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4126 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4127 "TARGET_SSE2 && TARGET_SSE_MATH"
4128 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4129 [(set_attr "type" "ssecvt")
4130 (set_attr "prefix" "maybe_vex")
4131 (set_attr "mode" "SF")])
4133 (define_insn "*truncdfsf_fast_i387"
4134 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4136 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4137 "TARGET_80387 && flag_unsafe_math_optimizations"
4138 "* return output_387_reg_move (insn, operands);"
4139 [(set_attr "type" "fmov")
4140 (set_attr "mode" "SF")])
4142 (define_insn "*truncdfsf_mixed"
4143 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4145 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4146 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4147 "TARGET_MIX_SSE_I387"
4149 switch (which_alternative)
4152 return output_387_reg_move (insn, operands);
4154 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4160 [(set_attr "isa" "*,sse2,*,*,*")
4161 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4162 (set_attr "unit" "*,*,i387,i387,i387")
4163 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4164 (set_attr "mode" "SF")])
4166 (define_insn "*truncdfsf_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4169 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4170 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4173 switch (which_alternative)
4176 return output_387_reg_move (insn, operands);
4182 [(set_attr "type" "fmov,multi,multi,multi")
4183 (set_attr "unit" "*,i387,i387,i387")
4184 (set_attr "mode" "SF")])
4186 (define_insn "*truncdfsf2_i387_1"
4187 [(set (match_operand:SF 0 "memory_operand" "=m")
4189 (match_operand:DF 1 "register_operand" "f")))]
4191 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4192 && !TARGET_MIX_SSE_I387"
4193 "* return output_387_reg_move (insn, operands);"
4194 [(set_attr "type" "fmov")
4195 (set_attr "mode" "SF")])
4198 [(set (match_operand:SF 0 "register_operand" "")
4200 (match_operand:DF 1 "fp_register_operand" "")))
4201 (clobber (match_operand 2 "" ""))]
4203 [(set (match_dup 2) (match_dup 1))
4204 (set (match_dup 0) (match_dup 2))]
4205 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4207 ;; Conversion from XFmode to {SF,DF}mode
4209 (define_expand "truncxf<mode>2"
4210 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4211 (float_truncate:MODEF
4212 (match_operand:XF 1 "register_operand" "")))
4213 (clobber (match_dup 2))])]
4216 if (flag_unsafe_math_optimizations)
4218 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4219 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4220 if (reg != operands[0])
4221 emit_move_insn (operands[0], reg);
4226 enum ix86_stack_slot slot = (virtuals_instantiated
4229 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4233 (define_insn "*truncxfsf2_mixed"
4234 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4236 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4237 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4240 gcc_assert (!which_alternative);
4241 return output_387_reg_move (insn, operands);
4243 [(set_attr "type" "fmov,multi,multi,multi")
4244 (set_attr "unit" "*,i387,i387,i387")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncxfdf2_mixed"
4248 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4250 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4251 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4254 gcc_assert (!which_alternative);
4255 return output_387_reg_move (insn, operands);
4257 [(set_attr "isa" "*,*,sse2,*")
4258 (set_attr "type" "fmov,multi,multi,multi")
4259 (set_attr "unit" "*,i387,i387,i387")
4260 (set_attr "mode" "DF")])
4262 (define_insn "truncxf<mode>2_i387_noop"
4263 [(set (match_operand:MODEF 0 "register_operand" "=f")
4264 (float_truncate:MODEF
4265 (match_operand:XF 1 "register_operand" "f")))]
4266 "TARGET_80387 && flag_unsafe_math_optimizations"
4267 "* return output_387_reg_move (insn, operands);"
4268 [(set_attr "type" "fmov")
4269 (set_attr "mode" "<MODE>")])
4271 (define_insn "*truncxf<mode>2_i387"
4272 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4273 (float_truncate:MODEF
4274 (match_operand:XF 1 "register_operand" "f")))]
4276 "* return output_387_reg_move (insn, operands);"
4277 [(set_attr "type" "fmov")
4278 (set_attr "mode" "<MODE>")])
4281 [(set (match_operand:MODEF 0 "register_operand" "")
4282 (float_truncate:MODEF
4283 (match_operand:XF 1 "register_operand" "")))
4284 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4285 "TARGET_80387 && reload_completed"
4286 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4287 (set (match_dup 0) (match_dup 2))])
4290 [(set (match_operand:MODEF 0 "memory_operand" "")
4291 (float_truncate:MODEF
4292 (match_operand:XF 1 "register_operand" "")))
4293 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4295 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4297 ;; Signed conversion to DImode.
4299 (define_expand "fix_truncxfdi2"
4300 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4301 (fix:DI (match_operand:XF 1 "register_operand" "")))
4302 (clobber (reg:CC FLAGS_REG))])]
4307 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4312 (define_expand "fix_trunc<mode>di2"
4313 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4314 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4315 (clobber (reg:CC FLAGS_REG))])]
4316 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4319 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4321 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4324 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4326 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4327 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4328 if (out != operands[0])
4329 emit_move_insn (operands[0], out);
4334 ;; Signed conversion to SImode.
4336 (define_expand "fix_truncxfsi2"
4337 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338 (fix:SI (match_operand:XF 1 "register_operand" "")))
4339 (clobber (reg:CC FLAGS_REG))])]
4344 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4349 (define_expand "fix_trunc<mode>si2"
4350 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4351 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4352 (clobber (reg:CC FLAGS_REG))])]
4353 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4356 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4358 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4361 if (SSE_FLOAT_MODE_P (<MODE>mode))
4363 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4364 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4365 if (out != operands[0])
4366 emit_move_insn (operands[0], out);
4371 ;; Signed conversion to HImode.
4373 (define_expand "fix_trunc<mode>hi2"
4374 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4375 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4376 (clobber (reg:CC FLAGS_REG))])]
4378 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4382 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4387 ;; Unsigned conversion to SImode.
4389 (define_expand "fixuns_trunc<mode>si2"
4391 [(set (match_operand:SI 0 "register_operand" "")
4393 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4395 (clobber (match_scratch:<ssevecmode> 3 ""))
4396 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4397 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4399 enum machine_mode mode = <MODE>mode;
4400 enum machine_mode vecmode = <ssevecmode>mode;
4401 REAL_VALUE_TYPE TWO31r;
4404 if (optimize_insn_for_size_p ())
4407 real_ldexp (&TWO31r, &dconst1, 31);
4408 two31 = const_double_from_real_value (TWO31r, mode);
4409 two31 = ix86_build_const_vector (vecmode, true, two31);
4410 operands[2] = force_reg (vecmode, two31);
4413 (define_insn_and_split "*fixuns_trunc<mode>_1"
4414 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4416 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4417 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4418 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4419 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4420 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4421 && optimize_function_for_speed_p (cfun)"
4423 "&& reload_completed"
4426 ix86_split_convert_uns_si_sse (operands);
4430 ;; Unsigned conversion to HImode.
4431 ;; Without these patterns, we'll try the unsigned SI conversion which
4432 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4434 (define_expand "fixuns_trunc<mode>hi2"
4436 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4437 (set (match_operand:HI 0 "nonimmediate_operand" "")
4438 (subreg:HI (match_dup 2) 0))]
4439 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4440 "operands[2] = gen_reg_rtx (SImode);")
4442 ;; When SSE is available, it is always faster to use it!
4443 (define_insn "fix_trunc<mode>di_sse"
4444 [(set (match_operand:DI 0 "register_operand" "=r,r")
4445 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4446 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4447 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4448 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4449 [(set_attr "type" "sseicvt")
4450 (set_attr "prefix" "maybe_vex")
4451 (set_attr "prefix_rex" "1")
4452 (set_attr "mode" "<MODE>")
4453 (set_attr "athlon_decode" "double,vector")
4454 (set_attr "amdfam10_decode" "double,double")
4455 (set_attr "bdver1_decode" "double,double")])
4457 (define_insn "fix_trunc<mode>si_sse"
4458 [(set (match_operand:SI 0 "register_operand" "=r,r")
4459 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4460 "SSE_FLOAT_MODE_P (<MODE>mode)
4461 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4462 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4463 [(set_attr "type" "sseicvt")
4464 (set_attr "prefix" "maybe_vex")
4465 (set_attr "mode" "<MODE>")
4466 (set_attr "athlon_decode" "double,vector")
4467 (set_attr "amdfam10_decode" "double,double")
4468 (set_attr "bdver1_decode" "double,double")])
4470 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4472 [(set (match_operand:MODEF 0 "register_operand" "")
4473 (match_operand:MODEF 1 "memory_operand" ""))
4474 (set (match_operand:SWI48x 2 "register_operand" "")
4475 (fix:SWI48x (match_dup 0)))]
4476 "TARGET_SHORTEN_X87_SSE
4477 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4478 && peep2_reg_dead_p (2, operands[0])"
4479 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4481 ;; Avoid vector decoded forms of the instruction.
4483 [(match_scratch:DF 2 "x")
4484 (set (match_operand:SWI48x 0 "register_operand" "")
4485 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4486 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4487 [(set (match_dup 2) (match_dup 1))
4488 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4491 [(match_scratch:SF 2 "x")
4492 (set (match_operand:SWI48x 0 "register_operand" "")
4493 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4494 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4495 [(set (match_dup 2) (match_dup 1))
4496 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4498 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4499 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4500 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4501 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4503 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4504 && (TARGET_64BIT || <MODE>mode != DImode))
4506 && can_create_pseudo_p ()"
4511 if (memory_operand (operands[0], VOIDmode))
4512 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4515 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4516 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4522 [(set_attr "type" "fisttp")
4523 (set_attr "mode" "<MODE>")])
4525 (define_insn "fix_trunc<mode>_i387_fisttp"
4526 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4527 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4528 (clobber (match_scratch:XF 2 "=&1f"))]
4529 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && (TARGET_64BIT || <MODE>mode != DImode))
4533 && TARGET_SSE_MATH)"
4534 "* return output_fix_trunc (insn, operands, true);"
4535 [(set_attr "type" "fisttp")
4536 (set_attr "mode" "<MODE>")])
4538 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4539 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4540 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4541 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && (TARGET_64BIT || <MODE>mode != DImode))
4547 && TARGET_SSE_MATH)"
4549 [(set_attr "type" "fisttp")
4550 (set_attr "mode" "<MODE>")])
4553 [(set (match_operand:SWI248x 0 "register_operand" "")
4554 (fix:SWI248x (match_operand 1 "register_operand" "")))
4555 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4556 (clobber (match_scratch 3 ""))]
4558 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4559 (clobber (match_dup 3))])
4560 (set (match_dup 0) (match_dup 2))])
4563 [(set (match_operand:SWI248x 0 "memory_operand" "")
4564 (fix:SWI248x (match_operand 1 "register_operand" "")))
4565 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4566 (clobber (match_scratch 3 ""))]
4568 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4569 (clobber (match_dup 3))])])
4571 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4572 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4573 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4574 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4575 ;; function in i386.c.
4576 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4577 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4578 (fix:SWI248x (match_operand 1 "register_operand" "")))
4579 (clobber (reg:CC FLAGS_REG))]
4580 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && (TARGET_64BIT || <MODE>mode != DImode))
4584 && can_create_pseudo_p ()"
4589 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4591 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4592 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4593 if (memory_operand (operands[0], VOIDmode))
4594 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4595 operands[2], operands[3]));
4598 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4599 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4600 operands[2], operands[3],
4605 [(set_attr "type" "fistp")
4606 (set_attr "i387_cw" "trunc")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_truncdi_i387"
4610 [(set (match_operand:DI 0 "memory_operand" "=m")
4611 (fix:DI (match_operand 1 "register_operand" "f")))
4612 (use (match_operand:HI 2 "memory_operand" "m"))
4613 (use (match_operand:HI 3 "memory_operand" "m"))
4614 (clobber (match_scratch:XF 4 "=&1f"))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4618 "* return output_fix_trunc (insn, operands, false);"
4619 [(set_attr "type" "fistp")
4620 (set_attr "i387_cw" "trunc")
4621 (set_attr "mode" "DI")])
4623 (define_insn "fix_truncdi_i387_with_temp"
4624 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4625 (fix:DI (match_operand 1 "register_operand" "f,f")))
4626 (use (match_operand:HI 2 "memory_operand" "m,m"))
4627 (use (match_operand:HI 3 "memory_operand" "m,m"))
4628 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4629 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4634 [(set_attr "type" "fistp")
4635 (set_attr "i387_cw" "trunc")
4636 (set_attr "mode" "DI")])
4639 [(set (match_operand:DI 0 "register_operand" "")
4640 (fix:DI (match_operand 1 "register_operand" "")))
4641 (use (match_operand:HI 2 "memory_operand" ""))
4642 (use (match_operand:HI 3 "memory_operand" ""))
4643 (clobber (match_operand:DI 4 "memory_operand" ""))
4644 (clobber (match_scratch 5 ""))]
4646 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4649 (clobber (match_dup 5))])
4650 (set (match_dup 0) (match_dup 4))])
4653 [(set (match_operand:DI 0 "memory_operand" "")
4654 (fix:DI (match_operand 1 "register_operand" "")))
4655 (use (match_operand:HI 2 "memory_operand" ""))
4656 (use (match_operand:HI 3 "memory_operand" ""))
4657 (clobber (match_operand:DI 4 "memory_operand" ""))
4658 (clobber (match_scratch 5 ""))]
4660 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4663 (clobber (match_dup 5))])])
4665 (define_insn "fix_trunc<mode>_i387"
4666 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4667 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4668 (use (match_operand:HI 2 "memory_operand" "m"))
4669 (use (match_operand:HI 3 "memory_operand" "m"))]
4670 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4673 "* return output_fix_trunc (insn, operands, false);"
4674 [(set_attr "type" "fistp")
4675 (set_attr "i387_cw" "trunc")
4676 (set_attr "mode" "<MODE>")])
4678 (define_insn "fix_trunc<mode>_i387_with_temp"
4679 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4680 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4681 (use (match_operand:HI 2 "memory_operand" "m,m"))
4682 (use (match_operand:HI 3 "memory_operand" "m,m"))
4683 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4684 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4688 [(set_attr "type" "fistp")
4689 (set_attr "i387_cw" "trunc")
4690 (set_attr "mode" "<MODE>")])
4693 [(set (match_operand:SWI24 0 "register_operand" "")
4694 (fix:SWI24 (match_operand 1 "register_operand" "")))
4695 (use (match_operand:HI 2 "memory_operand" ""))
4696 (use (match_operand:HI 3 "memory_operand" ""))
4697 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4699 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4701 (use (match_dup 3))])
4702 (set (match_dup 0) (match_dup 4))])
4705 [(set (match_operand:SWI24 0 "memory_operand" "")
4706 (fix:SWI24 (match_operand 1 "register_operand" "")))
4707 (use (match_operand:HI 2 "memory_operand" ""))
4708 (use (match_operand:HI 3 "memory_operand" ""))
4709 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4711 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4713 (use (match_dup 3))])])
4715 (define_insn "x86_fnstcw_1"
4716 [(set (match_operand:HI 0 "memory_operand" "=m")
4717 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4720 [(set (attr "length")
4721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722 (set_attr "mode" "HI")
4723 (set_attr "unit" "i387")
4724 (set_attr "bdver1_decode" "vector")])
4726 (define_insn "x86_fldcw_1"
4727 [(set (reg:HI FPCR_REG)
4728 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4731 [(set (attr "length")
4732 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4733 (set_attr "mode" "HI")
4734 (set_attr "unit" "i387")
4735 (set_attr "athlon_decode" "vector")
4736 (set_attr "amdfam10_decode" "vector")
4737 (set_attr "bdver1_decode" "vector")])
4739 ;; Conversion between fixed point and floating point.
4741 ;; Even though we only accept memory inputs, the backend _really_
4742 ;; wants to be able to do this between registers.
4744 (define_expand "floathi<mode>2"
4745 [(set (match_operand:X87MODEF 0 "register_operand" "")
4746 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4749 || TARGET_MIX_SSE_I387)")
4751 ;; Pre-reload splitter to add memory clobber to the pattern.
4752 (define_insn_and_split "*floathi<mode>2_1"
4753 [(set (match_operand:X87MODEF 0 "register_operand" "")
4754 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4757 || TARGET_MIX_SSE_I387)
4758 && can_create_pseudo_p ()"
4761 [(parallel [(set (match_dup 0)
4762 (float:X87MODEF (match_dup 1)))
4763 (clobber (match_dup 2))])]
4764 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4766 (define_insn "*floathi<mode>2_i387_with_temp"
4767 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4768 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4769 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4772 || TARGET_MIX_SSE_I387)"
4774 [(set_attr "type" "fmov,multi")
4775 (set_attr "mode" "<MODE>")
4776 (set_attr "unit" "*,i387")
4777 (set_attr "fp_int_src" "true")])
4779 (define_insn "*floathi<mode>2_i387"
4780 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4781 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4784 || TARGET_MIX_SSE_I387)"
4786 [(set_attr "type" "fmov")
4787 (set_attr "mode" "<MODE>")
4788 (set_attr "fp_int_src" "true")])
4791 [(set (match_operand:X87MODEF 0 "register_operand" "")
4792 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4793 (clobber (match_operand:HI 2 "memory_operand" ""))]
4795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796 || TARGET_MIX_SSE_I387)
4797 && reload_completed"
4798 [(set (match_dup 2) (match_dup 1))
4799 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4802 [(set (match_operand:X87MODEF 0 "register_operand" "")
4803 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4804 (clobber (match_operand:HI 2 "memory_operand" ""))]
4806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4807 || TARGET_MIX_SSE_I387)
4808 && reload_completed"
4809 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4811 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4812 [(set (match_operand:X87MODEF 0 "register_operand" "")
4814 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4816 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4819 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4820 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4821 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4823 rtx reg = gen_reg_rtx (XFmode);
4824 rtx (*insn)(rtx, rtx);
4826 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4828 if (<X87MODEF:MODE>mode == SFmode)
4829 insn = gen_truncxfsf2;
4830 else if (<X87MODEF:MODE>mode == DFmode)
4831 insn = gen_truncxfdf2;
4835 emit_insn (insn (operands[0], reg));
4840 ;; Pre-reload splitter to add memory clobber to the pattern.
4841 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4842 [(set (match_operand:X87MODEF 0 "register_operand" "")
4843 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4845 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4846 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4847 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4848 || TARGET_MIX_SSE_I387))
4849 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4851 && ((<SWI48x:MODE>mode == SImode
4852 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4853 && optimize_function_for_speed_p (cfun)
4854 && flag_trapping_math)
4855 || !(TARGET_INTER_UNIT_CONVERSIONS
4856 || optimize_function_for_size_p (cfun)))))
4857 && can_create_pseudo_p ()"
4860 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4861 (clobber (match_dup 2))])]
4863 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4865 /* Avoid store forwarding (partial memory) stall penalty
4866 by passing DImode value through XMM registers. */
4867 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4868 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4869 && optimize_function_for_speed_p (cfun))
4871 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4878 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4879 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4881 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4882 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4883 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4884 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4886 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4887 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4888 (set_attr "unit" "*,i387,*,*,*")
4889 (set_attr "athlon_decode" "*,*,double,direct,double")
4890 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4891 (set_attr "bdver1_decode" "*,*,double,direct,double")
4892 (set_attr "fp_int_src" "true")])
4894 (define_insn "*floatsi<mode>2_vector_mixed"
4895 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4896 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4897 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4898 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "mode" "<MODE>,<ssevecmode>")
4904 (set_attr "unit" "i387,*")
4905 (set_attr "athlon_decode" "*,direct")
4906 (set_attr "amdfam10_decode" "*,double")
4907 (set_attr "bdver1_decode" "*,direct")
4908 (set_attr "fp_int_src" "true")])
4910 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4911 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4913 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4914 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4915 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4918 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4919 (set_attr "mode" "<MODEF:MODE>")
4920 (set_attr "unit" "*,i387,*,*")
4921 (set_attr "athlon_decode" "*,*,double,direct")
4922 (set_attr "amdfam10_decode" "*,*,vector,double")
4923 (set_attr "bdver1_decode" "*,*,double,direct")
4924 (set_attr "fp_int_src" "true")])
4927 [(set (match_operand:MODEF 0 "register_operand" "")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && TARGET_INTER_UNIT_CONVERSIONS
4934 && (SSE_REG_P (operands[0])
4935 || (GET_CODE (operands[0]) == SUBREG
4936 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4937 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4940 [(set (match_operand:MODEF 0 "register_operand" "")
4941 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4942 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4943 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4944 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4945 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4947 && (SSE_REG_P (operands[0])
4948 || (GET_CODE (operands[0]) == SUBREG
4949 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4950 [(set (match_dup 2) (match_dup 1))
4951 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4953 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4954 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4956 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4957 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4958 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4959 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4962 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4963 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4964 [(set_attr "type" "fmov,sseicvt,sseicvt")
4965 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4966 (set_attr "mode" "<MODEF:MODE>")
4967 (set (attr "prefix_rex")
4969 (and (eq_attr "prefix" "maybe_vex")
4970 (match_test "<SWI48x:MODE>mode == DImode"))
4972 (const_string "*")))
4973 (set_attr "unit" "i387,*,*")
4974 (set_attr "athlon_decode" "*,double,direct")
4975 (set_attr "amdfam10_decode" "*,vector,double")
4976 (set_attr "bdver1_decode" "*,double,direct")
4977 (set_attr "fp_int_src" "true")])
4979 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4980 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4982 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4983 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4984 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4985 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4988 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4989 [(set_attr "type" "fmov,sseicvt")
4990 (set_attr "prefix" "orig,maybe_vex")
4991 (set_attr "mode" "<MODEF:MODE>")
4992 (set (attr "prefix_rex")
4994 (and (eq_attr "prefix" "maybe_vex")
4995 (match_test "<SWI48x:MODE>mode == DImode"))
4997 (const_string "*")))
4998 (set_attr "athlon_decode" "*,direct")
4999 (set_attr "amdfam10_decode" "*,double")
5000 (set_attr "bdver1_decode" "*,direct")
5001 (set_attr "fp_int_src" "true")])
5003 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5004 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5006 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5007 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5013 (set_attr "athlon_decode" "double,direct,double")
5014 (set_attr "amdfam10_decode" "vector,double,double")
5015 (set_attr "bdver1_decode" "double,direct,double")
5016 (set_attr "fp_int_src" "true")])
5018 (define_insn "*floatsi<mode>2_vector_sse"
5019 [(set (match_operand:MODEF 0 "register_operand" "=x")
5020 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5021 "TARGET_SSE2 && TARGET_SSE_MATH
5022 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5024 [(set_attr "type" "sseicvt")
5025 (set_attr "mode" "<MODE>")
5026 (set_attr "athlon_decode" "direct")
5027 (set_attr "amdfam10_decode" "double")
5028 (set_attr "bdver1_decode" "direct")
5029 (set_attr "fp_int_src" "true")])
5032 [(set (match_operand:MODEF 0 "register_operand" "")
5033 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5034 (clobber (match_operand:SI 2 "memory_operand" ""))]
5035 "TARGET_SSE2 && TARGET_SSE_MATH
5036 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5038 && (SSE_REG_P (operands[0])
5039 || (GET_CODE (operands[0]) == SUBREG
5040 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5043 rtx op1 = operands[1];
5045 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5047 if (GET_CODE (op1) == SUBREG)
5048 op1 = SUBREG_REG (op1);
5050 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5052 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5053 emit_insn (gen_sse2_loadld (operands[4],
5054 CONST0_RTX (V4SImode), operands[1]));
5056 /* We can ignore possible trapping value in the
5057 high part of SSE register for non-trapping math. */
5058 else if (SSE_REG_P (op1) && !flag_trapping_math)
5059 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063 emit_move_insn (operands[2], operands[1]);
5064 emit_insn (gen_sse2_loadld (operands[4],
5065 CONST0_RTX (V4SImode), operands[2]));
5067 if (<ssevecmode>mode == V4SFmode)
5068 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5070 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5075 [(set (match_operand:MODEF 0 "register_operand" "")
5076 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5077 (clobber (match_operand:SI 2 "memory_operand" ""))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5081 && (SSE_REG_P (operands[0])
5082 || (GET_CODE (operands[0]) == SUBREG
5083 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5086 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5088 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5090 emit_insn (gen_sse2_loadld (operands[4],
5091 CONST0_RTX (V4SImode), operands[1]));
5092 if (<ssevecmode>mode == V4SFmode)
5093 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5095 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5100 [(set (match_operand:MODEF 0 "register_operand" "")
5101 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5102 "TARGET_SSE2 && TARGET_SSE_MATH
5103 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5105 && (SSE_REG_P (operands[0])
5106 || (GET_CODE (operands[0]) == SUBREG
5107 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5110 rtx op1 = operands[1];
5112 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5114 if (GET_CODE (op1) == SUBREG)
5115 op1 = SUBREG_REG (op1);
5117 if (GENERAL_REG_P (op1))
5119 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5120 if (TARGET_INTER_UNIT_MOVES)
5121 emit_insn (gen_sse2_loadld (operands[4],
5122 CONST0_RTX (V4SImode), operands[1]));
5125 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5127 emit_insn (gen_sse2_loadld (operands[4],
5128 CONST0_RTX (V4SImode), operands[5]));
5129 ix86_free_from_memory (GET_MODE (operands[1]));
5132 /* We can ignore possible trapping value in the
5133 high part of SSE register for non-trapping math. */
5134 else if (SSE_REG_P (op1) && !flag_trapping_math)
5135 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5138 if (<ssevecmode>mode == V4SFmode)
5139 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5141 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5148 "TARGET_SSE2 && TARGET_SSE_MATH
5149 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5151 && (SSE_REG_P (operands[0])
5152 || (GET_CODE (operands[0]) == SUBREG
5153 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5156 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5158 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5160 emit_insn (gen_sse2_loadld (operands[4],
5161 CONST0_RTX (V4SImode), operands[1]));
5162 if (<ssevecmode>mode == V4SFmode)
5163 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5165 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5169 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5170 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5172 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5173 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5174 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5175 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5177 [(set_attr "type" "sseicvt")
5178 (set_attr "mode" "<MODEF:MODE>")
5179 (set_attr "athlon_decode" "double,direct")
5180 (set_attr "amdfam10_decode" "vector,double")
5181 (set_attr "bdver1_decode" "double,direct")
5182 (set_attr "fp_int_src" "true")])
5184 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5185 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5187 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5188 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5189 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5190 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5191 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5192 [(set_attr "type" "sseicvt")
5193 (set_attr "prefix" "maybe_vex")
5194 (set_attr "mode" "<MODEF:MODE>")
5195 (set (attr "prefix_rex")
5197 (and (eq_attr "prefix" "maybe_vex")
5198 (match_test "<SWI48x:MODE>mode == DImode"))
5200 (const_string "*")))
5201 (set_attr "athlon_decode" "double,direct")
5202 (set_attr "amdfam10_decode" "vector,double")
5203 (set_attr "bdver1_decode" "double,direct")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:MODEF 0 "register_operand" "")
5208 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5214 && (SSE_REG_P (operands[0])
5215 || (GET_CODE (operands[0]) == SUBREG
5216 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5217 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5219 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5220 [(set (match_operand:MODEF 0 "register_operand" "=x")
5222 (match_operand:SWI48x 1 "memory_operand" "m")))]
5223 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5224 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5225 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5226 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5227 [(set_attr "type" "sseicvt")
5228 (set_attr "prefix" "maybe_vex")
5229 (set_attr "mode" "<MODEF:MODE>")
5230 (set (attr "prefix_rex")
5232 (and (eq_attr "prefix" "maybe_vex")
5233 (match_test "<SWI48x:MODE>mode == DImode"))
5235 (const_string "*")))
5236 (set_attr "athlon_decode" "direct")
5237 (set_attr "amdfam10_decode" "double")
5238 (set_attr "bdver1_decode" "direct")
5239 (set_attr "fp_int_src" "true")])
5242 [(set (match_operand:MODEF 0 "register_operand" "")
5243 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5244 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5245 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5246 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5252 [(set (match_dup 2) (match_dup 1))
5253 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5256 [(set (match_operand:MODEF 0 "register_operand" "")
5257 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5258 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5259 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5262 && (SSE_REG_P (operands[0])
5263 || (GET_CODE (operands[0]) == SUBREG
5264 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5265 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5267 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5268 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5271 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5273 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5277 [(set_attr "type" "fmov,multi")
5278 (set_attr "mode" "<X87MODEF:MODE>")
5279 (set_attr "unit" "*,i387")
5280 (set_attr "fp_int_src" "true")])
5282 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5285 (match_operand:SWI48x 1 "memory_operand" "m")))]
5287 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5289 [(set_attr "type" "fmov")
5290 (set_attr "mode" "<X87MODEF:MODE>")
5291 (set_attr "fp_int_src" "true")])
5294 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5295 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5296 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5298 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5299 && reload_completed"
5300 [(set (match_dup 2) (match_dup 1))
5301 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5304 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5305 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5306 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5308 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5309 && reload_completed"
5310 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5312 ;; Avoid store forwarding (partial memory) stall penalty
5313 ;; by passing DImode value through XMM registers. */
5315 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5318 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5319 (clobber (match_scratch:V4SI 3 "=X,x"))
5320 (clobber (match_scratch:V4SI 4 "=X,x"))
5321 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5322 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5323 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5324 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5326 [(set_attr "type" "multi")
5327 (set_attr "mode" "<X87MODEF:MODE>")
5328 (set_attr "unit" "i387")
5329 (set_attr "fp_int_src" "true")])
5332 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5333 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5334 (clobber (match_scratch:V4SI 3 ""))
5335 (clobber (match_scratch:V4SI 4 ""))
5336 (clobber (match_operand:DI 2 "memory_operand" ""))]
5337 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5338 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5339 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5340 && reload_completed"
5341 [(set (match_dup 2) (match_dup 3))
5342 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5344 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5345 Assemble the 64-bit DImode value in an xmm register. */
5346 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5347 gen_rtx_SUBREG (SImode, operands[1], 0)));
5348 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5349 gen_rtx_SUBREG (SImode, operands[1], 4)));
5350 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5353 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5357 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5358 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5359 (clobber (match_scratch:V4SI 3 ""))
5360 (clobber (match_scratch:V4SI 4 ""))
5361 (clobber (match_operand:DI 2 "memory_operand" ""))]
5362 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5364 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5365 && reload_completed"
5366 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5368 ;; Avoid store forwarding (partial memory) stall penalty by extending
5369 ;; SImode value to DImode through XMM register instead of pushing two
5370 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5371 ;; targets benefit from this optimization. Also note that fild
5372 ;; loads from memory only.
5374 (define_insn "*floatunssi<mode>2_1"
5375 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5376 (unsigned_float:X87MODEF
5377 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5378 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5379 (clobber (match_scratch:SI 3 "=X,x"))]
5381 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5384 [(set_attr "type" "multi")
5385 (set_attr "mode" "<MODE>")])
5388 [(set (match_operand:X87MODEF 0 "register_operand" "")
5389 (unsigned_float:X87MODEF
5390 (match_operand:SI 1 "register_operand" "")))
5391 (clobber (match_operand:DI 2 "memory_operand" ""))
5392 (clobber (match_scratch:SI 3 ""))]
5394 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396 && reload_completed"
5397 [(set (match_dup 2) (match_dup 1))
5399 (float:X87MODEF (match_dup 2)))]
5400 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5403 [(set (match_operand:X87MODEF 0 "register_operand" "")
5404 (unsigned_float:X87MODEF
5405 (match_operand:SI 1 "memory_operand" "")))
5406 (clobber (match_operand:DI 2 "memory_operand" ""))
5407 (clobber (match_scratch:SI 3 ""))]
5409 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5411 && reload_completed"
5412 [(set (match_dup 2) (match_dup 3))
5414 (float:X87MODEF (match_dup 2)))]
5416 emit_move_insn (operands[3], operands[1]);
5417 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5420 (define_expand "floatunssi<mode>2"
5422 [(set (match_operand:X87MODEF 0 "register_operand" "")
5423 (unsigned_float:X87MODEF
5424 (match_operand:SI 1 "nonimmediate_operand" "")))
5425 (clobber (match_dup 2))
5426 (clobber (match_scratch:SI 3 ""))])]
5428 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5430 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5432 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5434 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5439 enum ix86_stack_slot slot = (virtuals_instantiated
5442 operands[2] = assign_386_stack_local (DImode, slot);
5446 (define_expand "floatunsdisf2"
5447 [(use (match_operand:SF 0 "register_operand" ""))
5448 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5449 "TARGET_64BIT && TARGET_SSE_MATH"
5450 "x86_emit_floatuns (operands); DONE;")
5452 (define_expand "floatunsdidf2"
5453 [(use (match_operand:DF 0 "register_operand" ""))
5454 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5455 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5456 && TARGET_SSE2 && TARGET_SSE_MATH"
5459 x86_emit_floatuns (operands);
5461 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5467 (define_expand "add<mode>3"
5468 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5469 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5470 (match_operand:SDWIM 2 "<general_operand>" "")))]
5472 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5474 (define_insn_and_split "*add<dwi>3_doubleword"
5475 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5477 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5478 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5479 (clobber (reg:CC FLAGS_REG))]
5480 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5483 [(parallel [(set (reg:CC FLAGS_REG)
5484 (unspec:CC [(match_dup 1) (match_dup 2)]
5487 (plus:DWIH (match_dup 1) (match_dup 2)))])
5488 (parallel [(set (match_dup 3)
5492 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5494 (clobber (reg:CC FLAGS_REG))])]
5495 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5497 (define_insn "*add<mode>3_cc"
5498 [(set (reg:CC FLAGS_REG)
5500 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5503 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5504 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5505 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5506 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5507 [(set_attr "type" "alu")
5508 (set_attr "mode" "<MODE>")])
5510 (define_insn "addqi3_cc"
5511 [(set (reg:CC FLAGS_REG)
5513 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5514 (match_operand:QI 2 "general_operand" "qn,qm")]
5516 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5517 (plus:QI (match_dup 1) (match_dup 2)))]
5518 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5519 "add{b}\t{%2, %0|%0, %2}"
5520 [(set_attr "type" "alu")
5521 (set_attr "mode" "QI")])
5523 (define_insn_and_split "*lea_1"
5524 [(set (match_operand:SI 0 "register_operand" "=r")
5525 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5527 "lea{l}\t{%a1, %0|%0, %a1}"
5528 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5531 ix86_split_lea_for_addr (operands, SImode);
5534 [(set_attr "type" "lea")
5535 (set_attr "mode" "SI")])
5537 (define_insn_and_split "*lea<mode>_2"
5538 [(set (match_operand:SWI48 0 "register_operand" "=r")
5539 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5541 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5542 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5545 ix86_split_lea_for_addr (operands, <MODE>mode);
5548 [(set_attr "type" "lea")
5549 (set_attr "mode" "<MODE>")])
5551 (define_insn "*lea_3_zext"
5552 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5556 "lea{l}\t{%a1, %k0|%k0, %a1}"
5557 [(set_attr "type" "lea")
5558 (set_attr "mode" "SI")])
5560 (define_insn "*lea_4_zext"
5561 [(set (match_operand:DI 0 "register_operand" "=r")
5563 (match_operand:SI 1 "lea_address_operand" "j")))]
5565 "lea{l}\t{%a1, %k0|%k0, %a1}"
5566 [(set_attr "type" "lea")
5567 (set_attr "mode" "SI")])
5569 (define_insn "*lea_5_zext"
5570 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5573 (match_operand:DI 2 "const_32bit_mask" "n")))]
5575 "lea{l}\t{%a1, %k0|%k0, %a1}"
5576 [(set_attr "type" "lea")
5577 (set_attr "mode" "SI")])
5579 (define_insn "*lea_6_zext"
5580 [(set (match_operand:DI 0 "register_operand" "=r")
5582 (match_operand:DI 1 "lea_address_operand" "p")
5583 (match_operand:DI 2 "const_32bit_mask" "n")))]
5585 "lea{l}\t{%a1, %k0|%k0, %a1}"
5586 [(set_attr "type" "lea")
5587 (set_attr "mode" "SI")])
5589 (define_insn "*add<mode>_1"
5590 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5592 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5593 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5594 (clobber (reg:CC FLAGS_REG))]
5595 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5597 switch (get_attr_type (insn))
5603 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5604 if (operands[2] == const1_rtx)
5605 return "inc{<imodesuffix>}\t%0";
5608 gcc_assert (operands[2] == constm1_rtx);
5609 return "dec{<imodesuffix>}\t%0";
5613 /* For most processors, ADD is faster than LEA. This alternative
5614 was added to use ADD as much as possible. */
5615 if (which_alternative == 2)
5618 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5621 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5623 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5625 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5629 (cond [(eq_attr "alternative" "3")
5630 (const_string "lea")
5631 (match_operand:SWI48 2 "incdec_operand" "")
5632 (const_string "incdec")
5634 (const_string "alu")))
5635 (set (attr "length_immediate")
5637 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5639 (const_string "*")))
5640 (set_attr "mode" "<MODE>")])
5642 ;; It may seem that nonimmediate operand is proper one for operand 1.
5643 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5644 ;; we take care in ix86_binary_operator_ok to not allow two memory
5645 ;; operands so proper swapping will be done in reload. This allow
5646 ;; patterns constructed from addsi_1 to match.
5648 (define_insn "addsi_1_zext"
5649 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5651 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5652 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5656 switch (get_attr_type (insn))
5662 if (operands[2] == const1_rtx)
5663 return "inc{l}\t%k0";
5666 gcc_assert (operands[2] == constm1_rtx);
5667 return "dec{l}\t%k0";
5671 /* For most processors, ADD is faster than LEA. This alternative
5672 was added to use ADD as much as possible. */
5673 if (which_alternative == 1)
5676 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5679 if (x86_maybe_negate_const_int (&operands[2], SImode))
5680 return "sub{l}\t{%2, %k0|%k0, %2}";
5682 return "add{l}\t{%2, %k0|%k0, %2}";
5686 (cond [(eq_attr "alternative" "2")
5687 (const_string "lea")
5688 (match_operand:SI 2 "incdec_operand" "")
5689 (const_string "incdec")
5691 (const_string "alu")))
5692 (set (attr "length_immediate")
5694 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5696 (const_string "*")))
5697 (set_attr "mode" "SI")])
5699 (define_insn "*addhi_1"
5700 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5701 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5702 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5703 (clobber (reg:CC FLAGS_REG))]
5704 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5706 switch (get_attr_type (insn))
5712 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5713 if (operands[2] == const1_rtx)
5714 return "inc{w}\t%0";
5717 gcc_assert (operands[2] == constm1_rtx);
5718 return "dec{w}\t%0";
5722 /* For most processors, ADD is faster than LEA. This alternative
5723 was added to use ADD as much as possible. */
5724 if (which_alternative == 2)
5727 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5731 if (x86_maybe_negate_const_int (&operands[2], HImode))
5732 return "sub{w}\t{%2, %0|%0, %2}";
5734 return "add{w}\t{%2, %0|%0, %2}";
5738 (cond [(eq_attr "alternative" "3")
5739 (const_string "lea")
5740 (match_operand:HI 2 "incdec_operand" "")
5741 (const_string "incdec")
5743 (const_string "alu")))
5744 (set (attr "length_immediate")
5746 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5748 (const_string "*")))
5749 (set_attr "mode" "HI,HI,HI,SI")])
5751 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5752 (define_insn "*addqi_1"
5753 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5754 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5755 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5759 bool widen = (which_alternative == 3 || which_alternative == 4);
5761 switch (get_attr_type (insn))
5767 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5768 if (operands[2] == const1_rtx)
5769 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5772 gcc_assert (operands[2] == constm1_rtx);
5773 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5777 /* For most processors, ADD is faster than LEA. These alternatives
5778 were added to use ADD as much as possible. */
5779 if (which_alternative == 2 || which_alternative == 4)
5782 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5785 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786 if (x86_maybe_negate_const_int (&operands[2], QImode))
5789 return "sub{l}\t{%2, %k0|%k0, %2}";
5791 return "sub{b}\t{%2, %0|%0, %2}";
5794 return "add{l}\t{%k2, %k0|%k0, %k2}";
5796 return "add{b}\t{%2, %0|%0, %2}";
5800 (cond [(eq_attr "alternative" "5")
5801 (const_string "lea")
5802 (match_operand:QI 2 "incdec_operand" "")
5803 (const_string "incdec")
5805 (const_string "alu")))
5806 (set (attr "length_immediate")
5808 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5810 (const_string "*")))
5811 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5813 (define_insn "*addqi_1_slp"
5814 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5815 (plus:QI (match_dup 0)
5816 (match_operand:QI 1 "general_operand" "qn,qm")))
5817 (clobber (reg:CC FLAGS_REG))]
5818 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5819 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5821 switch (get_attr_type (insn))
5824 if (operands[1] == const1_rtx)
5825 return "inc{b}\t%0";
5828 gcc_assert (operands[1] == constm1_rtx);
5829 return "dec{b}\t%0";
5833 if (x86_maybe_negate_const_int (&operands[1], QImode))
5834 return "sub{b}\t{%1, %0|%0, %1}";
5836 return "add{b}\t{%1, %0|%0, %1}";
5840 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5841 (const_string "incdec")
5842 (const_string "alu1")))
5843 (set (attr "memory")
5844 (if_then_else (match_operand 1 "memory_operand" "")
5845 (const_string "load")
5846 (const_string "none")))
5847 (set_attr "mode" "QI")])
5849 ;; Split non destructive adds if we cannot use lea.
5851 [(set (match_operand:SWI48 0 "register_operand" "")
5852 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5853 (match_operand:SWI48 2 "nonmemory_operand" "")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5856 [(set (match_dup 0) (match_dup 1))
5857 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5858 (clobber (reg:CC FLAGS_REG))])])
5860 ;; Convert add to the lea pattern to avoid flags dependency.
5862 [(set (match_operand:SWI 0 "register_operand" "")
5863 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5864 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5865 (clobber (reg:CC FLAGS_REG))]
5866 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5869 enum machine_mode mode = <MODE>mode;
5872 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5875 operands[0] = gen_lowpart (mode, operands[0]);
5876 operands[1] = gen_lowpart (mode, operands[1]);
5877 operands[2] = gen_lowpart (mode, operands[2]);
5880 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5882 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5886 ;; Convert add to the lea pattern to avoid flags dependency.
5888 [(set (match_operand:DI 0 "register_operand" "")
5890 (plus:SI (match_operand:SI 1 "register_operand" "")
5891 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5892 (clobber (reg:CC FLAGS_REG))]
5893 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5895 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5897 (define_insn "*add<mode>_2"
5898 [(set (reg FLAGS_REG)
5901 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5902 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5904 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5905 (plus:SWI (match_dup 1) (match_dup 2)))]
5906 "ix86_match_ccmode (insn, CCGOCmode)
5907 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5909 switch (get_attr_type (insn))
5912 if (operands[2] == const1_rtx)
5913 return "inc{<imodesuffix>}\t%0";
5916 gcc_assert (operands[2] == constm1_rtx);
5917 return "dec{<imodesuffix>}\t%0";
5921 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5922 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5924 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5928 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5929 (const_string "incdec")
5930 (const_string "alu")))
5931 (set (attr "length_immediate")
5933 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5935 (const_string "*")))
5936 (set_attr "mode" "<MODE>")])
5938 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5939 (define_insn "*addsi_2_zext"
5940 [(set (reg FLAGS_REG)
5942 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5943 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5945 (set (match_operand:DI 0 "register_operand" "=r")
5946 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5947 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5948 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5950 switch (get_attr_type (insn))
5953 if (operands[2] == const1_rtx)
5954 return "inc{l}\t%k0";
5957 gcc_assert (operands[2] == constm1_rtx);
5958 return "dec{l}\t%k0";
5962 if (x86_maybe_negate_const_int (&operands[2], SImode))
5963 return "sub{l}\t{%2, %k0|%k0, %2}";
5965 return "add{l}\t{%2, %k0|%k0, %2}";
5969 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set (attr "length_immediate")
5974 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5976 (const_string "*")))
5977 (set_attr "mode" "SI")])
5979 (define_insn "*add<mode>_3"
5980 [(set (reg FLAGS_REG)
5982 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5983 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5984 (clobber (match_scratch:SWI 0 "=<r>"))]
5985 "ix86_match_ccmode (insn, CCZmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5988 switch (get_attr_type (insn))
5991 if (operands[2] == const1_rtx)
5992 return "inc{<imodesuffix>}\t%0";
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return "dec{<imodesuffix>}\t%0";
6000 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6001 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6003 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6007 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6014 (const_string "*")))
6015 (set_attr "mode" "<MODE>")])
6017 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6018 (define_insn "*addsi_3_zext"
6019 [(set (reg FLAGS_REG)
6021 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
6022 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6023 (set (match_operand:DI 0 "register_operand" "=r")
6024 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6025 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6026 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6028 switch (get_attr_type (insn))
6031 if (operands[2] == const1_rtx)
6032 return "inc{l}\t%k0";
6035 gcc_assert (operands[2] == constm1_rtx);
6036 return "dec{l}\t%k0";
6040 if (x86_maybe_negate_const_int (&operands[2], SImode))
6041 return "sub{l}\t{%2, %k0|%k0, %2}";
6043 return "add{l}\t{%2, %k0|%k0, %2}";
6047 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6048 (const_string "incdec")
6049 (const_string "alu")))
6050 (set (attr "length_immediate")
6052 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6054 (const_string "*")))
6055 (set_attr "mode" "SI")])
6057 ; For comparisons against 1, -1 and 128, we may generate better code
6058 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6059 ; is matched then. We can't accept general immediate, because for
6060 ; case of overflows, the result is messed up.
6061 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6062 ; only for comparisons not depending on it.
6064 (define_insn "*adddi_4"
6065 [(set (reg FLAGS_REG)
6067 (match_operand:DI 1 "nonimmediate_operand" "0")
6068 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6069 (clobber (match_scratch:DI 0 "=rm"))]
6071 && ix86_match_ccmode (insn, CCGCmode)"
6073 switch (get_attr_type (insn))
6076 if (operands[2] == constm1_rtx)
6077 return "inc{q}\t%0";
6080 gcc_assert (operands[2] == const1_rtx);
6081 return "dec{q}\t%0";
6085 if (x86_maybe_negate_const_int (&operands[2], DImode))
6086 return "add{q}\t{%2, %0|%0, %2}";
6088 return "sub{q}\t{%2, %0|%0, %2}";
6092 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6093 (const_string "incdec")
6094 (const_string "alu")))
6095 (set (attr "length_immediate")
6097 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6099 (const_string "*")))
6100 (set_attr "mode" "DI")])
6102 ; For comparisons against 1, -1 and 128, we may generate better code
6103 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6104 ; is matched then. We can't accept general immediate, because for
6105 ; case of overflows, the result is messed up.
6106 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6107 ; only for comparisons not depending on it.
6109 (define_insn "*add<mode>_4"
6110 [(set (reg FLAGS_REG)
6112 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6113 (match_operand:SWI124 2 "const_int_operand" "n")))
6114 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6115 "ix86_match_ccmode (insn, CCGCmode)"
6117 switch (get_attr_type (insn))
6120 if (operands[2] == constm1_rtx)
6121 return "inc{<imodesuffix>}\t%0";
6124 gcc_assert (operands[2] == const1_rtx);
6125 return "dec{<imodesuffix>}\t%0";
6129 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6130 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6132 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6136 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set (attr "length_immediate")
6141 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143 (const_string "*")))
6144 (set_attr "mode" "<MODE>")])
6146 (define_insn "*add<mode>_5"
6147 [(set (reg FLAGS_REG)
6150 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6151 (match_operand:SWI 2 "<general_operand>" "<g>"))
6153 (clobber (match_scratch:SWI 0 "=<r>"))]
6154 "ix86_match_ccmode (insn, CCGOCmode)
6155 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6157 switch (get_attr_type (insn))
6160 if (operands[2] == const1_rtx)
6161 return "inc{<imodesuffix>}\t%0";
6164 gcc_assert (operands[2] == constm1_rtx);
6165 return "dec{<imodesuffix>}\t%0";
6169 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6170 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6172 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6176 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set (attr "length_immediate")
6181 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6183 (const_string "*")))
6184 (set_attr "mode" "<MODE>")])
6186 (define_insn "*addqi_ext_1_rex64"
6187 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6192 (match_operand 1 "ext_register_operand" "0")
6195 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6196 (clobber (reg:CC FLAGS_REG))]
6199 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{b}\t%h0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{b}\t%h0";
6211 return "add{b}\t{%2, %h0|%h0, %2}";
6215 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "modrm" "1")
6219 (set_attr "mode" "QI")])
6221 (define_insn "addqi_ext_1"
6222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6227 (match_operand 1 "ext_register_operand" "0")
6230 (match_operand:QI 2 "general_operand" "Qmn")))
6231 (clobber (reg:CC FLAGS_REG))]
6234 switch (get_attr_type (insn))
6237 if (operands[2] == const1_rtx)
6238 return "inc{b}\t%h0";
6241 gcc_assert (operands[2] == constm1_rtx);
6242 return "dec{b}\t%h0";
6246 return "add{b}\t{%2, %h0|%h0, %2}";
6250 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251 (const_string "incdec")
6252 (const_string "alu")))
6253 (set_attr "modrm" "1")
6254 (set_attr "mode" "QI")])
6256 (define_insn "*addqi_ext_2"
6257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6262 (match_operand 1 "ext_register_operand" "%0")
6266 (match_operand 2 "ext_register_operand" "Q")
6269 (clobber (reg:CC FLAGS_REG))]
6271 "add{b}\t{%h2, %h0|%h0, %h2}"
6272 [(set_attr "type" "alu")
6273 (set_attr "mode" "QI")])
6275 ;; The lea patterns for modes less than 32 bits need to be matched by
6276 ;; several insns converted to real lea by splitters.
6278 (define_insn_and_split "*lea_general_1"
6279 [(set (match_operand 0 "register_operand" "=r")
6280 (plus (plus (match_operand 1 "index_register_operand" "l")
6281 (match_operand 2 "register_operand" "r"))
6282 (match_operand 3 "immediate_operand" "i")))]
6283 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6284 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6285 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6286 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6287 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6288 || GET_MODE (operands[3]) == VOIDmode)"
6290 "&& reload_completed"
6293 enum machine_mode mode = SImode;
6296 operands[0] = gen_lowpart (mode, operands[0]);
6297 operands[1] = gen_lowpart (mode, operands[1]);
6298 operands[2] = gen_lowpart (mode, operands[2]);
6299 operands[3] = gen_lowpart (mode, operands[3]);
6301 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6304 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6307 [(set_attr "type" "lea")
6308 (set_attr "mode" "SI")])
6310 (define_insn_and_split "*lea_general_2"
6311 [(set (match_operand 0 "register_operand" "=r")
6312 (plus (mult (match_operand 1 "index_register_operand" "l")
6313 (match_operand 2 "const248_operand" "n"))
6314 (match_operand 3 "nonmemory_operand" "ri")))]
6315 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6316 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6317 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6318 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6319 || GET_MODE (operands[3]) == VOIDmode)"
6321 "&& reload_completed"
6324 enum machine_mode mode = SImode;
6327 operands[0] = gen_lowpart (mode, operands[0]);
6328 operands[1] = gen_lowpart (mode, operands[1]);
6329 operands[3] = gen_lowpart (mode, operands[3]);
6331 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6334 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6337 [(set_attr "type" "lea")
6338 (set_attr "mode" "SI")])
6340 (define_insn_and_split "*lea_general_3"
6341 [(set (match_operand 0 "register_operand" "=r")
6342 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6343 (match_operand 2 "const248_operand" "n"))
6344 (match_operand 3 "register_operand" "r"))
6345 (match_operand 4 "immediate_operand" "i")))]
6346 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6347 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6348 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6349 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6351 "&& reload_completed"
6354 enum machine_mode mode = SImode;
6357 operands[0] = gen_lowpart (mode, operands[0]);
6358 operands[1] = gen_lowpart (mode, operands[1]);
6359 operands[3] = gen_lowpart (mode, operands[3]);
6360 operands[4] = gen_lowpart (mode, operands[4]);
6362 pat = gen_rtx_PLUS (mode,
6364 gen_rtx_MULT (mode, operands[1],
6369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6372 [(set_attr "type" "lea")
6373 (set_attr "mode" "SI")])
6375 (define_insn_and_split "*lea_general_4"
6376 [(set (match_operand 0 "register_operand" "=r")
6378 (match_operand 1 "index_register_operand" "l")
6379 (match_operand 2 "const_int_operand" "n"))
6380 (match_operand 3 "const_int_operand" "n")))]
6381 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6382 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6383 || GET_MODE (operands[0]) == SImode
6384 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6385 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6386 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6387 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6388 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6390 "&& reload_completed"
6393 enum machine_mode mode = GET_MODE (operands[0]);
6396 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6399 operands[0] = gen_lowpart (mode, operands[0]);
6400 operands[1] = gen_lowpart (mode, operands[1]);
6403 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6405 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6406 INTVAL (operands[3]));
6408 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6411 [(set_attr "type" "lea")
6413 (if_then_else (match_operand:DI 0 "" "")
6415 (const_string "SI")))])
6417 ;; Subtract instructions
6419 (define_expand "sub<mode>3"
6420 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6421 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6422 (match_operand:SDWIM 2 "<general_operand>" "")))]
6424 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6426 (define_insn_and_split "*sub<dwi>3_doubleword"
6427 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6429 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6430 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6431 (clobber (reg:CC FLAGS_REG))]
6432 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6435 [(parallel [(set (reg:CC FLAGS_REG)
6436 (compare:CC (match_dup 1) (match_dup 2)))
6438 (minus:DWIH (match_dup 1) (match_dup 2)))])
6439 (parallel [(set (match_dup 3)
6443 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6445 (clobber (reg:CC FLAGS_REG))])]
6446 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6448 (define_insn "*sub<mode>_1"
6449 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6451 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6452 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6453 (clobber (reg:CC FLAGS_REG))]
6454 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6456 [(set_attr "type" "alu")
6457 (set_attr "mode" "<MODE>")])
6459 (define_insn "*subsi_1_zext"
6460 [(set (match_operand:DI 0 "register_operand" "=r")
6462 (minus:SI (match_operand:SI 1 "register_operand" "0")
6463 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %k0|%k0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6470 (define_insn "*subqi_1_slp"
6471 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6472 (minus:QI (match_dup 0)
6473 (match_operand:QI 1 "general_operand" "qn,qm")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6476 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6477 "sub{b}\t{%1, %0|%0, %1}"
6478 [(set_attr "type" "alu1")
6479 (set_attr "mode" "QI")])
6481 (define_insn "*sub<mode>_2"
6482 [(set (reg FLAGS_REG)
6485 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6488 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6489 (minus:SWI (match_dup 1) (match_dup 2)))]
6490 "ix86_match_ccmode (insn, CCGOCmode)
6491 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6492 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "<MODE>")])
6496 (define_insn "*subsi_2_zext"
6497 [(set (reg FLAGS_REG)
6499 (minus:SI (match_operand:SI 1 "register_operand" "0")
6500 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6502 (set (match_operand:DI 0 "register_operand" "=r")
6504 (minus:SI (match_dup 1)
6506 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6507 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6508 "sub{l}\t{%2, %k0|%k0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "mode" "SI")])
6512 (define_insn "*sub<mode>_3"
6513 [(set (reg FLAGS_REG)
6514 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6515 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6516 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6517 (minus:SWI (match_dup 1) (match_dup 2)))]
6518 "ix86_match_ccmode (insn, CCmode)
6519 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6520 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "<MODE>")])
6524 (define_insn "*subsi_3_zext"
6525 [(set (reg FLAGS_REG)
6526 (compare (match_operand:SI 1 "register_operand" "0")
6527 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6528 (set (match_operand:DI 0 "register_operand" "=r")
6530 (minus:SI (match_dup 1)
6532 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6533 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6534 "sub{l}\t{%2, %1|%1, %2}"
6535 [(set_attr "type" "alu")
6536 (set_attr "mode" "SI")])
6538 ;; Add with carry and subtract with borrow
6540 (define_expand "<plusminus_insn><mode>3_carry"
6542 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6544 (match_operand:SWI 1 "nonimmediate_operand" "")
6545 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6546 [(match_operand 3 "flags_reg_operand" "")
6548 (match_operand:SWI 2 "<general_operand>" ""))))
6549 (clobber (reg:CC FLAGS_REG))])]
6550 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6552 (define_insn "*<plusminus_insn><mode>3_carry"
6553 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6555 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6557 (match_operator 3 "ix86_carry_flag_operator"
6558 [(reg FLAGS_REG) (const_int 0)])
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "<MODE>")])
6568 (define_insn "*addsi3_carry_zext"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6571 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6572 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6573 [(reg FLAGS_REG) (const_int 0)])
6574 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6577 "adc{l}\t{%2, %k0|%k0, %2}"
6578 [(set_attr "type" "alu")
6579 (set_attr "use_carry" "1")
6580 (set_attr "pent_pair" "pu")
6581 (set_attr "mode" "SI")])
6583 (define_insn "*subsi3_carry_zext"
6584 [(set (match_operand:DI 0 "register_operand" "=r")
6586 (minus:SI (match_operand:SI 1 "register_operand" "0")
6587 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6588 [(reg FLAGS_REG) (const_int 0)])
6589 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6590 (clobber (reg:CC FLAGS_REG))]
6591 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592 "sbb{l}\t{%2, %k0|%k0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "pent_pair" "pu")
6595 (set_attr "mode" "SI")])
6597 ;; Overflow setting add and subtract instructions
6599 (define_insn "*add<mode>3_cconly_overflow"
6600 [(set (reg:CCC FLAGS_REG)
6603 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6604 (match_operand:SWI 2 "<general_operand>" "<g>"))
6606 (clobber (match_scratch:SWI 0 "=<r>"))]
6607 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6608 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "<MODE>")])
6612 (define_insn "*sub<mode>3_cconly_overflow"
6613 [(set (reg:CCC FLAGS_REG)
6616 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6617 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6620 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6621 [(set_attr "type" "icmp")
6622 (set_attr "mode" "<MODE>")])
6624 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6625 [(set (reg:CCC FLAGS_REG)
6628 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6629 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6631 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6632 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6633 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6634 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "mode" "<MODE>")])
6638 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6639 [(set (reg:CCC FLAGS_REG)
6642 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6643 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6645 (set (match_operand:DI 0 "register_operand" "=r")
6646 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6647 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6648 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6649 [(set_attr "type" "alu")
6650 (set_attr "mode" "SI")])
6652 ;; The patterns that match these are at the end of this file.
6654 (define_expand "<plusminus_insn>xf3"
6655 [(set (match_operand:XF 0 "register_operand" "")
6657 (match_operand:XF 1 "register_operand" "")
6658 (match_operand:XF 2 "register_operand" "")))]
6661 (define_expand "<plusminus_insn><mode>3"
6662 [(set (match_operand:MODEF 0 "register_operand" "")
6664 (match_operand:MODEF 1 "register_operand" "")
6665 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6666 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6667 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6669 ;; Multiply instructions
6671 (define_expand "mul<mode>3"
6672 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6674 (match_operand:SWIM248 1 "register_operand" "")
6675 (match_operand:SWIM248 2 "<general_operand>" "")))
6676 (clobber (reg:CC FLAGS_REG))])])
6678 (define_expand "mulqi3"
6679 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6681 (match_operand:QI 1 "register_operand" "")
6682 (match_operand:QI 2 "nonimmediate_operand" "")))
6683 (clobber (reg:CC FLAGS_REG))])]
6684 "TARGET_QIMODE_MATH")
6687 ;; IMUL reg32/64, reg32/64, imm8 Direct
6688 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6689 ;; IMUL reg32/64, reg32/64, imm32 Direct
6690 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6691 ;; IMUL reg32/64, reg32/64 Direct
6692 ;; IMUL reg32/64, mem32/64 Direct
6694 ;; On BDVER1, all above IMULs use DirectPath
6696 (define_insn "*mul<mode>3_1"
6697 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6699 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6700 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6701 (clobber (reg:CC FLAGS_REG))]
6702 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6704 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6705 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6706 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "imul")
6708 (set_attr "prefix_0f" "0,0,1")
6709 (set (attr "athlon_decode")
6710 (cond [(eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (eq_attr "alternative" "1")
6713 (const_string "vector")
6714 (and (eq_attr "alternative" "2")
6715 (match_operand 1 "memory_operand" ""))
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set (attr "amdfam10_decode")
6719 (cond [(and (eq_attr "alternative" "0,1")
6720 (match_operand 1 "memory_operand" ""))
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "direct")
6724 (set_attr "mode" "<MODE>")])
6726 (define_insn "*mulsi3_1_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6729 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6730 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6731 (clobber (reg:CC FLAGS_REG))]
6733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6736 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6737 imul{l}\t{%2, %k0|%k0, %2}"
6738 [(set_attr "type" "imul")
6739 (set_attr "prefix_0f" "0,0,1")
6740 (set (attr "athlon_decode")
6741 (cond [(eq_attr "cpu" "athlon")
6742 (const_string "vector")
6743 (eq_attr "alternative" "1")
6744 (const_string "vector")
6745 (and (eq_attr "alternative" "2")
6746 (match_operand 1 "memory_operand" ""))
6747 (const_string "vector")]
6748 (const_string "direct")))
6749 (set (attr "amdfam10_decode")
6750 (cond [(and (eq_attr "alternative" "0,1")
6751 (match_operand 1 "memory_operand" ""))
6752 (const_string "vector")]
6753 (const_string "direct")))
6754 (set_attr "bdver1_decode" "direct")
6755 (set_attr "mode" "SI")])
6758 ;; IMUL reg16, reg16, imm8 VectorPath
6759 ;; IMUL reg16, mem16, imm8 VectorPath
6760 ;; IMUL reg16, reg16, imm16 VectorPath
6761 ;; IMUL reg16, mem16, imm16 VectorPath
6762 ;; IMUL reg16, reg16 Direct
6763 ;; IMUL reg16, mem16 Direct
6765 ;; On BDVER1, all HI MULs use DoublePath
6767 (define_insn "*mulhi3_1"
6768 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6769 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6770 (match_operand:HI 2 "general_operand" "K,n,mr")))
6771 (clobber (reg:CC FLAGS_REG))]
6773 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 imul{w}\t{%2, %1, %0|%0, %1, %2}
6776 imul{w}\t{%2, %1, %0|%0, %1, %2}
6777 imul{w}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "imul")
6779 (set_attr "prefix_0f" "0,0,1")
6780 (set (attr "athlon_decode")
6781 (cond [(eq_attr "cpu" "athlon")
6782 (const_string "vector")
6783 (eq_attr "alternative" "1,2")
6784 (const_string "vector")]
6785 (const_string "direct")))
6786 (set (attr "amdfam10_decode")
6787 (cond [(eq_attr "alternative" "0,1")
6788 (const_string "vector")]
6789 (const_string "direct")))
6790 (set_attr "bdver1_decode" "double")
6791 (set_attr "mode" "HI")])
6793 ;;On AMDFAM10 and BDVER1
6797 (define_insn "*mulqi3_1"
6798 [(set (match_operand:QI 0 "register_operand" "=a")
6799 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6800 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6801 (clobber (reg:CC FLAGS_REG))]
6803 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6805 [(set_attr "type" "imul")
6806 (set_attr "length_immediate" "0")
6807 (set (attr "athlon_decode")
6808 (if_then_else (eq_attr "cpu" "athlon")
6809 (const_string "vector")
6810 (const_string "direct")))
6811 (set_attr "amdfam10_decode" "direct")
6812 (set_attr "bdver1_decode" "direct")
6813 (set_attr "mode" "QI")])
6815 (define_expand "<u>mul<mode><dwi>3"
6816 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6819 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6821 (match_operand:DWIH 2 "register_operand" ""))))
6822 (clobber (reg:CC FLAGS_REG))])])
6824 (define_expand "<u>mulqihi3"
6825 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6828 (match_operand:QI 1 "nonimmediate_operand" ""))
6830 (match_operand:QI 2 "register_operand" ""))))
6831 (clobber (reg:CC FLAGS_REG))])]
6832 "TARGET_QIMODE_MATH")
6834 (define_insn "*bmi2_umulditi3_1"
6835 [(set (match_operand:DI 0 "register_operand" "=r")
6837 (match_operand:DI 2 "nonimmediate_operand" "%d")
6838 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6839 (set (match_operand:DI 1 "register_operand" "=r")
6842 (mult:TI (zero_extend:TI (match_dup 2))
6843 (zero_extend:TI (match_dup 3)))
6845 "TARGET_64BIT && TARGET_BMI2
6846 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847 "mulx\t{%3, %0, %1|%1, %0, %3}"
6848 [(set_attr "type" "imulx")
6849 (set_attr "prefix" "vex")
6850 (set_attr "mode" "DI")])
6852 (define_insn "*bmi2_umulsidi3_1"
6853 [(set (match_operand:SI 0 "register_operand" "=r")
6855 (match_operand:SI 2 "nonimmediate_operand" "%d")
6856 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6857 (set (match_operand:SI 1 "register_operand" "=r")
6860 (mult:DI (zero_extend:DI (match_dup 2))
6861 (zero_extend:DI (match_dup 3)))
6863 "!TARGET_64BIT && TARGET_BMI2
6864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865 "mulx\t{%3, %0, %1|%1, %0, %3}"
6866 [(set_attr "type" "imulx")
6867 (set_attr "prefix" "vex")
6868 (set_attr "mode" "SI")])
6870 (define_insn "*umul<mode><dwi>3_1"
6871 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6874 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6876 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6877 (clobber (reg:CC FLAGS_REG))]
6878 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6880 mul{<imodesuffix>}\t%2
6882 [(set_attr "isa" "*,bmi2")
6883 (set_attr "type" "imul,imulx")
6884 (set_attr "length_immediate" "0,*")
6885 (set (attr "athlon_decode")
6886 (cond [(eq_attr "alternative" "0")
6887 (if_then_else (eq_attr "cpu" "athlon")
6888 (const_string "vector")
6889 (const_string "double"))]
6890 (const_string "*")))
6891 (set_attr "amdfam10_decode" "double,*")
6892 (set_attr "bdver1_decode" "direct,*")
6893 (set_attr "prefix" "orig,vex")
6894 (set_attr "mode" "<MODE>")])
6896 ;; Convert mul to the mulx pattern to avoid flags dependency.
6898 [(set (match_operand:<DWI> 0 "register_operand" "")
6901 (match_operand:DWIH 1 "register_operand" ""))
6903 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6904 (clobber (reg:CC FLAGS_REG))]
6905 "TARGET_BMI2 && reload_completed
6906 && true_regnum (operands[1]) == DX_REG"
6907 [(parallel [(set (match_dup 3)
6908 (mult:DWIH (match_dup 1) (match_dup 2)))
6912 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6913 (zero_extend:<DWI> (match_dup 2)))
6916 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6918 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6921 (define_insn "*mul<mode><dwi>3_1"
6922 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6925 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6927 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6928 (clobber (reg:CC FLAGS_REG))]
6929 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6930 "imul{<imodesuffix>}\t%2"
6931 [(set_attr "type" "imul")
6932 (set_attr "length_immediate" "0")
6933 (set (attr "athlon_decode")
6934 (if_then_else (eq_attr "cpu" "athlon")
6935 (const_string "vector")
6936 (const_string "double")))
6937 (set_attr "amdfam10_decode" "double")
6938 (set_attr "bdver1_decode" "direct")
6939 (set_attr "mode" "<MODE>")])
6941 (define_insn "*<u>mulqihi3_1"
6942 [(set (match_operand:HI 0 "register_operand" "=a")
6945 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6947 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6948 (clobber (reg:CC FLAGS_REG))]
6950 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "<sgnprefix>mul{b}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "direct")))
6958 (set_attr "amdfam10_decode" "direct")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "QI")])
6962 (define_expand "<s>mul<mode>3_highpart"
6963 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6968 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6970 (match_operand:SWI48 2 "register_operand" "")))
6972 (clobber (match_scratch:SWI48 3 ""))
6973 (clobber (reg:CC FLAGS_REG))])]
6975 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6977 (define_insn "*<s>muldi3_highpart_1"
6978 [(set (match_operand:DI 0 "register_operand" "=d")
6983 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6985 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6987 (clobber (match_scratch:DI 3 "=1"))
6988 (clobber (reg:CC FLAGS_REG))]
6990 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991 "<sgnprefix>mul{q}\t%2"
6992 [(set_attr "type" "imul")
6993 (set_attr "length_immediate" "0")
6994 (set (attr "athlon_decode")
6995 (if_then_else (eq_attr "cpu" "athlon")
6996 (const_string "vector")
6997 (const_string "double")))
6998 (set_attr "amdfam10_decode" "double")
6999 (set_attr "bdver1_decode" "direct")
7000 (set_attr "mode" "DI")])
7002 (define_insn "*<s>mulsi3_highpart_1"
7003 [(set (match_operand:SI 0 "register_operand" "=d")
7008 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7010 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7012 (clobber (match_scratch:SI 3 "=1"))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7015 "<sgnprefix>mul{l}\t%2"
7016 [(set_attr "type" "imul")
7017 (set_attr "length_immediate" "0")
7018 (set (attr "athlon_decode")
7019 (if_then_else (eq_attr "cpu" "athlon")
7020 (const_string "vector")
7021 (const_string "double")))
7022 (set_attr "amdfam10_decode" "double")
7023 (set_attr "bdver1_decode" "direct")
7024 (set_attr "mode" "SI")])
7026 (define_insn "*<s>mulsi3_highpart_zext"
7027 [(set (match_operand:DI 0 "register_operand" "=d")
7028 (zero_extend:DI (truncate:SI
7030 (mult:DI (any_extend:DI
7031 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7033 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7035 (clobber (match_scratch:SI 3 "=1"))
7036 (clobber (reg:CC FLAGS_REG))]
7038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 "<sgnprefix>mul{l}\t%2"
7040 [(set_attr "type" "imul")
7041 (set_attr "length_immediate" "0")
7042 (set (attr "athlon_decode")
7043 (if_then_else (eq_attr "cpu" "athlon")
7044 (const_string "vector")
7045 (const_string "double")))
7046 (set_attr "amdfam10_decode" "double")
7047 (set_attr "bdver1_decode" "direct")
7048 (set_attr "mode" "SI")])
7050 ;; The patterns that match these are at the end of this file.
7052 (define_expand "mulxf3"
7053 [(set (match_operand:XF 0 "register_operand" "")
7054 (mult:XF (match_operand:XF 1 "register_operand" "")
7055 (match_operand:XF 2 "register_operand" "")))]
7058 (define_expand "mul<mode>3"
7059 [(set (match_operand:MODEF 0 "register_operand" "")
7060 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7061 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7062 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7063 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7065 ;; Divide instructions
7067 ;; The patterns that match these are at the end of this file.
7069 (define_expand "divxf3"
7070 [(set (match_operand:XF 0 "register_operand" "")
7071 (div:XF (match_operand:XF 1 "register_operand" "")
7072 (match_operand:XF 2 "register_operand" "")))]
7075 (define_expand "divdf3"
7076 [(set (match_operand:DF 0 "register_operand" "")
7077 (div:DF (match_operand:DF 1 "register_operand" "")
7078 (match_operand:DF 2 "nonimmediate_operand" "")))]
7079 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7080 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7082 (define_expand "divsf3"
7083 [(set (match_operand:SF 0 "register_operand" "")
7084 (div:SF (match_operand:SF 1 "register_operand" "")
7085 (match_operand:SF 2 "nonimmediate_operand" "")))]
7086 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7091 && optimize_insn_for_speed_p ()
7092 && flag_finite_math_only && !flag_trapping_math
7093 && flag_unsafe_math_optimizations)
7095 ix86_emit_swdivsf (operands[0], operands[1],
7096 operands[2], SFmode);
7101 ;; Divmod instructions.
7103 (define_expand "divmod<mode>4"
7104 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7106 (match_operand:SWIM248 1 "register_operand" "")
7107 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7108 (set (match_operand:SWIM248 3 "register_operand" "")
7109 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7110 (clobber (reg:CC FLAGS_REG))])])
7112 ;; Split with 8bit unsigned divide:
7113 ;; if (dividend an divisor are in [0-255])
7114 ;; use 8bit unsigned integer divide
7116 ;; use original integer divide
7118 [(set (match_operand:SWI48 0 "register_operand" "")
7119 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7120 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7121 (set (match_operand:SWI48 1 "register_operand" "")
7122 (mod:SWI48 (match_dup 2) (match_dup 3)))
7123 (clobber (reg:CC FLAGS_REG))]
7124 "TARGET_USE_8BIT_IDIV
7125 && TARGET_QIMODE_MATH
7126 && can_create_pseudo_p ()
7127 && !optimize_insn_for_size_p ()"
7129 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7131 (define_insn_and_split "divmod<mode>4_1"
7132 [(set (match_operand:SWI48 0 "register_operand" "=a")
7133 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7134 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7135 (set (match_operand:SWI48 1 "register_operand" "=&d")
7136 (mod:SWI48 (match_dup 2) (match_dup 3)))
7137 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7138 (clobber (reg:CC FLAGS_REG))]
7142 [(parallel [(set (match_dup 1)
7143 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7144 (clobber (reg:CC FLAGS_REG))])
7145 (parallel [(set (match_dup 0)
7146 (div:SWI48 (match_dup 2) (match_dup 3)))
7148 (mod:SWI48 (match_dup 2) (match_dup 3)))
7150 (clobber (reg:CC FLAGS_REG))])]
7152 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7154 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7155 operands[4] = operands[2];
7158 /* Avoid use of cltd in favor of a mov+shift. */
7159 emit_move_insn (operands[1], operands[2]);
7160 operands[4] = operands[1];
7163 [(set_attr "type" "multi")
7164 (set_attr "mode" "<MODE>")])
7166 (define_insn_and_split "*divmod<mode>4"
7167 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7168 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7169 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7170 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7171 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7172 (clobber (reg:CC FLAGS_REG))]
7176 [(parallel [(set (match_dup 1)
7177 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7178 (clobber (reg:CC FLAGS_REG))])
7179 (parallel [(set (match_dup 0)
7180 (div:SWIM248 (match_dup 2) (match_dup 3)))
7182 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7184 (clobber (reg:CC FLAGS_REG))])]
7186 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7188 if (<MODE>mode != HImode
7189 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7190 operands[4] = operands[2];
7193 /* Avoid use of cltd in favor of a mov+shift. */
7194 emit_move_insn (operands[1], operands[2]);
7195 operands[4] = operands[1];
7198 [(set_attr "type" "multi")
7199 (set_attr "mode" "<MODE>")])
7201 (define_insn "*divmod<mode>4_noext"
7202 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7203 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7204 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7205 (set (match_operand:SWIM248 1 "register_operand" "=d")
7206 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7207 (use (match_operand:SWIM248 4 "register_operand" "1"))
7208 (clobber (reg:CC FLAGS_REG))]
7210 "idiv{<imodesuffix>}\t%3"
7211 [(set_attr "type" "idiv")
7212 (set_attr "mode" "<MODE>")])
7214 (define_expand "divmodqi4"
7215 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7217 (match_operand:QI 1 "register_operand" "")
7218 (match_operand:QI 2 "nonimmediate_operand" "")))
7219 (set (match_operand:QI 3 "register_operand" "")
7220 (mod:QI (match_dup 1) (match_dup 2)))
7221 (clobber (reg:CC FLAGS_REG))])]
7222 "TARGET_QIMODE_MATH"
7227 tmp0 = gen_reg_rtx (HImode);
7228 tmp1 = gen_reg_rtx (HImode);
7230 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7232 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7233 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7235 /* Extract remainder from AH. */
7236 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7237 insn = emit_move_insn (operands[3], tmp1);
7239 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7240 set_unique_reg_note (insn, REG_EQUAL, mod);
7242 /* Extract quotient from AL. */
7243 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7245 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7246 set_unique_reg_note (insn, REG_EQUAL, div);
7251 ;; Divide AX by r/m8, with result stored in
7254 ;; Change div/mod to HImode and extend the second argument to HImode
7255 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7256 ;; combine may fail.
7257 (define_insn "divmodhiqi3"
7258 [(set (match_operand:HI 0 "register_operand" "=a")
7263 (mod:HI (match_operand:HI 1 "register_operand" "0")
7265 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7269 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7270 (clobber (reg:CC FLAGS_REG))]
7271 "TARGET_QIMODE_MATH"
7273 [(set_attr "type" "idiv")
7274 (set_attr "mode" "QI")])
7276 (define_expand "udivmod<mode>4"
7277 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7279 (match_operand:SWIM248 1 "register_operand" "")
7280 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7281 (set (match_operand:SWIM248 3 "register_operand" "")
7282 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7283 (clobber (reg:CC FLAGS_REG))])])
7285 ;; Split with 8bit unsigned divide:
7286 ;; if (dividend an divisor are in [0-255])
7287 ;; use 8bit unsigned integer divide
7289 ;; use original integer divide
7291 [(set (match_operand:SWI48 0 "register_operand" "")
7292 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7293 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7294 (set (match_operand:SWI48 1 "register_operand" "")
7295 (umod:SWI48 (match_dup 2) (match_dup 3)))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "TARGET_USE_8BIT_IDIV
7298 && TARGET_QIMODE_MATH
7299 && can_create_pseudo_p ()
7300 && !optimize_insn_for_size_p ()"
7302 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7304 (define_insn_and_split "udivmod<mode>4_1"
7305 [(set (match_operand:SWI48 0 "register_operand" "=a")
7306 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7307 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7308 (set (match_operand:SWI48 1 "register_operand" "=&d")
7309 (umod:SWI48 (match_dup 2) (match_dup 3)))
7310 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7311 (clobber (reg:CC FLAGS_REG))]
7315 [(set (match_dup 1) (const_int 0))
7316 (parallel [(set (match_dup 0)
7317 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7319 (umod:SWI48 (match_dup 2) (match_dup 3)))
7321 (clobber (reg:CC FLAGS_REG))])]
7323 [(set_attr "type" "multi")
7324 (set_attr "mode" "<MODE>")])
7326 (define_insn_and_split "*udivmod<mode>4"
7327 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7328 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7329 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7330 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7331 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7332 (clobber (reg:CC FLAGS_REG))]
7336 [(set (match_dup 1) (const_int 0))
7337 (parallel [(set (match_dup 0)
7338 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7340 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7342 (clobber (reg:CC FLAGS_REG))])]
7344 [(set_attr "type" "multi")
7345 (set_attr "mode" "<MODE>")])
7347 (define_insn "*udivmod<mode>4_noext"
7348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351 (set (match_operand:SWIM248 1 "register_operand" "=d")
7352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353 (use (match_operand:SWIM248 4 "register_operand" "1"))
7354 (clobber (reg:CC FLAGS_REG))]
7356 "div{<imodesuffix>}\t%3"
7357 [(set_attr "type" "idiv")
7358 (set_attr "mode" "<MODE>")])
7360 (define_expand "udivmodqi4"
7361 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7363 (match_operand:QI 1 "register_operand" "")
7364 (match_operand:QI 2 "nonimmediate_operand" "")))
7365 (set (match_operand:QI 3 "register_operand" "")
7366 (umod:QI (match_dup 1) (match_dup 2)))
7367 (clobber (reg:CC FLAGS_REG))])]
7368 "TARGET_QIMODE_MATH"
7373 tmp0 = gen_reg_rtx (HImode);
7374 tmp1 = gen_reg_rtx (HImode);
7376 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7378 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7379 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7381 /* Extract remainder from AH. */
7382 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7383 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7384 insn = emit_move_insn (operands[3], tmp1);
7386 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7387 set_unique_reg_note (insn, REG_EQUAL, mod);
7389 /* Extract quotient from AL. */
7390 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7392 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7393 set_unique_reg_note (insn, REG_EQUAL, div);
7398 (define_insn "udivmodhiqi3"
7399 [(set (match_operand:HI 0 "register_operand" "=a")
7404 (mod:HI (match_operand:HI 1 "register_operand" "0")
7406 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7410 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7411 (clobber (reg:CC FLAGS_REG))]
7412 "TARGET_QIMODE_MATH"
7414 [(set_attr "type" "idiv")
7415 (set_attr "mode" "QI")])
7417 ;; We cannot use div/idiv for double division, because it causes
7418 ;; "division by zero" on the overflow and that's not what we expect
7419 ;; from truncate. Because true (non truncating) double division is
7420 ;; never generated, we can't create this insn anyway.
7423 ; [(set (match_operand:SI 0 "register_operand" "=a")
7425 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7427 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7428 ; (set (match_operand:SI 3 "register_operand" "=d")
7430 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7431 ; (clobber (reg:CC FLAGS_REG))]
7433 ; "div{l}\t{%2, %0|%0, %2}"
7434 ; [(set_attr "type" "idiv")])
7436 ;;- Logical AND instructions
7438 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7439 ;; Note that this excludes ah.
7441 (define_expand "testsi_ccno_1"
7442 [(set (reg:CCNO FLAGS_REG)
7444 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7445 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7448 (define_expand "testqi_ccz_1"
7449 [(set (reg:CCZ FLAGS_REG)
7450 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7451 (match_operand:QI 1 "nonmemory_operand" ""))
7454 (define_expand "testdi_ccno_1"
7455 [(set (reg:CCNO FLAGS_REG)
7457 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7458 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7460 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7462 (define_insn "*testdi_1"
7463 [(set (reg FLAGS_REG)
7466 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7467 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7469 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7470 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7472 test{l}\t{%k1, %k0|%k0, %k1}
7473 test{l}\t{%k1, %k0|%k0, %k1}
7474 test{q}\t{%1, %0|%0, %1}
7475 test{q}\t{%1, %0|%0, %1}
7476 test{q}\t{%1, %0|%0, %1}"
7477 [(set_attr "type" "test")
7478 (set_attr "modrm" "0,1,0,1,1")
7479 (set_attr "mode" "SI,SI,DI,DI,DI")])
7481 (define_insn "*testqi_1_maybe_si"
7482 [(set (reg FLAGS_REG)
7485 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7486 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7488 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7489 && ix86_match_ccmode (insn,
7490 CONST_INT_P (operands[1])
7491 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7493 if (which_alternative == 3)
7495 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7496 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7497 return "test{l}\t{%1, %k0|%k0, %1}";
7499 return "test{b}\t{%1, %0|%0, %1}";
7501 [(set_attr "type" "test")
7502 (set_attr "modrm" "0,1,1,1")
7503 (set_attr "mode" "QI,QI,QI,SI")
7504 (set_attr "pent_pair" "uv,np,uv,np")])
7506 (define_insn "*test<mode>_1"
7507 [(set (reg FLAGS_REG)
7510 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7511 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7513 "ix86_match_ccmode (insn, CCNOmode)
7514 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7515 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7516 [(set_attr "type" "test")
7517 (set_attr "modrm" "0,1,1")
7518 (set_attr "mode" "<MODE>")
7519 (set_attr "pent_pair" "uv,np,uv")])
7521 (define_expand "testqi_ext_ccno_0"
7522 [(set (reg:CCNO FLAGS_REG)
7526 (match_operand 0 "ext_register_operand" "")
7529 (match_operand 1 "const_int_operand" ""))
7532 (define_insn "*testqi_ext_0"
7533 [(set (reg FLAGS_REG)
7537 (match_operand 0 "ext_register_operand" "Q")
7540 (match_operand 1 "const_int_operand" "n"))
7542 "ix86_match_ccmode (insn, CCNOmode)"
7543 "test{b}\t{%1, %h0|%h0, %1}"
7544 [(set_attr "type" "test")
7545 (set_attr "mode" "QI")
7546 (set_attr "length_immediate" "1")
7547 (set_attr "modrm" "1")
7548 (set_attr "pent_pair" "np")])
7550 (define_insn "*testqi_ext_1_rex64"
7551 [(set (reg FLAGS_REG)
7555 (match_operand 0 "ext_register_operand" "Q")
7559 (match_operand:QI 1 "register_operand" "Q")))
7561 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7562 "test{b}\t{%1, %h0|%h0, %1}"
7563 [(set_attr "type" "test")
7564 (set_attr "mode" "QI")])
7566 (define_insn "*testqi_ext_1"
7567 [(set (reg FLAGS_REG)
7571 (match_operand 0 "ext_register_operand" "Q")
7575 (match_operand:QI 1 "general_operand" "Qm")))
7577 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7578 "test{b}\t{%1, %h0|%h0, %1}"
7579 [(set_attr "type" "test")
7580 (set_attr "mode" "QI")])
7582 (define_insn "*testqi_ext_2"
7583 [(set (reg FLAGS_REG)
7587 (match_operand 0 "ext_register_operand" "Q")
7591 (match_operand 1 "ext_register_operand" "Q")
7595 "ix86_match_ccmode (insn, CCNOmode)"
7596 "test{b}\t{%h1, %h0|%h0, %h1}"
7597 [(set_attr "type" "test")
7598 (set_attr "mode" "QI")])
7600 (define_insn "*testqi_ext_3_rex64"
7601 [(set (reg FLAGS_REG)
7602 (compare (zero_extract:DI
7603 (match_operand 0 "nonimmediate_operand" "rm")
7604 (match_operand:DI 1 "const_int_operand" "")
7605 (match_operand:DI 2 "const_int_operand" ""))
7608 && ix86_match_ccmode (insn, CCNOmode)
7609 && INTVAL (operands[1]) > 0
7610 && INTVAL (operands[2]) >= 0
7611 /* Ensure that resulting mask is zero or sign extended operand. */
7612 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7613 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7614 && INTVAL (operands[1]) > 32))
7615 && (GET_MODE (operands[0]) == SImode
7616 || GET_MODE (operands[0]) == DImode
7617 || GET_MODE (operands[0]) == HImode
7618 || GET_MODE (operands[0]) == QImode)"
7621 ;; Combine likes to form bit extractions for some tests. Humor it.
7622 (define_insn "*testqi_ext_3"
7623 [(set (reg FLAGS_REG)
7624 (compare (zero_extract:SI
7625 (match_operand 0 "nonimmediate_operand" "rm")
7626 (match_operand:SI 1 "const_int_operand" "")
7627 (match_operand:SI 2 "const_int_operand" ""))
7629 "ix86_match_ccmode (insn, CCNOmode)
7630 && INTVAL (operands[1]) > 0
7631 && INTVAL (operands[2]) >= 0
7632 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7633 && (GET_MODE (operands[0]) == SImode
7634 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7635 || GET_MODE (operands[0]) == HImode
7636 || GET_MODE (operands[0]) == QImode)"
7640 [(set (match_operand 0 "flags_reg_operand" "")
7641 (match_operator 1 "compare_operator"
7643 (match_operand 2 "nonimmediate_operand" "")
7644 (match_operand 3 "const_int_operand" "")
7645 (match_operand 4 "const_int_operand" ""))
7647 "ix86_match_ccmode (insn, CCNOmode)"
7648 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7650 rtx val = operands[2];
7651 HOST_WIDE_INT len = INTVAL (operands[3]);
7652 HOST_WIDE_INT pos = INTVAL (operands[4]);
7654 enum machine_mode mode, submode;
7656 mode = GET_MODE (val);
7659 /* ??? Combine likes to put non-volatile mem extractions in QImode
7660 no matter the size of the test. So find a mode that works. */
7661 if (! MEM_VOLATILE_P (val))
7663 mode = smallest_mode_for_size (pos + len, MODE_INT);
7664 val = adjust_address (val, mode, 0);
7667 else if (GET_CODE (val) == SUBREG
7668 && (submode = GET_MODE (SUBREG_REG (val)),
7669 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7670 && pos + len <= GET_MODE_BITSIZE (submode)
7671 && GET_MODE_CLASS (submode) == MODE_INT)
7673 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7675 val = SUBREG_REG (val);
7677 else if (mode == HImode && pos + len <= 8)
7679 /* Small HImode tests can be converted to QImode. */
7681 val = gen_lowpart (QImode, val);
7684 if (len == HOST_BITS_PER_WIDE_INT)
7687 mask = ((HOST_WIDE_INT)1 << len) - 1;
7690 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7693 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7694 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7695 ;; this is relatively important trick.
7696 ;; Do the conversion only post-reload to avoid limiting of the register class
7699 [(set (match_operand 0 "flags_reg_operand" "")
7700 (match_operator 1 "compare_operator"
7701 [(and (match_operand 2 "register_operand" "")
7702 (match_operand 3 "const_int_operand" ""))
7705 && QI_REG_P (operands[2])
7706 && GET_MODE (operands[2]) != QImode
7707 && ((ix86_match_ccmode (insn, CCZmode)
7708 && !(INTVAL (operands[3]) & ~(255 << 8)))
7709 || (ix86_match_ccmode (insn, CCNOmode)
7710 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7713 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7717 operands[2] = gen_lowpart (SImode, operands[2]);
7718 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7722 [(set (match_operand 0 "flags_reg_operand" "")
7723 (match_operator 1 "compare_operator"
7724 [(and (match_operand 2 "nonimmediate_operand" "")
7725 (match_operand 3 "const_int_operand" ""))
7728 && GET_MODE (operands[2]) != QImode
7729 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7730 && ((ix86_match_ccmode (insn, CCZmode)
7731 && !(INTVAL (operands[3]) & ~255))
7732 || (ix86_match_ccmode (insn, CCNOmode)
7733 && !(INTVAL (operands[3]) & ~127)))"
7735 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7738 operands[2] = gen_lowpart (QImode, operands[2]);
7739 operands[3] = gen_lowpart (QImode, operands[3]);
7742 ;; %%% This used to optimize known byte-wide and operations to memory,
7743 ;; and sometimes to QImode registers. If this is considered useful,
7744 ;; it should be done with splitters.
7746 (define_expand "and<mode>3"
7747 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7748 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7749 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7751 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7753 (define_insn "*anddi_1"
7754 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7756 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7757 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7761 switch (get_attr_type (insn))
7765 enum machine_mode mode;
7767 gcc_assert (CONST_INT_P (operands[2]));
7768 if (INTVAL (operands[2]) == 0xff)
7772 gcc_assert (INTVAL (operands[2]) == 0xffff);
7776 operands[1] = gen_lowpart (mode, operands[1]);
7778 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7780 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7785 if (get_attr_mode (insn) == MODE_SI)
7786 return "and{l}\t{%k2, %k0|%k0, %k2}";
7788 return "and{q}\t{%2, %0|%0, %2}";
7791 [(set_attr "type" "alu,alu,alu,imovx")
7792 (set_attr "length_immediate" "*,*,*,0")
7793 (set (attr "prefix_rex")
7795 (and (eq_attr "type" "imovx")
7796 (and (match_test "INTVAL (operands[2]) == 0xff")
7797 (match_operand 1 "ext_QIreg_operand" "")))
7799 (const_string "*")))
7800 (set_attr "mode" "SI,DI,DI,SI")])
7802 (define_insn "*andsi_1"
7803 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7805 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "ix86_binary_operator_ok (AND, SImode, operands)"
7809 switch (get_attr_type (insn))
7813 enum machine_mode mode;
7815 gcc_assert (CONST_INT_P (operands[2]));
7816 if (INTVAL (operands[2]) == 0xff)
7820 gcc_assert (INTVAL (operands[2]) == 0xffff);
7824 operands[1] = gen_lowpart (mode, operands[1]);
7826 return "movz{bl|x}\t{%1, %0|%0, %1}";
7828 return "movz{wl|x}\t{%1, %0|%0, %1}";
7832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7833 return "and{l}\t{%2, %0|%0, %2}";
7836 [(set_attr "type" "alu,alu,imovx")
7837 (set (attr "prefix_rex")
7839 (and (eq_attr "type" "imovx")
7840 (and (match_test "INTVAL (operands[2]) == 0xff")
7841 (match_operand 1 "ext_QIreg_operand" "")))
7843 (const_string "*")))
7844 (set_attr "length_immediate" "*,*,0")
7845 (set_attr "mode" "SI")])
7847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7848 (define_insn "*andsi_1_zext"
7849 [(set (match_operand:DI 0 "register_operand" "=r")
7851 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7852 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7855 "and{l}\t{%2, %k0|%k0, %2}"
7856 [(set_attr "type" "alu")
7857 (set_attr "mode" "SI")])
7859 (define_insn "*andhi_1"
7860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7861 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7862 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7863 (clobber (reg:CC FLAGS_REG))]
7864 "ix86_binary_operator_ok (AND, HImode, operands)"
7866 switch (get_attr_type (insn))
7869 gcc_assert (CONST_INT_P (operands[2]));
7870 gcc_assert (INTVAL (operands[2]) == 0xff);
7871 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7874 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7876 return "and{w}\t{%2, %0|%0, %2}";
7879 [(set_attr "type" "alu,alu,imovx")
7880 (set_attr "length_immediate" "*,*,0")
7881 (set (attr "prefix_rex")
7883 (and (eq_attr "type" "imovx")
7884 (match_operand 1 "ext_QIreg_operand" ""))
7886 (const_string "*")))
7887 (set_attr "mode" "HI,HI,SI")])
7889 ;; %%% Potential partial reg stall on alternative 2. What to do?
7890 (define_insn "*andqi_1"
7891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7892 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "ix86_binary_operator_ok (AND, QImode, operands)"
7897 and{b}\t{%2, %0|%0, %2}
7898 and{b}\t{%2, %0|%0, %2}
7899 and{l}\t{%k2, %k0|%k0, %k2}"
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "QI,QI,SI")])
7903 (define_insn "*andqi_1_slp"
7904 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7905 (and:QI (match_dup 0)
7906 (match_operand:QI 1 "general_operand" "qn,qmn")))
7907 (clobber (reg:CC FLAGS_REG))]
7908 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7910 "and{b}\t{%1, %0|%0, %1}"
7911 [(set_attr "type" "alu1")
7912 (set_attr "mode" "QI")])
7915 [(set (match_operand 0 "register_operand" "")
7917 (const_int -65536)))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7920 || optimize_function_for_size_p (cfun)"
7921 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7922 "operands[1] = gen_lowpart (HImode, operands[0]);")
7925 [(set (match_operand 0 "ext_register_operand" "")
7928 (clobber (reg:CC FLAGS_REG))]
7929 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7930 && reload_completed"
7931 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932 "operands[1] = gen_lowpart (QImode, operands[0]);")
7935 [(set (match_operand 0 "ext_register_operand" "")
7937 (const_int -65281)))
7938 (clobber (reg:CC FLAGS_REG))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && reload_completed"
7941 [(parallel [(set (zero_extract:SI (match_dup 0)
7945 (zero_extract:SI (match_dup 0)
7948 (zero_extract:SI (match_dup 0)
7951 (clobber (reg:CC FLAGS_REG))])]
7952 "operands[0] = gen_lowpart (SImode, operands[0]);")
7954 (define_insn "*anddi_2"
7955 [(set (reg FLAGS_REG)
7958 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7959 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7961 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7962 (and:DI (match_dup 1) (match_dup 2)))]
7963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7964 && ix86_binary_operator_ok (AND, DImode, operands)"
7966 and{l}\t{%k2, %k0|%k0, %k2}
7967 and{q}\t{%2, %0|%0, %2}
7968 and{q}\t{%2, %0|%0, %2}"
7969 [(set_attr "type" "alu")
7970 (set_attr "mode" "SI,DI,DI")])
7972 (define_insn "*andqi_2_maybe_si"
7973 [(set (reg FLAGS_REG)
7975 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7978 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7979 (and:QI (match_dup 1) (match_dup 2)))]
7980 "ix86_binary_operator_ok (AND, QImode, operands)
7981 && ix86_match_ccmode (insn,
7982 CONST_INT_P (operands[2])
7983 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7985 if (which_alternative == 2)
7987 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7988 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7989 return "and{l}\t{%2, %k0|%k0, %2}";
7991 return "and{b}\t{%2, %0|%0, %2}";
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "QI,QI,SI")])
7996 (define_insn "*and<mode>_2"
7997 [(set (reg FLAGS_REG)
7998 (compare (and:SWI124
7999 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8000 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8002 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8003 (and:SWI124 (match_dup 1) (match_dup 2)))]
8004 "ix86_match_ccmode (insn, CCNOmode)
8005 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8006 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8007 [(set_attr "type" "alu")
8008 (set_attr "mode" "<MODE>")])
8010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8011 (define_insn "*andsi_2_zext"
8012 [(set (reg FLAGS_REG)
8014 (match_operand:SI 1 "nonimmediate_operand" "%0")
8015 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8017 (set (match_operand:DI 0 "register_operand" "=r")
8018 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8019 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8020 && ix86_binary_operator_ok (AND, SImode, operands)"
8021 "and{l}\t{%2, %k0|%k0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "SI")])
8025 (define_insn "*andqi_2_slp"
8026 [(set (reg FLAGS_REG)
8028 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8029 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8031 (set (strict_low_part (match_dup 0))
8032 (and:QI (match_dup 0) (match_dup 1)))]
8033 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034 && ix86_match_ccmode (insn, CCNOmode)
8035 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8036 "and{b}\t{%1, %0|%0, %1}"
8037 [(set_attr "type" "alu1")
8038 (set_attr "mode" "QI")])
8040 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8041 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8042 ;; for a QImode operand, which of course failed.
8043 (define_insn "andqi_ext_0"
8044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8049 (match_operand 1 "ext_register_operand" "0")
8052 (match_operand 2 "const_int_operand" "n")))
8053 (clobber (reg:CC FLAGS_REG))]
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8061 ;; Generated by peephole translating test to and. This shows up
8062 ;; often in fp comparisons.
8063 (define_insn "*andqi_ext_0_cc"
8064 [(set (reg FLAGS_REG)
8068 (match_operand 1 "ext_register_operand" "0")
8071 (match_operand 2 "const_int_operand" "n"))
8073 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082 "ix86_match_ccmode (insn, CCNOmode)"
8083 "and{b}\t{%2, %h0|%h0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "length_immediate" "1")
8086 (set_attr "modrm" "1")
8087 (set_attr "mode" "QI")])
8089 (define_insn "*andqi_ext_1_rex64"
8090 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8095 (match_operand 1 "ext_register_operand" "0")
8099 (match_operand 2 "ext_register_operand" "Q"))))
8100 (clobber (reg:CC FLAGS_REG))]
8102 "and{b}\t{%2, %h0|%h0, %2}"
8103 [(set_attr "type" "alu")
8104 (set_attr "length_immediate" "0")
8105 (set_attr "mode" "QI")])
8107 (define_insn "*andqi_ext_1"
8108 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8113 (match_operand 1 "ext_register_operand" "0")
8117 (match_operand:QI 2 "general_operand" "Qm"))))
8118 (clobber (reg:CC FLAGS_REG))]
8120 "and{b}\t{%2, %h0|%h0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "length_immediate" "0")
8123 (set_attr "mode" "QI")])
8125 (define_insn "*andqi_ext_2"
8126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8131 (match_operand 1 "ext_register_operand" "%0")
8135 (match_operand 2 "ext_register_operand" "Q")
8138 (clobber (reg:CC FLAGS_REG))]
8140 "and{b}\t{%h2, %h0|%h0, %h2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "length_immediate" "0")
8143 (set_attr "mode" "QI")])
8145 ;; Convert wide AND instructions with immediate operand to shorter QImode
8146 ;; equivalents when possible.
8147 ;; Don't do the splitting with memory operands, since it introduces risk
8148 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8149 ;; for size, but that can (should?) be handled by generic code instead.
8151 [(set (match_operand 0 "register_operand" "")
8152 (and (match_operand 1 "register_operand" "")
8153 (match_operand 2 "const_int_operand" "")))
8154 (clobber (reg:CC FLAGS_REG))]
8156 && QI_REG_P (operands[0])
8157 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(~INTVAL (operands[2]) & ~(255 << 8))
8159 && GET_MODE (operands[0]) != QImode"
8160 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8161 (and:SI (zero_extract:SI (match_dup 1)
8162 (const_int 8) (const_int 8))
8164 (clobber (reg:CC FLAGS_REG))])]
8166 operands[0] = gen_lowpart (SImode, operands[0]);
8167 operands[1] = gen_lowpart (SImode, operands[1]);
8168 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8171 ;; Since AND can be encoded with sign extended immediate, this is only
8172 ;; profitable when 7th bit is not set.
8174 [(set (match_operand 0 "register_operand" "")
8175 (and (match_operand 1 "general_operand" "")
8176 (match_operand 2 "const_int_operand" "")))
8177 (clobber (reg:CC FLAGS_REG))]
8179 && ANY_QI_REG_P (operands[0])
8180 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8181 && !(~INTVAL (operands[2]) & ~255)
8182 && !(INTVAL (operands[2]) & 128)
8183 && GET_MODE (operands[0]) != QImode"
8184 [(parallel [(set (strict_low_part (match_dup 0))
8185 (and:QI (match_dup 1)
8187 (clobber (reg:CC FLAGS_REG))])]
8189 operands[0] = gen_lowpart (QImode, operands[0]);
8190 operands[1] = gen_lowpart (QImode, operands[1]);
8191 operands[2] = gen_lowpart (QImode, operands[2]);
8194 ;; Logical inclusive and exclusive OR instructions
8196 ;; %%% This used to optimize known byte-wide and operations to memory.
8197 ;; If this is considered useful, it should be done with splitters.
8199 (define_expand "<code><mode>3"
8200 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8201 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8202 (match_operand:SWIM 2 "<general_operand>" "")))]
8204 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8206 (define_insn "*<code><mode>_1"
8207 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8209 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8210 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8213 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "mode" "<MODE>")])
8217 ;; %%% Potential partial reg stall on alternative 2. What to do?
8218 (define_insn "*<code>qi_1"
8219 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8220 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8221 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8222 (clobber (reg:CC FLAGS_REG))]
8223 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8225 <logic>{b}\t{%2, %0|%0, %2}
8226 <logic>{b}\t{%2, %0|%0, %2}
8227 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "QI,QI,SI")])
8231 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8232 (define_insn "*<code>si_1_zext"
8233 [(set (match_operand:DI 0 "register_operand" "=r")
8235 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8236 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8239 "<logic>{l}\t{%2, %k0|%k0, %2}"
8240 [(set_attr "type" "alu")
8241 (set_attr "mode" "SI")])
8243 (define_insn "*<code>si_1_zext_imm"
8244 [(set (match_operand:DI 0 "register_operand" "=r")
8246 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8247 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8250 "<logic>{l}\t{%2, %k0|%k0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "SI")])
8254 (define_insn "*<code>qi_1_slp"
8255 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8256 (any_or:QI (match_dup 0)
8257 (match_operand:QI 1 "general_operand" "qmn,qn")))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8261 "<logic>{b}\t{%1, %0|%0, %1}"
8262 [(set_attr "type" "alu1")
8263 (set_attr "mode" "QI")])
8265 (define_insn "*<code><mode>_2"
8266 [(set (reg FLAGS_REG)
8267 (compare (any_or:SWI
8268 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8269 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8271 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8272 (any_or:SWI (match_dup 1) (match_dup 2)))]
8273 "ix86_match_ccmode (insn, CCNOmode)
8274 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8275 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "<MODE>")])
8279 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8280 ;; ??? Special case for immediate operand is missing - it is tricky.
8281 (define_insn "*<code>si_2_zext"
8282 [(set (reg FLAGS_REG)
8283 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8286 (set (match_operand:DI 0 "register_operand" "=r")
8287 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8288 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8289 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8290 "<logic>{l}\t{%2, %k0|%k0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "SI")])
8294 (define_insn "*<code>si_2_zext_imm"
8295 [(set (reg FLAGS_REG)
8297 (match_operand:SI 1 "nonimmediate_operand" "%0")
8298 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8300 (set (match_operand:DI 0 "register_operand" "=r")
8301 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8302 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8304 "<logic>{l}\t{%2, %k0|%k0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8308 (define_insn "*<code>qi_2_slp"
8309 [(set (reg FLAGS_REG)
8310 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8311 (match_operand:QI 1 "general_operand" "qmn,qn"))
8313 (set (strict_low_part (match_dup 0))
8314 (any_or:QI (match_dup 0) (match_dup 1)))]
8315 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8316 && ix86_match_ccmode (insn, CCNOmode)
8317 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8318 "<logic>{b}\t{%1, %0|%0, %1}"
8319 [(set_attr "type" "alu1")
8320 (set_attr "mode" "QI")])
8322 (define_insn "*<code><mode>_3"
8323 [(set (reg FLAGS_REG)
8324 (compare (any_or:SWI
8325 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8326 (match_operand:SWI 2 "<general_operand>" "<g>"))
8328 (clobber (match_scratch:SWI 0 "=<r>"))]
8329 "ix86_match_ccmode (insn, CCNOmode)
8330 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8331 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8332 [(set_attr "type" "alu")
8333 (set_attr "mode" "<MODE>")])
8335 (define_insn "*<code>qi_ext_0"
8336 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8341 (match_operand 1 "ext_register_operand" "0")
8344 (match_operand 2 "const_int_operand" "n")))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8347 "<logic>{b}\t{%2, %h0|%h0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "length_immediate" "1")
8350 (set_attr "modrm" "1")
8351 (set_attr "mode" "QI")])
8353 (define_insn "*<code>qi_ext_1_rex64"
8354 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359 (match_operand 1 "ext_register_operand" "0")
8363 (match_operand 2 "ext_register_operand" "Q"))))
8364 (clobber (reg:CC FLAGS_REG))]
8366 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8367 "<logic>{b}\t{%2, %h0|%h0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "length_immediate" "0")
8370 (set_attr "mode" "QI")])
8372 (define_insn "*<code>qi_ext_1"
8373 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8378 (match_operand 1 "ext_register_operand" "0")
8382 (match_operand:QI 2 "general_operand" "Qm"))))
8383 (clobber (reg:CC FLAGS_REG))]
8385 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8386 "<logic>{b}\t{%2, %h0|%h0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "length_immediate" "0")
8389 (set_attr "mode" "QI")])
8391 (define_insn "*<code>qi_ext_2"
8392 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8399 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8402 (clobber (reg:CC FLAGS_REG))]
8403 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8404 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "length_immediate" "0")
8407 (set_attr "mode" "QI")])
8410 [(set (match_operand 0 "register_operand" "")
8411 (any_or (match_operand 1 "register_operand" "")
8412 (match_operand 2 "const_int_operand" "")))
8413 (clobber (reg:CC FLAGS_REG))]
8415 && QI_REG_P (operands[0])
8416 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8417 && !(INTVAL (operands[2]) & ~(255 << 8))
8418 && GET_MODE (operands[0]) != QImode"
8419 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8420 (any_or:SI (zero_extract:SI (match_dup 1)
8421 (const_int 8) (const_int 8))
8423 (clobber (reg:CC FLAGS_REG))])]
8425 operands[0] = gen_lowpart (SImode, operands[0]);
8426 operands[1] = gen_lowpart (SImode, operands[1]);
8427 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8430 ;; Since OR can be encoded with sign extended immediate, this is only
8431 ;; profitable when 7th bit is set.
8433 [(set (match_operand 0 "register_operand" "")
8434 (any_or (match_operand 1 "general_operand" "")
8435 (match_operand 2 "const_int_operand" "")))
8436 (clobber (reg:CC FLAGS_REG))]
8438 && ANY_QI_REG_P (operands[0])
8439 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8440 && !(INTVAL (operands[2]) & ~255)
8441 && (INTVAL (operands[2]) & 128)
8442 && GET_MODE (operands[0]) != QImode"
8443 [(parallel [(set (strict_low_part (match_dup 0))
8444 (any_or:QI (match_dup 1)
8446 (clobber (reg:CC FLAGS_REG))])]
8448 operands[0] = gen_lowpart (QImode, operands[0]);
8449 operands[1] = gen_lowpart (QImode, operands[1]);
8450 operands[2] = gen_lowpart (QImode, operands[2]);
8453 (define_expand "xorqi_cc_ext_1"
8455 (set (reg:CCNO FLAGS_REG)
8459 (match_operand 1 "ext_register_operand" "")
8462 (match_operand:QI 2 "general_operand" ""))
8464 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8474 (define_insn "*xorqi_cc_ext_1_rex64"
8475 [(set (reg FLAGS_REG)
8479 (match_operand 1 "ext_register_operand" "0")
8482 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8484 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8494 "xor{b}\t{%2, %h0|%h0, %2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "modrm" "1")
8497 (set_attr "mode" "QI")])
8499 (define_insn "*xorqi_cc_ext_1"
8500 [(set (reg FLAGS_REG)
8504 (match_operand 1 "ext_register_operand" "0")
8507 (match_operand:QI 2 "general_operand" "qmn"))
8509 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8518 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8519 "xor{b}\t{%2, %h0|%h0, %2}"
8520 [(set_attr "type" "alu")
8521 (set_attr "modrm" "1")
8522 (set_attr "mode" "QI")])
8524 ;; Negation instructions
8526 (define_expand "neg<mode>2"
8527 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8528 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8530 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8532 (define_insn_and_split "*neg<dwi>2_doubleword"
8533 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8534 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8540 [(set (reg:CCZ FLAGS_REG)
8541 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8542 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8545 (plus:DWIH (match_dup 3)
8546 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8548 (clobber (reg:CC FLAGS_REG))])
8551 (neg:DWIH (match_dup 2)))
8552 (clobber (reg:CC FLAGS_REG))])]
8553 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8555 (define_insn "*neg<mode>2_1"
8556 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8557 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8558 (clobber (reg:CC FLAGS_REG))]
8559 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8560 "neg{<imodesuffix>}\t%0"
8561 [(set_attr "type" "negnot")
8562 (set_attr "mode" "<MODE>")])
8564 ;; Combine is quite creative about this pattern.
8565 (define_insn "*negsi2_1_zext"
8566 [(set (match_operand:DI 0 "register_operand" "=r")
8568 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8571 (clobber (reg:CC FLAGS_REG))]
8572 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8574 [(set_attr "type" "negnot")
8575 (set_attr "mode" "SI")])
8577 ;; The problem with neg is that it does not perform (compare x 0),
8578 ;; it really performs (compare 0 x), which leaves us with the zero
8579 ;; flag being the only useful item.
8581 (define_insn "*neg<mode>2_cmpz"
8582 [(set (reg:CCZ FLAGS_REG)
8584 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8586 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8587 (neg:SWI (match_dup 1)))]
8588 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8589 "neg{<imodesuffix>}\t%0"
8590 [(set_attr "type" "negnot")
8591 (set_attr "mode" "<MODE>")])
8593 (define_insn "*negsi2_cmpz_zext"
8594 [(set (reg:CCZ FLAGS_REG)
8598 (match_operand:DI 1 "register_operand" "0")
8602 (set (match_operand:DI 0 "register_operand" "=r")
8603 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8606 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8608 [(set_attr "type" "negnot")
8609 (set_attr "mode" "SI")])
8611 ;; Changing of sign for FP values is doable using integer unit too.
8613 (define_expand "<code><mode>2"
8614 [(set (match_operand:X87MODEF 0 "register_operand" "")
8615 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8616 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8619 (define_insn "*absneg<mode>2_mixed"
8620 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8621 (match_operator:MODEF 3 "absneg_operator"
8622 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8623 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8628 (define_insn "*absneg<mode>2_sse"
8629 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8630 (match_operator:MODEF 3 "absneg_operator"
8631 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8632 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8633 (clobber (reg:CC FLAGS_REG))]
8634 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8637 (define_insn "*absneg<mode>2_i387"
8638 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8639 (match_operator:X87MODEF 3 "absneg_operator"
8640 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8641 (use (match_operand 2 "" ""))
8642 (clobber (reg:CC FLAGS_REG))]
8643 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8646 (define_expand "<code>tf2"
8647 [(set (match_operand:TF 0 "register_operand" "")
8648 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8650 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8652 (define_insn "*absnegtf2_sse"
8653 [(set (match_operand:TF 0 "register_operand" "=x,x")
8654 (match_operator:TF 3 "absneg_operator"
8655 [(match_operand:TF 1 "register_operand" "0,x")]))
8656 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8657 (clobber (reg:CC FLAGS_REG))]
8661 ;; Splitters for fp abs and neg.
8664 [(set (match_operand 0 "fp_register_operand" "")
8665 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8666 (use (match_operand 2 "" ""))
8667 (clobber (reg:CC FLAGS_REG))]
8669 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8672 [(set (match_operand 0 "register_operand" "")
8673 (match_operator 3 "absneg_operator"
8674 [(match_operand 1 "register_operand" "")]))
8675 (use (match_operand 2 "nonimmediate_operand" ""))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "reload_completed && SSE_REG_P (operands[0])"
8678 [(set (match_dup 0) (match_dup 3))]
8680 enum machine_mode mode = GET_MODE (operands[0]);
8681 enum machine_mode vmode = GET_MODE (operands[2]);
8684 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8685 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8686 if (operands_match_p (operands[0], operands[2]))
8689 operands[1] = operands[2];
8692 if (GET_CODE (operands[3]) == ABS)
8693 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8695 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8700 [(set (match_operand:SF 0 "register_operand" "")
8701 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8702 (use (match_operand:V4SF 2 "" ""))
8703 (clobber (reg:CC FLAGS_REG))]
8705 [(parallel [(set (match_dup 0) (match_dup 1))
8706 (clobber (reg:CC FLAGS_REG))])]
8709 operands[0] = gen_lowpart (SImode, operands[0]);
8710 if (GET_CODE (operands[1]) == ABS)
8712 tmp = gen_int_mode (0x7fffffff, SImode);
8713 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8717 tmp = gen_int_mode (0x80000000, SImode);
8718 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8724 [(set (match_operand:DF 0 "register_operand" "")
8725 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8726 (use (match_operand 2 "" ""))
8727 (clobber (reg:CC FLAGS_REG))]
8729 [(parallel [(set (match_dup 0) (match_dup 1))
8730 (clobber (reg:CC FLAGS_REG))])]
8735 tmp = gen_lowpart (DImode, operands[0]);
8736 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8739 if (GET_CODE (operands[1]) == ABS)
8742 tmp = gen_rtx_NOT (DImode, tmp);
8746 operands[0] = gen_highpart (SImode, operands[0]);
8747 if (GET_CODE (operands[1]) == ABS)
8749 tmp = gen_int_mode (0x7fffffff, SImode);
8750 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8754 tmp = gen_int_mode (0x80000000, SImode);
8755 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8762 [(set (match_operand:XF 0 "register_operand" "")
8763 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8764 (use (match_operand 2 "" ""))
8765 (clobber (reg:CC FLAGS_REG))]
8767 [(parallel [(set (match_dup 0) (match_dup 1))
8768 (clobber (reg:CC FLAGS_REG))])]
8771 operands[0] = gen_rtx_REG (SImode,
8772 true_regnum (operands[0])
8773 + (TARGET_64BIT ? 1 : 2));
8774 if (GET_CODE (operands[1]) == ABS)
8776 tmp = GEN_INT (0x7fff);
8777 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8781 tmp = GEN_INT (0x8000);
8782 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8787 ;; Conditionalize these after reload. If they match before reload, we
8788 ;; lose the clobber and ability to use integer instructions.
8790 (define_insn "*<code><mode>2_1"
8791 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8792 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8794 && (reload_completed
8795 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8796 "f<absneg_mnemonic>"
8797 [(set_attr "type" "fsgn")
8798 (set_attr "mode" "<MODE>")])
8800 (define_insn "*<code>extendsfdf2"
8801 [(set (match_operand:DF 0 "register_operand" "=f")
8802 (absneg:DF (float_extend:DF
8803 (match_operand:SF 1 "register_operand" "0"))))]
8804 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8805 "f<absneg_mnemonic>"
8806 [(set_attr "type" "fsgn")
8807 (set_attr "mode" "DF")])
8809 (define_insn "*<code>extendsfxf2"
8810 [(set (match_operand:XF 0 "register_operand" "=f")
8811 (absneg:XF (float_extend:XF
8812 (match_operand:SF 1 "register_operand" "0"))))]
8814 "f<absneg_mnemonic>"
8815 [(set_attr "type" "fsgn")
8816 (set_attr "mode" "XF")])
8818 (define_insn "*<code>extenddfxf2"
8819 [(set (match_operand:XF 0 "register_operand" "=f")
8820 (absneg:XF (float_extend:XF
8821 (match_operand:DF 1 "register_operand" "0"))))]
8823 "f<absneg_mnemonic>"
8824 [(set_attr "type" "fsgn")
8825 (set_attr "mode" "XF")])
8827 ;; Copysign instructions
8829 (define_mode_iterator CSGNMODE [SF DF TF])
8830 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8832 (define_expand "copysign<mode>3"
8833 [(match_operand:CSGNMODE 0 "register_operand" "")
8834 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8835 (match_operand:CSGNMODE 2 "register_operand" "")]
8836 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838 "ix86_expand_copysign (operands); DONE;")
8840 (define_insn_and_split "copysign<mode>3_const"
8841 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8843 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8844 (match_operand:CSGNMODE 2 "register_operand" "0")
8845 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8847 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8848 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8850 "&& reload_completed"
8852 "ix86_split_copysign_const (operands); DONE;")
8854 (define_insn "copysign<mode>3_var"
8855 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8857 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8858 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8859 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8860 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8862 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8863 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8864 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8868 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8870 [(match_operand:CSGNMODE 2 "register_operand" "")
8871 (match_operand:CSGNMODE 3 "register_operand" "")
8872 (match_operand:<CSGNVMODE> 4 "" "")
8873 (match_operand:<CSGNVMODE> 5 "" "")]
8875 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8876 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8877 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8878 && reload_completed"
8880 "ix86_split_copysign_var (operands); DONE;")
8882 ;; One complement instructions
8884 (define_expand "one_cmpl<mode>2"
8885 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8886 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8888 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8890 (define_insn "*one_cmpl<mode>2_1"
8891 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8892 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8893 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8894 "not{<imodesuffix>}\t%0"
8895 [(set_attr "type" "negnot")
8896 (set_attr "mode" "<MODE>")])
8898 ;; %%% Potential partial reg stall on alternative 1. What to do?
8899 (define_insn "*one_cmplqi2_1"
8900 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8901 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8902 "ix86_unary_operator_ok (NOT, QImode, operands)"
8906 [(set_attr "type" "negnot")
8907 (set_attr "mode" "QI,SI")])
8909 ;; ??? Currently never generated - xor is used instead.
8910 (define_insn "*one_cmplsi2_1_zext"
8911 [(set (match_operand:DI 0 "register_operand" "=r")
8913 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8914 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8916 [(set_attr "type" "negnot")
8917 (set_attr "mode" "SI")])
8919 (define_insn "*one_cmpl<mode>2_2"
8920 [(set (reg FLAGS_REG)
8921 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8924 (not:SWI (match_dup 1)))]
8925 "ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8928 [(set_attr "type" "alu1")
8929 (set_attr "mode" "<MODE>")])
8932 [(set (match_operand 0 "flags_reg_operand" "")
8933 (match_operator 2 "compare_operator"
8934 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8936 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8937 (not:SWI (match_dup 3)))]
8938 "ix86_match_ccmode (insn, CCNOmode)"
8939 [(parallel [(set (match_dup 0)
8940 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8943 (xor:SWI (match_dup 3) (const_int -1)))])])
8945 ;; ??? Currently never generated - xor is used instead.
8946 (define_insn "*one_cmplsi2_2_zext"
8947 [(set (reg FLAGS_REG)
8948 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8950 (set (match_operand:DI 0 "register_operand" "=r")
8951 (zero_extend:DI (not:SI (match_dup 1))))]
8952 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8953 && ix86_unary_operator_ok (NOT, SImode, operands)"
8955 [(set_attr "type" "alu1")
8956 (set_attr "mode" "SI")])
8959 [(set (match_operand 0 "flags_reg_operand" "")
8960 (match_operator 2 "compare_operator"
8961 [(not:SI (match_operand:SI 3 "register_operand" ""))
8963 (set (match_operand:DI 1 "register_operand" "")
8964 (zero_extend:DI (not:SI (match_dup 3))))]
8965 "ix86_match_ccmode (insn, CCNOmode)"
8966 [(parallel [(set (match_dup 0)
8967 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8970 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8972 ;; Shift instructions
8974 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8975 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8976 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8977 ;; from the assembler input.
8979 ;; This instruction shifts the target reg/mem as usual, but instead of
8980 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8981 ;; is a left shift double, bits are taken from the high order bits of
8982 ;; reg, else if the insn is a shift right double, bits are taken from the
8983 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8984 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8986 ;; Since sh[lr]d does not change the `reg' operand, that is done
8987 ;; separately, making all shifts emit pairs of shift double and normal
8988 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8989 ;; support a 63 bit shift, each shift where the count is in a reg expands
8990 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8992 ;; If the shift count is a constant, we need never emit more than one
8993 ;; shift pair, instead using moves and sign extension for counts greater
8996 (define_expand "ashl<mode>3"
8997 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8998 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8999 (match_operand:QI 2 "nonmemory_operand" "")))]
9001 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9003 (define_insn "*ashl<mode>3_doubleword"
9004 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9005 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9006 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9007 (clobber (reg:CC FLAGS_REG))]
9010 [(set_attr "type" "multi")])
9013 [(set (match_operand:DWI 0 "register_operand" "")
9014 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9015 (match_operand:QI 2 "nonmemory_operand" "")))
9016 (clobber (reg:CC FLAGS_REG))]
9017 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9019 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9021 ;; By default we don't ask for a scratch register, because when DWImode
9022 ;; values are manipulated, registers are already at a premium. But if
9023 ;; we have one handy, we won't turn it away.
9026 [(match_scratch:DWIH 3 "r")
9027 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9029 (match_operand:<DWI> 1 "nonmemory_operand" "")
9030 (match_operand:QI 2 "nonmemory_operand" "")))
9031 (clobber (reg:CC FLAGS_REG))])
9035 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9037 (define_insn "x86_64_shld"
9038 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9039 (ior:DI (ashift:DI (match_dup 0)
9040 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9041 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9042 (minus:QI (const_int 64) (match_dup 2)))))
9043 (clobber (reg:CC FLAGS_REG))]
9045 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9046 [(set_attr "type" "ishift")
9047 (set_attr "prefix_0f" "1")
9048 (set_attr "mode" "DI")
9049 (set_attr "athlon_decode" "vector")
9050 (set_attr "amdfam10_decode" "vector")
9051 (set_attr "bdver1_decode" "vector")])
9053 (define_insn "x86_shld"
9054 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9055 (ior:SI (ashift:SI (match_dup 0)
9056 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9057 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9058 (minus:QI (const_int 32) (match_dup 2)))))
9059 (clobber (reg:CC FLAGS_REG))]
9061 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9062 [(set_attr "type" "ishift")
9063 (set_attr "prefix_0f" "1")
9064 (set_attr "mode" "SI")
9065 (set_attr "pent_pair" "np")
9066 (set_attr "athlon_decode" "vector")
9067 (set_attr "amdfam10_decode" "vector")
9068 (set_attr "bdver1_decode" "vector")])
9070 (define_expand "x86_shift<mode>_adj_1"
9071 [(set (reg:CCZ FLAGS_REG)
9072 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9075 (set (match_operand:SWI48 0 "register_operand" "")
9076 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9077 (match_operand:SWI48 1 "register_operand" "")
9080 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9081 (match_operand:SWI48 3 "register_operand" "r")
9084 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9086 (define_expand "x86_shift<mode>_adj_2"
9087 [(use (match_operand:SWI48 0 "register_operand" ""))
9088 (use (match_operand:SWI48 1 "register_operand" ""))
9089 (use (match_operand:QI 2 "register_operand" ""))]
9092 rtx label = gen_label_rtx ();
9095 emit_insn (gen_testqi_ccz_1 (operands[2],
9096 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9098 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9099 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9100 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9101 gen_rtx_LABEL_REF (VOIDmode, label),
9103 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9104 JUMP_LABEL (tmp) = label;
9106 emit_move_insn (operands[0], operands[1]);
9107 ix86_expand_clear (operands[1]);
9110 LABEL_NUSES (label) = 1;
9115 ;; Avoid useless masking of count operand.
9116 (define_insn_and_split "*ashl<mode>3_mask"
9117 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9119 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9122 (match_operand:SI 2 "nonimmediate_operand" "c")
9123 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9126 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9127 == GET_MODE_BITSIZE (<MODE>mode)-1"
9130 [(parallel [(set (match_dup 0)
9131 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9132 (clobber (reg:CC FLAGS_REG))])]
9134 if (can_create_pseudo_p ())
9135 operands [2] = force_reg (SImode, operands[2]);
9137 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9139 [(set_attr "type" "ishift")
9140 (set_attr "mode" "<MODE>")])
9142 (define_insn "*bmi2_ashl<mode>3_1"
9143 [(set (match_operand:SWI48 0 "register_operand" "=r")
9144 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9145 (match_operand:SWI48 2 "register_operand" "r")))]
9147 "shlx\t{%2, %1, %0|%0, %1, %2}"
9148 [(set_attr "type" "ishiftx")
9149 (set_attr "mode" "<MODE>")])
9151 (define_insn "*ashl<mode>3_1"
9152 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9153 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9154 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9155 (clobber (reg:CC FLAGS_REG))]
9156 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9158 switch (get_attr_type (insn))
9165 gcc_assert (operands[2] == const1_rtx);
9166 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9167 return "add{<imodesuffix>}\t%0, %0";
9170 if (operands[2] == const1_rtx
9171 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9172 return "sal{<imodesuffix>}\t%0";
9174 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9177 [(set_attr "isa" "*,*,bmi2")
9179 (cond [(eq_attr "alternative" "1")
9180 (const_string "lea")
9181 (eq_attr "alternative" "2")
9182 (const_string "ishiftx")
9183 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9184 (match_operand 0 "register_operand" ""))
9185 (match_operand 2 "const1_operand" ""))
9186 (const_string "alu")
9188 (const_string "ishift")))
9189 (set (attr "length_immediate")
9191 (ior (eq_attr "type" "alu")
9192 (and (eq_attr "type" "ishift")
9193 (and (match_operand 2 "const1_operand" "")
9194 (ior (match_test "TARGET_SHIFT1")
9195 (match_test "optimize_function_for_size_p (cfun)")))))
9197 (const_string "*")))
9198 (set_attr "mode" "<MODE>")])
9200 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9202 [(set (match_operand:SWI48 0 "register_operand" "")
9203 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9204 (match_operand:QI 2 "register_operand" "")))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "TARGET_BMI2 && reload_completed"
9208 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9209 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9211 (define_insn "*bmi2_ashlsi3_1_zext"
9212 [(set (match_operand:DI 0 "register_operand" "=r")
9214 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9215 (match_operand:SI 2 "register_operand" "r"))))]
9216 "TARGET_64BIT && TARGET_BMI2"
9217 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9218 [(set_attr "type" "ishiftx")
9219 (set_attr "mode" "SI")])
9221 (define_insn "*ashlsi3_1_zext"
9222 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9224 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9225 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9229 switch (get_attr_type (insn))
9236 gcc_assert (operands[2] == const1_rtx);
9237 return "add{l}\t%k0, %k0";
9240 if (operands[2] == const1_rtx
9241 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9242 return "sal{l}\t%k0";
9244 return "sal{l}\t{%2, %k0|%k0, %2}";
9247 [(set_attr "isa" "*,*,bmi2")
9249 (cond [(eq_attr "alternative" "1")
9250 (const_string "lea")
9251 (eq_attr "alternative" "2")
9252 (const_string "ishiftx")
9253 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9254 (match_operand 2 "const1_operand" ""))
9255 (const_string "alu")
9257 (const_string "ishift")))
9258 (set (attr "length_immediate")
9260 (ior (eq_attr "type" "alu")
9261 (and (eq_attr "type" "ishift")
9262 (and (match_operand 2 "const1_operand" "")
9263 (ior (match_test "TARGET_SHIFT1")
9264 (match_test "optimize_function_for_size_p (cfun)")))))
9266 (const_string "*")))
9267 (set_attr "mode" "SI")])
9269 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9271 [(set (match_operand:DI 0 "register_operand" "")
9273 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9274 (match_operand:QI 2 "register_operand" ""))))
9275 (clobber (reg:CC FLAGS_REG))]
9276 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9278 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9279 "operands[2] = gen_lowpart (SImode, operands[2]);")
9281 (define_insn "*ashlhi3_1"
9282 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9283 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9284 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9285 (clobber (reg:CC FLAGS_REG))]
9286 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9288 switch (get_attr_type (insn))
9294 gcc_assert (operands[2] == const1_rtx);
9295 return "add{w}\t%0, %0";
9298 if (operands[2] == const1_rtx
9299 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9300 return "sal{w}\t%0";
9302 return "sal{w}\t{%2, %0|%0, %2}";
9306 (cond [(eq_attr "alternative" "1")
9307 (const_string "lea")
9308 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9309 (match_operand 0 "register_operand" ""))
9310 (match_operand 2 "const1_operand" ""))
9311 (const_string "alu")
9313 (const_string "ishift")))
9314 (set (attr "length_immediate")
9316 (ior (eq_attr "type" "alu")
9317 (and (eq_attr "type" "ishift")
9318 (and (match_operand 2 "const1_operand" "")
9319 (ior (match_test "TARGET_SHIFT1")
9320 (match_test "optimize_function_for_size_p (cfun)")))))
9322 (const_string "*")))
9323 (set_attr "mode" "HI,SI")])
9325 ;; %%% Potential partial reg stall on alternative 1. What to do?
9326 (define_insn "*ashlqi3_1"
9327 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9328 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9329 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9333 switch (get_attr_type (insn))
9339 gcc_assert (operands[2] == const1_rtx);
9340 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9341 return "add{l}\t%k0, %k0";
9343 return "add{b}\t%0, %0";
9346 if (operands[2] == const1_rtx
9347 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9349 if (get_attr_mode (insn) == MODE_SI)
9350 return "sal{l}\t%k0";
9352 return "sal{b}\t%0";
9356 if (get_attr_mode (insn) == MODE_SI)
9357 return "sal{l}\t{%2, %k0|%k0, %2}";
9359 return "sal{b}\t{%2, %0|%0, %2}";
9364 (cond [(eq_attr "alternative" "2")
9365 (const_string "lea")
9366 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9367 (match_operand 0 "register_operand" ""))
9368 (match_operand 2 "const1_operand" ""))
9369 (const_string "alu")
9371 (const_string "ishift")))
9372 (set (attr "length_immediate")
9374 (ior (eq_attr "type" "alu")
9375 (and (eq_attr "type" "ishift")
9376 (and (match_operand 2 "const1_operand" "")
9377 (ior (match_test "TARGET_SHIFT1")
9378 (match_test "optimize_function_for_size_p (cfun)")))))
9380 (const_string "*")))
9381 (set_attr "mode" "QI,SI,SI")])
9383 (define_insn "*ashlqi3_1_slp"
9384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9385 (ashift:QI (match_dup 0)
9386 (match_operand:QI 1 "nonmemory_operand" "cI")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "(optimize_function_for_size_p (cfun)
9389 || !TARGET_PARTIAL_FLAG_REG_STALL
9390 || (operands[1] == const1_rtx
9392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9394 switch (get_attr_type (insn))
9397 gcc_assert (operands[1] == const1_rtx);
9398 return "add{b}\t%0, %0";
9401 if (operands[1] == const1_rtx
9402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403 return "sal{b}\t%0";
9405 return "sal{b}\t{%1, %0|%0, %1}";
9409 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9410 (match_operand 0 "register_operand" ""))
9411 (match_operand 1 "const1_operand" ""))
9412 (const_string "alu")
9414 (const_string "ishift1")))
9415 (set (attr "length_immediate")
9417 (ior (eq_attr "type" "alu")
9418 (and (eq_attr "type" "ishift1")
9419 (and (match_operand 1 "const1_operand" "")
9420 (ior (match_test "TARGET_SHIFT1")
9421 (match_test "optimize_function_for_size_p (cfun)")))))
9423 (const_string "*")))
9424 (set_attr "mode" "QI")])
9426 ;; Convert ashift to the lea pattern to avoid flags dependency.
9428 [(set (match_operand 0 "register_operand" "")
9429 (ashift (match_operand 1 "index_register_operand" "")
9430 (match_operand:QI 2 "const_int_operand" "")))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9434 && true_regnum (operands[0]) != true_regnum (operands[1])"
9437 enum machine_mode mode = GET_MODE (operands[0]);
9440 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9443 operands[0] = gen_lowpart (mode, operands[0]);
9444 operands[1] = gen_lowpart (mode, operands[1]);
9447 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9449 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9455 ;; Convert ashift to the lea pattern to avoid flags dependency.
9457 [(set (match_operand:DI 0 "register_operand" "")
9459 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9460 (match_operand:QI 2 "const_int_operand" ""))))
9461 (clobber (reg:CC FLAGS_REG))]
9462 "TARGET_64BIT && reload_completed
9463 && true_regnum (operands[0]) != true_regnum (operands[1])"
9465 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9467 operands[1] = gen_lowpart (DImode, operands[1]);
9468 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9471 ;; This pattern can't accept a variable shift count, since shifts by
9472 ;; zero don't affect the flags. We assume that shifts by constant
9473 ;; zero are optimized away.
9474 (define_insn "*ashl<mode>3_cmp"
9475 [(set (reg FLAGS_REG)
9477 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9478 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9480 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9481 (ashift:SWI (match_dup 1) (match_dup 2)))]
9482 "(optimize_function_for_size_p (cfun)
9483 || !TARGET_PARTIAL_FLAG_REG_STALL
9484 || (operands[2] == const1_rtx
9486 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9487 && ix86_match_ccmode (insn, CCGOCmode)
9488 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9490 switch (get_attr_type (insn))
9493 gcc_assert (operands[2] == const1_rtx);
9494 return "add{<imodesuffix>}\t%0, %0";
9497 if (operands[2] == const1_rtx
9498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9499 return "sal{<imodesuffix>}\t%0";
9501 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9505 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9506 (match_operand 0 "register_operand" ""))
9507 (match_operand 2 "const1_operand" ""))
9508 (const_string "alu")
9510 (const_string "ishift")))
9511 (set (attr "length_immediate")
9513 (ior (eq_attr "type" "alu")
9514 (and (eq_attr "type" "ishift")
9515 (and (match_operand 2 "const1_operand" "")
9516 (ior (match_test "TARGET_SHIFT1")
9517 (match_test "optimize_function_for_size_p (cfun)")))))
9519 (const_string "*")))
9520 (set_attr "mode" "<MODE>")])
9522 (define_insn "*ashlsi3_cmp_zext"
9523 [(set (reg FLAGS_REG)
9525 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9526 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9528 (set (match_operand:DI 0 "register_operand" "=r")
9529 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9531 && (optimize_function_for_size_p (cfun)
9532 || !TARGET_PARTIAL_FLAG_REG_STALL
9533 || (operands[2] == const1_rtx
9535 || TARGET_DOUBLE_WITH_ADD)))
9536 && ix86_match_ccmode (insn, CCGOCmode)
9537 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9539 switch (get_attr_type (insn))
9542 gcc_assert (operands[2] == const1_rtx);
9543 return "add{l}\t%k0, %k0";
9546 if (operands[2] == const1_rtx
9547 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9548 return "sal{l}\t%k0";
9550 return "sal{l}\t{%2, %k0|%k0, %2}";
9554 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9555 (match_operand 2 "const1_operand" ""))
9556 (const_string "alu")
9558 (const_string "ishift")))
9559 (set (attr "length_immediate")
9561 (ior (eq_attr "type" "alu")
9562 (and (eq_attr "type" "ishift")
9563 (and (match_operand 2 "const1_operand" "")
9564 (ior (match_test "TARGET_SHIFT1")
9565 (match_test "optimize_function_for_size_p (cfun)")))))
9567 (const_string "*")))
9568 (set_attr "mode" "SI")])
9570 (define_insn "*ashl<mode>3_cconly"
9571 [(set (reg FLAGS_REG)
9573 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9574 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9576 (clobber (match_scratch:SWI 0 "=<r>"))]
9577 "(optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[2] == const1_rtx
9581 || TARGET_DOUBLE_WITH_ADD)))
9582 && ix86_match_ccmode (insn, CCGOCmode)"
9584 switch (get_attr_type (insn))
9587 gcc_assert (operands[2] == const1_rtx);
9588 return "add{<imodesuffix>}\t%0, %0";
9591 if (operands[2] == const1_rtx
9592 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9593 return "sal{<imodesuffix>}\t%0";
9595 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9599 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9600 (match_operand 0 "register_operand" ""))
9601 (match_operand 2 "const1_operand" ""))
9602 (const_string "alu")
9604 (const_string "ishift")))
9605 (set (attr "length_immediate")
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift")
9609 (and (match_operand 2 "const1_operand" "")
9610 (ior (match_test "TARGET_SHIFT1")
9611 (match_test "optimize_function_for_size_p (cfun)")))))
9613 (const_string "*")))
9614 (set_attr "mode" "<MODE>")])
9616 ;; See comment above `ashl<mode>3' about how this works.
9618 (define_expand "<shift_insn><mode>3"
9619 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9620 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9621 (match_operand:QI 2 "nonmemory_operand" "")))]
9623 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9625 ;; Avoid useless masking of count operand.
9626 (define_insn_and_split "*<shift_insn><mode>3_mask"
9627 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9629 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9632 (match_operand:SI 2 "nonimmediate_operand" "c")
9633 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9636 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9637 == GET_MODE_BITSIZE (<MODE>mode)-1"
9640 [(parallel [(set (match_dup 0)
9641 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9642 (clobber (reg:CC FLAGS_REG))])]
9644 if (can_create_pseudo_p ())
9645 operands [2] = force_reg (SImode, operands[2]);
9647 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9649 [(set_attr "type" "ishift")
9650 (set_attr "mode" "<MODE>")])
9652 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9653 [(set (match_operand:DWI 0 "register_operand" "=r")
9654 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9655 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9656 (clobber (reg:CC FLAGS_REG))]
9659 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9661 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9662 [(set_attr "type" "multi")])
9664 ;; By default we don't ask for a scratch register, because when DWImode
9665 ;; values are manipulated, registers are already at a premium. But if
9666 ;; we have one handy, we won't turn it away.
9669 [(match_scratch:DWIH 3 "r")
9670 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9672 (match_operand:<DWI> 1 "register_operand" "")
9673 (match_operand:QI 2 "nonmemory_operand" "")))
9674 (clobber (reg:CC FLAGS_REG))])
9678 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9680 (define_insn "x86_64_shrd"
9681 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9682 (ior:DI (ashiftrt:DI (match_dup 0)
9683 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9684 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9685 (minus:QI (const_int 64) (match_dup 2)))))
9686 (clobber (reg:CC FLAGS_REG))]
9688 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9689 [(set_attr "type" "ishift")
9690 (set_attr "prefix_0f" "1")
9691 (set_attr "mode" "DI")
9692 (set_attr "athlon_decode" "vector")
9693 (set_attr "amdfam10_decode" "vector")
9694 (set_attr "bdver1_decode" "vector")])
9696 (define_insn "x86_shrd"
9697 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9698 (ior:SI (ashiftrt:SI (match_dup 0)
9699 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9700 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9701 (minus:QI (const_int 32) (match_dup 2)))))
9702 (clobber (reg:CC FLAGS_REG))]
9704 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9705 [(set_attr "type" "ishift")
9706 (set_attr "prefix_0f" "1")
9707 (set_attr "mode" "SI")
9708 (set_attr "pent_pair" "np")
9709 (set_attr "athlon_decode" "vector")
9710 (set_attr "amdfam10_decode" "vector")
9711 (set_attr "bdver1_decode" "vector")])
9713 (define_insn "ashrdi3_cvt"
9714 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9715 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9716 (match_operand:QI 2 "const_int_operand" "")))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "TARGET_64BIT && INTVAL (operands[2]) == 63
9719 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9720 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9723 sar{q}\t{%2, %0|%0, %2}"
9724 [(set_attr "type" "imovx,ishift")
9725 (set_attr "prefix_0f" "0,*")
9726 (set_attr "length_immediate" "0,*")
9727 (set_attr "modrm" "0,1")
9728 (set_attr "mode" "DI")])
9730 (define_insn "ashrsi3_cvt"
9731 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9732 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9733 (match_operand:QI 2 "const_int_operand" "")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "INTVAL (operands[2]) == 31
9736 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9737 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9740 sar{l}\t{%2, %0|%0, %2}"
9741 [(set_attr "type" "imovx,ishift")
9742 (set_attr "prefix_0f" "0,*")
9743 (set_attr "length_immediate" "0,*")
9744 (set_attr "modrm" "0,1")
9745 (set_attr "mode" "SI")])
9747 (define_insn "*ashrsi3_cvt_zext"
9748 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9750 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9751 (match_operand:QI 2 "const_int_operand" ""))))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "TARGET_64BIT && INTVAL (operands[2]) == 31
9754 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9755 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9758 sar{l}\t{%2, %k0|%k0, %2}"
9759 [(set_attr "type" "imovx,ishift")
9760 (set_attr "prefix_0f" "0,*")
9761 (set_attr "length_immediate" "0,*")
9762 (set_attr "modrm" "0,1")
9763 (set_attr "mode" "SI")])
9765 (define_expand "x86_shift<mode>_adj_3"
9766 [(use (match_operand:SWI48 0 "register_operand" ""))
9767 (use (match_operand:SWI48 1 "register_operand" ""))
9768 (use (match_operand:QI 2 "register_operand" ""))]
9771 rtx label = gen_label_rtx ();
9774 emit_insn (gen_testqi_ccz_1 (operands[2],
9775 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9777 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9778 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9779 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9780 gen_rtx_LABEL_REF (VOIDmode, label),
9782 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9783 JUMP_LABEL (tmp) = label;
9785 emit_move_insn (operands[0], operands[1]);
9786 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9787 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9789 LABEL_NUSES (label) = 1;
9794 (define_insn "*bmi2_<shift_insn><mode>3_1"
9795 [(set (match_operand:SWI48 0 "register_operand" "=r")
9796 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9797 (match_operand:SWI48 2 "register_operand" "r")))]
9799 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9800 [(set_attr "type" "ishiftx")
9801 (set_attr "mode" "<MODE>")])
9803 (define_insn "*<shift_insn><mode>3_1"
9804 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9806 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9807 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9811 switch (get_attr_type (insn))
9817 if (operands[2] == const1_rtx
9818 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9819 return "<shift>{<imodesuffix>}\t%0";
9821 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9824 [(set_attr "isa" "*,bmi2")
9825 (set_attr "type" "ishift,ishiftx")
9826 (set (attr "length_immediate")
9828 (and (match_operand 2 "const1_operand" "")
9829 (ior (match_test "TARGET_SHIFT1")
9830 (match_test "optimize_function_for_size_p (cfun)")))
9832 (const_string "*")))
9833 (set_attr "mode" "<MODE>")])
9835 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9837 [(set (match_operand:SWI48 0 "register_operand" "")
9838 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9839 (match_operand:QI 2 "register_operand" "")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "TARGET_BMI2 && reload_completed"
9843 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9844 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9846 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9847 [(set (match_operand:DI 0 "register_operand" "=r")
9849 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9850 (match_operand:SI 2 "register_operand" "r"))))]
9851 "TARGET_64BIT && TARGET_BMI2"
9852 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9853 [(set_attr "type" "ishiftx")
9854 (set_attr "mode" "SI")])
9856 (define_insn "*<shift_insn>si3_1_zext"
9857 [(set (match_operand:DI 0 "register_operand" "=r,r")
9859 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9860 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9864 switch (get_attr_type (insn))
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<shift>{l}\t%k0";
9874 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9877 [(set_attr "isa" "*,bmi2")
9878 (set_attr "type" "ishift,ishiftx")
9879 (set (attr "length_immediate")
9881 (and (match_operand 2 "const1_operand" "")
9882 (ior (match_test "TARGET_SHIFT1")
9883 (match_test "optimize_function_for_size_p (cfun)")))
9885 (const_string "*")))
9886 (set_attr "mode" "SI")])
9888 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9890 [(set (match_operand:DI 0 "register_operand" "")
9892 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9893 (match_operand:QI 2 "register_operand" ""))))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9897 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9898 "operands[2] = gen_lowpart (SImode, operands[2]);")
9900 (define_insn "*<shift_insn><mode>3_1"
9901 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9903 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9904 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9905 (clobber (reg:CC FLAGS_REG))]
9906 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9908 if (operands[2] == const1_rtx
9909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9910 return "<shift>{<imodesuffix>}\t%0";
9912 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9914 [(set_attr "type" "ishift")
9915 (set (attr "length_immediate")
9917 (and (match_operand 2 "const1_operand" "")
9918 (ior (match_test "TARGET_SHIFT1")
9919 (match_test "optimize_function_for_size_p (cfun)")))
9921 (const_string "*")))
9922 (set_attr "mode" "<MODE>")])
9924 (define_insn "*<shift_insn>qi3_1_slp"
9925 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9926 (any_shiftrt:QI (match_dup 0)
9927 (match_operand:QI 1 "nonmemory_operand" "cI")))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "(optimize_function_for_size_p (cfun)
9930 || !TARGET_PARTIAL_REG_STALL
9931 || (operands[1] == const1_rtx
9934 if (operands[1] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936 return "<shift>{b}\t%0";
9938 return "<shift>{b}\t{%1, %0|%0, %1}";
9940 [(set_attr "type" "ishift1")
9941 (set (attr "length_immediate")
9943 (and (match_operand 1 "const1_operand" "")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))
9947 (const_string "*")))
9948 (set_attr "mode" "QI")])
9950 ;; This pattern can't accept a variable shift count, since shifts by
9951 ;; zero don't affect the flags. We assume that shifts by constant
9952 ;; zero are optimized away.
9953 (define_insn "*<shift_insn><mode>3_cmp"
9954 [(set (reg FLAGS_REG)
9957 (match_operand:SWI 1 "nonimmediate_operand" "0")
9958 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9960 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9961 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9962 "(optimize_function_for_size_p (cfun)
9963 || !TARGET_PARTIAL_FLAG_REG_STALL
9964 || (operands[2] == const1_rtx
9966 && ix86_match_ccmode (insn, CCGOCmode)
9967 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9969 if (operands[2] == const1_rtx
9970 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9971 return "<shift>{<imodesuffix>}\t%0";
9973 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9975 [(set_attr "type" "ishift")
9976 (set (attr "length_immediate")
9978 (and (match_operand 2 "const1_operand" "")
9979 (ior (match_test "TARGET_SHIFT1")
9980 (match_test "optimize_function_for_size_p (cfun)")))
9982 (const_string "*")))
9983 (set_attr "mode" "<MODE>")])
9985 (define_insn "*<shift_insn>si3_cmp_zext"
9986 [(set (reg FLAGS_REG)
9988 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9989 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9991 (set (match_operand:DI 0 "register_operand" "=r")
9992 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9994 && (optimize_function_for_size_p (cfun)
9995 || !TARGET_PARTIAL_FLAG_REG_STALL
9996 || (operands[2] == const1_rtx
9998 && ix86_match_ccmode (insn, CCGOCmode)
9999 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10001 if (operands[2] == const1_rtx
10002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003 return "<shift>{l}\t%k0";
10005 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10007 [(set_attr "type" "ishift")
10008 (set (attr "length_immediate")
10010 (and (match_operand 2 "const1_operand" "")
10011 (ior (match_test "TARGET_SHIFT1")
10012 (match_test "optimize_function_for_size_p (cfun)")))
10014 (const_string "*")))
10015 (set_attr "mode" "SI")])
10017 (define_insn "*<shift_insn><mode>3_cconly"
10018 [(set (reg FLAGS_REG)
10021 (match_operand:SWI 1 "register_operand" "0")
10022 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10024 (clobber (match_scratch:SWI 0 "=<r>"))]
10025 "(optimize_function_for_size_p (cfun)
10026 || !TARGET_PARTIAL_FLAG_REG_STALL
10027 || (operands[2] == const1_rtx
10029 && ix86_match_ccmode (insn, CCGOCmode)"
10031 if (operands[2] == const1_rtx
10032 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10033 return "<shift>{<imodesuffix>}\t%0";
10035 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10037 [(set_attr "type" "ishift")
10038 (set (attr "length_immediate")
10040 (and (match_operand 2 "const1_operand" "")
10041 (ior (match_test "TARGET_SHIFT1")
10042 (match_test "optimize_function_for_size_p (cfun)")))
10044 (const_string "*")))
10045 (set_attr "mode" "<MODE>")])
10047 ;; Rotate instructions
10049 (define_expand "<rotate_insn>ti3"
10050 [(set (match_operand:TI 0 "register_operand" "")
10051 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10052 (match_operand:QI 2 "nonmemory_operand" "")))]
10055 if (const_1_to_63_operand (operands[2], VOIDmode))
10056 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10057 (operands[0], operands[1], operands[2]));
10064 (define_expand "<rotate_insn>di3"
10065 [(set (match_operand:DI 0 "shiftdi_operand" "")
10066 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10067 (match_operand:QI 2 "nonmemory_operand" "")))]
10071 ix86_expand_binary_operator (<CODE>, DImode, operands);
10072 else if (const_1_to_31_operand (operands[2], VOIDmode))
10073 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10074 (operands[0], operands[1], operands[2]));
10081 (define_expand "<rotate_insn><mode>3"
10082 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10083 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10084 (match_operand:QI 2 "nonmemory_operand" "")))]
10086 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10088 ;; Avoid useless masking of count operand.
10089 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10090 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10092 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10095 (match_operand:SI 2 "nonimmediate_operand" "c")
10096 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10097 (clobber (reg:CC FLAGS_REG))]
10098 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10099 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10100 == GET_MODE_BITSIZE (<MODE>mode)-1"
10103 [(parallel [(set (match_dup 0)
10104 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10105 (clobber (reg:CC FLAGS_REG))])]
10107 if (can_create_pseudo_p ())
10108 operands [2] = force_reg (SImode, operands[2]);
10110 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10112 [(set_attr "type" "rotate")
10113 (set_attr "mode" "<MODE>")])
10115 ;; Implement rotation using two double-precision
10116 ;; shift instructions and a scratch register.
10118 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10119 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10120 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10121 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10122 (clobber (reg:CC FLAGS_REG))
10123 (clobber (match_scratch:DWIH 3 "=&r"))]
10127 [(set (match_dup 3) (match_dup 4))
10129 [(set (match_dup 4)
10130 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10131 (lshiftrt:DWIH (match_dup 5)
10132 (minus:QI (match_dup 6) (match_dup 2)))))
10133 (clobber (reg:CC FLAGS_REG))])
10135 [(set (match_dup 5)
10136 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10137 (lshiftrt:DWIH (match_dup 3)
10138 (minus:QI (match_dup 6) (match_dup 2)))))
10139 (clobber (reg:CC FLAGS_REG))])]
10141 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10143 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10146 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10147 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10148 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10149 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10150 (clobber (reg:CC FLAGS_REG))
10151 (clobber (match_scratch:DWIH 3 "=&r"))]
10155 [(set (match_dup 3) (match_dup 4))
10157 [(set (match_dup 4)
10158 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10159 (ashift:DWIH (match_dup 5)
10160 (minus:QI (match_dup 6) (match_dup 2)))))
10161 (clobber (reg:CC FLAGS_REG))])
10163 [(set (match_dup 5)
10164 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10165 (ashift:DWIH (match_dup 3)
10166 (minus:QI (match_dup 6) (match_dup 2)))))
10167 (clobber (reg:CC FLAGS_REG))])]
10169 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10171 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10174 (define_insn "*bmi2_rorx<mode>3_1"
10175 [(set (match_operand:SWI48 0 "register_operand" "=r")
10176 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10177 (match_operand:QI 2 "immediate_operand" "<S>")))]
10179 "rorx\t{%2, %1, %0|%0, %1, %2}"
10180 [(set_attr "type" "rotatex")
10181 (set_attr "mode" "<MODE>")])
10183 (define_insn "*<rotate_insn><mode>3_1"
10184 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10186 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10187 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10188 (clobber (reg:CC FLAGS_REG))]
10189 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10191 switch (get_attr_type (insn))
10197 if (operands[2] == const1_rtx
10198 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10199 return "<rotate>{<imodesuffix>}\t%0";
10201 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10204 [(set_attr "isa" "*,bmi2")
10205 (set_attr "type" "rotate,rotatex")
10206 (set (attr "length_immediate")
10208 (and (eq_attr "type" "rotate")
10209 (and (match_operand 2 "const1_operand" "")
10210 (ior (match_test "TARGET_SHIFT1")
10211 (match_test "optimize_function_for_size_p (cfun)"))))
10213 (const_string "*")))
10214 (set_attr "mode" "<MODE>")])
10216 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10218 [(set (match_operand:SWI48 0 "register_operand" "")
10219 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10220 (match_operand:QI 2 "immediate_operand" "")))
10221 (clobber (reg:CC FLAGS_REG))]
10222 "TARGET_BMI2 && reload_completed"
10223 [(set (match_dup 0)
10224 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10227 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10231 [(set (match_operand:SWI48 0 "register_operand" "")
10232 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10233 (match_operand:QI 2 "immediate_operand" "")))
10234 (clobber (reg:CC FLAGS_REG))]
10235 "TARGET_BMI2 && reload_completed"
10236 [(set (match_dup 0)
10237 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10239 (define_insn "*bmi2_rorxsi3_1_zext"
10240 [(set (match_operand:DI 0 "register_operand" "=r")
10242 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10243 (match_operand:QI 2 "immediate_operand" "I"))))]
10244 "TARGET_64BIT && TARGET_BMI2"
10245 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10246 [(set_attr "type" "rotatex")
10247 (set_attr "mode" "SI")])
10249 (define_insn "*<rotate_insn>si3_1_zext"
10250 [(set (match_operand:DI 0 "register_operand" "=r,r")
10252 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10253 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10254 (clobber (reg:CC FLAGS_REG))]
10255 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10257 switch (get_attr_type (insn))
10263 if (operands[2] == const1_rtx
10264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265 return "<rotate>{l}\t%k0";
10267 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10270 [(set_attr "isa" "*,bmi2")
10271 (set_attr "type" "rotate,rotatex")
10272 (set (attr "length_immediate")
10274 (and (eq_attr "type" "rotate")
10275 (and (match_operand 2 "const1_operand" "")
10276 (ior (match_test "TARGET_SHIFT1")
10277 (match_test "optimize_function_for_size_p (cfun)"))))
10279 (const_string "*")))
10280 (set_attr "mode" "SI")])
10282 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10284 [(set (match_operand:DI 0 "register_operand" "")
10286 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10287 (match_operand:QI 2 "immediate_operand" ""))))
10288 (clobber (reg:CC FLAGS_REG))]
10289 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10290 [(set (match_dup 0)
10291 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10294 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10298 [(set (match_operand:DI 0 "register_operand" "")
10300 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10301 (match_operand:QI 2 "immediate_operand" ""))))
10302 (clobber (reg:CC FLAGS_REG))]
10303 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10304 [(set (match_dup 0)
10305 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10307 (define_insn "*<rotate_insn><mode>3_1"
10308 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10309 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10310 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10314 if (operands[2] == const1_rtx
10315 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10316 return "<rotate>{<imodesuffix>}\t%0";
10318 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10320 [(set_attr "type" "rotate")
10321 (set (attr "length_immediate")
10323 (and (match_operand 2 "const1_operand" "")
10324 (ior (match_test "TARGET_SHIFT1")
10325 (match_test "optimize_function_for_size_p (cfun)")))
10327 (const_string "*")))
10328 (set_attr "mode" "<MODE>")])
10330 (define_insn "*<rotate_insn>qi3_1_slp"
10331 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10332 (any_rotate:QI (match_dup 0)
10333 (match_operand:QI 1 "nonmemory_operand" "cI")))
10334 (clobber (reg:CC FLAGS_REG))]
10335 "(optimize_function_for_size_p (cfun)
10336 || !TARGET_PARTIAL_REG_STALL
10337 || (operands[1] == const1_rtx
10338 && TARGET_SHIFT1))"
10340 if (operands[1] == const1_rtx
10341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342 return "<rotate>{b}\t%0";
10344 return "<rotate>{b}\t{%1, %0|%0, %1}";
10346 [(set_attr "type" "rotate1")
10347 (set (attr "length_immediate")
10349 (and (match_operand 1 "const1_operand" "")
10350 (ior (match_test "TARGET_SHIFT1")
10351 (match_test "optimize_function_for_size_p (cfun)")))
10353 (const_string "*")))
10354 (set_attr "mode" "QI")])
10357 [(set (match_operand:HI 0 "register_operand" "")
10358 (any_rotate:HI (match_dup 0) (const_int 8)))
10359 (clobber (reg:CC FLAGS_REG))]
10361 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10362 [(parallel [(set (strict_low_part (match_dup 0))
10363 (bswap:HI (match_dup 0)))
10364 (clobber (reg:CC FLAGS_REG))])])
10366 ;; Bit set / bit test instructions
10368 (define_expand "extv"
10369 [(set (match_operand:SI 0 "register_operand" "")
10370 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10371 (match_operand:SI 2 "const8_operand" "")
10372 (match_operand:SI 3 "const8_operand" "")))]
10375 /* Handle extractions from %ah et al. */
10376 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10379 /* From mips.md: extract_bit_field doesn't verify that our source
10380 matches the predicate, so check it again here. */
10381 if (! ext_register_operand (operands[1], VOIDmode))
10385 (define_expand "extzv"
10386 [(set (match_operand:SI 0 "register_operand" "")
10387 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10388 (match_operand:SI 2 "const8_operand" "")
10389 (match_operand:SI 3 "const8_operand" "")))]
10392 /* Handle extractions from %ah et al. */
10393 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10396 /* From mips.md: extract_bit_field doesn't verify that our source
10397 matches the predicate, so check it again here. */
10398 if (! ext_register_operand (operands[1], VOIDmode))
10402 (define_expand "insv"
10403 [(set (zero_extract (match_operand 0 "register_operand" "")
10404 (match_operand 1 "const_int_operand" "")
10405 (match_operand 2 "const_int_operand" ""))
10406 (match_operand 3 "register_operand" ""))]
10409 rtx (*gen_mov_insv_1) (rtx, rtx);
10411 if (ix86_expand_pinsr (operands))
10414 /* Handle insertions to %ah et al. */
10415 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10418 /* From mips.md: insert_bit_field doesn't verify that our source
10419 matches the predicate, so check it again here. */
10420 if (! ext_register_operand (operands[0], VOIDmode))
10423 gen_mov_insv_1 = (TARGET_64BIT
10424 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10426 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10430 ;; %%% bts, btr, btc, bt.
10431 ;; In general these instructions are *slow* when applied to memory,
10432 ;; since they enforce atomic operation. When applied to registers,
10433 ;; it depends on the cpu implementation. They're never faster than
10434 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10435 ;; no point. But in 64-bit, we can't hold the relevant immediates
10436 ;; within the instruction itself, so operating on bits in the high
10437 ;; 32-bits of a register becomes easier.
10439 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10440 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10441 ;; negdf respectively, so they can never be disabled entirely.
10443 (define_insn "*btsq"
10444 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10446 (match_operand:DI 1 "const_0_to_63_operand" ""))
10448 (clobber (reg:CC FLAGS_REG))]
10449 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10450 "bts{q}\t{%1, %0|%0, %1}"
10451 [(set_attr "type" "alu1")
10452 (set_attr "prefix_0f" "1")
10453 (set_attr "mode" "DI")])
10455 (define_insn "*btrq"
10456 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10458 (match_operand:DI 1 "const_0_to_63_operand" ""))
10460 (clobber (reg:CC FLAGS_REG))]
10461 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10462 "btr{q}\t{%1, %0|%0, %1}"
10463 [(set_attr "type" "alu1")
10464 (set_attr "prefix_0f" "1")
10465 (set_attr "mode" "DI")])
10467 (define_insn "*btcq"
10468 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10470 (match_operand:DI 1 "const_0_to_63_operand" ""))
10471 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10472 (clobber (reg:CC FLAGS_REG))]
10473 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10474 "btc{q}\t{%1, %0|%0, %1}"
10475 [(set_attr "type" "alu1")
10476 (set_attr "prefix_0f" "1")
10477 (set_attr "mode" "DI")])
10479 ;; Allow Nocona to avoid these instructions if a register is available.
10482 [(match_scratch:DI 2 "r")
10483 (parallel [(set (zero_extract:DI
10484 (match_operand:DI 0 "register_operand" "")
10486 (match_operand:DI 1 "const_0_to_63_operand" ""))
10488 (clobber (reg:CC FLAGS_REG))])]
10489 "TARGET_64BIT && !TARGET_USE_BT"
10492 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10495 if (HOST_BITS_PER_WIDE_INT >= 64)
10496 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10497 else if (i < HOST_BITS_PER_WIDE_INT)
10498 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10500 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10502 op1 = immed_double_const (lo, hi, DImode);
10505 emit_move_insn (operands[2], op1);
10509 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10514 [(match_scratch:DI 2 "r")
10515 (parallel [(set (zero_extract:DI
10516 (match_operand:DI 0 "register_operand" "")
10518 (match_operand:DI 1 "const_0_to_63_operand" ""))
10520 (clobber (reg:CC FLAGS_REG))])]
10521 "TARGET_64BIT && !TARGET_USE_BT"
10524 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10527 if (HOST_BITS_PER_WIDE_INT >= 64)
10528 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10529 else if (i < HOST_BITS_PER_WIDE_INT)
10530 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10532 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10534 op1 = immed_double_const (~lo, ~hi, DImode);
10537 emit_move_insn (operands[2], op1);
10541 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10546 [(match_scratch:DI 2 "r")
10547 (parallel [(set (zero_extract:DI
10548 (match_operand:DI 0 "register_operand" "")
10550 (match_operand:DI 1 "const_0_to_63_operand" ""))
10551 (not:DI (zero_extract:DI
10552 (match_dup 0) (const_int 1) (match_dup 1))))
10553 (clobber (reg:CC FLAGS_REG))])]
10554 "TARGET_64BIT && !TARGET_USE_BT"
10557 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10560 if (HOST_BITS_PER_WIDE_INT >= 64)
10561 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 else if (i < HOST_BITS_PER_WIDE_INT)
10563 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10565 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10567 op1 = immed_double_const (lo, hi, DImode);
10570 emit_move_insn (operands[2], op1);
10574 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10578 (define_insn "*bt<mode>"
10579 [(set (reg:CCC FLAGS_REG)
10581 (zero_extract:SWI48
10582 (match_operand:SWI48 0 "register_operand" "r")
10584 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10586 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10587 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10588 [(set_attr "type" "alu1")
10589 (set_attr "prefix_0f" "1")
10590 (set_attr "mode" "<MODE>")])
10592 ;; Store-flag instructions.
10594 ;; For all sCOND expanders, also expand the compare or test insn that
10595 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10597 (define_insn_and_split "*setcc_di_1"
10598 [(set (match_operand:DI 0 "register_operand" "=q")
10599 (match_operator:DI 1 "ix86_comparison_operator"
10600 [(reg FLAGS_REG) (const_int 0)]))]
10601 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10603 "&& reload_completed"
10604 [(set (match_dup 2) (match_dup 1))
10605 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10607 PUT_MODE (operands[1], QImode);
10608 operands[2] = gen_lowpart (QImode, operands[0]);
10611 (define_insn_and_split "*setcc_si_1_and"
10612 [(set (match_operand:SI 0 "register_operand" "=q")
10613 (match_operator:SI 1 "ix86_comparison_operator"
10614 [(reg FLAGS_REG) (const_int 0)]))
10615 (clobber (reg:CC FLAGS_REG))]
10616 "!TARGET_PARTIAL_REG_STALL
10617 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10619 "&& reload_completed"
10620 [(set (match_dup 2) (match_dup 1))
10621 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10622 (clobber (reg:CC FLAGS_REG))])]
10624 PUT_MODE (operands[1], QImode);
10625 operands[2] = gen_lowpart (QImode, operands[0]);
10628 (define_insn_and_split "*setcc_si_1_movzbl"
10629 [(set (match_operand:SI 0 "register_operand" "=q")
10630 (match_operator:SI 1 "ix86_comparison_operator"
10631 [(reg FLAGS_REG) (const_int 0)]))]
10632 "!TARGET_PARTIAL_REG_STALL
10633 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10635 "&& reload_completed"
10636 [(set (match_dup 2) (match_dup 1))
10637 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10639 PUT_MODE (operands[1], QImode);
10640 operands[2] = gen_lowpart (QImode, operands[0]);
10643 (define_insn "*setcc_qi"
10644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10645 (match_operator:QI 1 "ix86_comparison_operator"
10646 [(reg FLAGS_REG) (const_int 0)]))]
10649 [(set_attr "type" "setcc")
10650 (set_attr "mode" "QI")])
10652 (define_insn "*setcc_qi_slp"
10653 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10654 (match_operator:QI 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)]))]
10658 [(set_attr "type" "setcc")
10659 (set_attr "mode" "QI")])
10661 ;; In general it is not safe to assume too much about CCmode registers,
10662 ;; so simplify-rtx stops when it sees a second one. Under certain
10663 ;; conditions this is safe on x86, so help combine not create
10670 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10671 (ne:QI (match_operator 1 "ix86_comparison_operator"
10672 [(reg FLAGS_REG) (const_int 0)])
10675 [(set (match_dup 0) (match_dup 1))]
10676 "PUT_MODE (operands[1], QImode);")
10679 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10680 (ne:QI (match_operator 1 "ix86_comparison_operator"
10681 [(reg FLAGS_REG) (const_int 0)])
10684 [(set (match_dup 0) (match_dup 1))]
10685 "PUT_MODE (operands[1], QImode);")
10688 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10689 (eq:QI (match_operator 1 "ix86_comparison_operator"
10690 [(reg FLAGS_REG) (const_int 0)])
10693 [(set (match_dup 0) (match_dup 1))]
10695 rtx new_op1 = copy_rtx (operands[1]);
10696 operands[1] = new_op1;
10697 PUT_MODE (new_op1, QImode);
10698 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10699 GET_MODE (XEXP (new_op1, 0))));
10701 /* Make sure that (a) the CCmode we have for the flags is strong
10702 enough for the reversed compare or (b) we have a valid FP compare. */
10703 if (! ix86_comparison_operator (new_op1, VOIDmode))
10708 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10709 (eq:QI (match_operator 1 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)])
10713 [(set (match_dup 0) (match_dup 1))]
10715 rtx new_op1 = copy_rtx (operands[1]);
10716 operands[1] = new_op1;
10717 PUT_MODE (new_op1, QImode);
10718 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10719 GET_MODE (XEXP (new_op1, 0))));
10721 /* Make sure that (a) the CCmode we have for the flags is strong
10722 enough for the reversed compare or (b) we have a valid FP compare. */
10723 if (! ix86_comparison_operator (new_op1, VOIDmode))
10727 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10728 ;; subsequent logical operations are used to imitate conditional moves.
10729 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10732 (define_insn "setcc_<mode>_sse"
10733 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10734 (match_operator:MODEF 3 "sse_comparison_operator"
10735 [(match_operand:MODEF 1 "register_operand" "0,x")
10736 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10737 "SSE_FLOAT_MODE_P (<MODE>mode)"
10739 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10740 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10741 [(set_attr "isa" "noavx,avx")
10742 (set_attr "type" "ssecmp")
10743 (set_attr "length_immediate" "1")
10744 (set_attr "prefix" "orig,vex")
10745 (set_attr "mode" "<MODE>")])
10747 ;; Basic conditional jump instructions.
10748 ;; We ignore the overflow flag for signed branch instructions.
10750 (define_insn "*jcc_1"
10752 (if_then_else (match_operator 1 "ix86_comparison_operator"
10753 [(reg FLAGS_REG) (const_int 0)])
10754 (label_ref (match_operand 0 "" ""))
10758 [(set_attr "type" "ibr")
10759 (set_attr "modrm" "0")
10760 (set (attr "length")
10761 (if_then_else (and (ge (minus (match_dup 0) (pc))
10763 (lt (minus (match_dup 0) (pc))
10768 (define_insn "*jcc_2"
10770 (if_then_else (match_operator 1 "ix86_comparison_operator"
10771 [(reg FLAGS_REG) (const_int 0)])
10773 (label_ref (match_operand 0 "" ""))))]
10776 [(set_attr "type" "ibr")
10777 (set_attr "modrm" "0")
10778 (set (attr "length")
10779 (if_then_else (and (ge (minus (match_dup 0) (pc))
10781 (lt (minus (match_dup 0) (pc))
10786 ;; In general it is not safe to assume too much about CCmode registers,
10787 ;; so simplify-rtx stops when it sees a second one. Under certain
10788 ;; conditions this is safe on x86, so help combine not create
10796 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10797 [(reg FLAGS_REG) (const_int 0)])
10799 (label_ref (match_operand 1 "" ""))
10803 (if_then_else (match_dup 0)
10804 (label_ref (match_dup 1))
10806 "PUT_MODE (operands[0], VOIDmode);")
10810 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10811 [(reg FLAGS_REG) (const_int 0)])
10813 (label_ref (match_operand 1 "" ""))
10817 (if_then_else (match_dup 0)
10818 (label_ref (match_dup 1))
10821 rtx new_op0 = copy_rtx (operands[0]);
10822 operands[0] = new_op0;
10823 PUT_MODE (new_op0, VOIDmode);
10824 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10825 GET_MODE (XEXP (new_op0, 0))));
10827 /* Make sure that (a) the CCmode we have for the flags is strong
10828 enough for the reversed compare or (b) we have a valid FP compare. */
10829 if (! ix86_comparison_operator (new_op0, VOIDmode))
10833 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10834 ;; pass generates from shift insn with QImode operand. Actually, the mode
10835 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10836 ;; appropriate modulo of the bit offset value.
10838 (define_insn_and_split "*jcc_bt<mode>"
10840 (if_then_else (match_operator 0 "bt_comparison_operator"
10841 [(zero_extract:SWI48
10842 (match_operand:SWI48 1 "register_operand" "r")
10845 (match_operand:QI 2 "register_operand" "r")))
10847 (label_ref (match_operand 3 "" ""))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10853 [(set (reg:CCC FLAGS_REG)
10855 (zero_extract:SWI48
10861 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10862 (label_ref (match_dup 3))
10865 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10867 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10870 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10871 ;; also for DImode, this is what combine produces.
10872 (define_insn_and_split "*jcc_bt<mode>_mask"
10874 (if_then_else (match_operator 0 "bt_comparison_operator"
10875 [(zero_extract:SWI48
10876 (match_operand:SWI48 1 "register_operand" "r")
10879 (match_operand:SI 2 "register_operand" "r")
10880 (match_operand:SI 3 "const_int_operand" "n")))])
10881 (label_ref (match_operand 4 "" ""))
10883 (clobber (reg:CC FLAGS_REG))]
10884 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10885 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10886 == GET_MODE_BITSIZE (<MODE>mode)-1"
10889 [(set (reg:CCC FLAGS_REG)
10891 (zero_extract:SWI48
10897 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10898 (label_ref (match_dup 4))
10901 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10903 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10906 (define_insn_and_split "*jcc_btsi_1"
10908 (if_then_else (match_operator 0 "bt_comparison_operator"
10911 (match_operand:SI 1 "register_operand" "r")
10912 (match_operand:QI 2 "register_operand" "r"))
10915 (label_ref (match_operand 3 "" ""))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10921 [(set (reg:CCC FLAGS_REG)
10929 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10930 (label_ref (match_dup 3))
10933 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10935 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10938 ;; avoid useless masking of bit offset operand
10939 (define_insn_and_split "*jcc_btsi_mask_1"
10942 (match_operator 0 "bt_comparison_operator"
10945 (match_operand:SI 1 "register_operand" "r")
10948 (match_operand:SI 2 "register_operand" "r")
10949 (match_operand:SI 3 "const_int_operand" "n")) 0))
10952 (label_ref (match_operand 4 "" ""))
10954 (clobber (reg:CC FLAGS_REG))]
10955 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10956 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10959 [(set (reg:CCC FLAGS_REG)
10967 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10968 (label_ref (match_dup 4))
10970 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10972 ;; Define combination compare-and-branch fp compare instructions to help
10975 (define_insn "*fp_jcc_1_387"
10977 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978 [(match_operand 1 "register_operand" "f")
10979 (match_operand 2 "nonimmediate_operand" "fm")])
10980 (label_ref (match_operand 3 "" ""))
10982 (clobber (reg:CCFP FPSR_REG))
10983 (clobber (reg:CCFP FLAGS_REG))
10984 (clobber (match_scratch:HI 4 "=a"))]
10986 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988 && SELECT_CC_MODE (GET_CODE (operands[0]),
10989 operands[1], operands[2]) == CCFPmode
10993 (define_insn "*fp_jcc_1r_387"
10995 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10996 [(match_operand 1 "register_operand" "f")
10997 (match_operand 2 "nonimmediate_operand" "fm")])
10999 (label_ref (match_operand 3 "" ""))))
11000 (clobber (reg:CCFP FPSR_REG))
11001 (clobber (reg:CCFP FLAGS_REG))
11002 (clobber (match_scratch:HI 4 "=a"))]
11004 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11005 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11006 && SELECT_CC_MODE (GET_CODE (operands[0]),
11007 operands[1], operands[2]) == CCFPmode
11011 (define_insn "*fp_jcc_2_387"
11013 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11014 [(match_operand 1 "register_operand" "f")
11015 (match_operand 2 "register_operand" "f")])
11016 (label_ref (match_operand 3 "" ""))
11018 (clobber (reg:CCFP FPSR_REG))
11019 (clobber (reg:CCFP FLAGS_REG))
11020 (clobber (match_scratch:HI 4 "=a"))]
11021 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11022 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11026 (define_insn "*fp_jcc_2r_387"
11028 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11029 [(match_operand 1 "register_operand" "f")
11030 (match_operand 2 "register_operand" "f")])
11032 (label_ref (match_operand 3 "" ""))))
11033 (clobber (reg:CCFP FPSR_REG))
11034 (clobber (reg:CCFP FLAGS_REG))
11035 (clobber (match_scratch:HI 4 "=a"))]
11036 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11037 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11041 (define_insn "*fp_jcc_3_387"
11043 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11044 [(match_operand 1 "register_operand" "f")
11045 (match_operand 2 "const0_operand" "")])
11046 (label_ref (match_operand 3 "" ""))
11048 (clobber (reg:CCFP FPSR_REG))
11049 (clobber (reg:CCFP FLAGS_REG))
11050 (clobber (match_scratch:HI 4 "=a"))]
11051 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11052 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11053 && SELECT_CC_MODE (GET_CODE (operands[0]),
11054 operands[1], operands[2]) == CCFPmode
11060 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11061 [(match_operand 1 "register_operand" "")
11062 (match_operand 2 "nonimmediate_operand" "")])
11063 (match_operand 3 "" "")
11064 (match_operand 4 "" "")))
11065 (clobber (reg:CCFP FPSR_REG))
11066 (clobber (reg:CCFP FLAGS_REG))]
11070 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11071 operands[3], operands[4], NULL_RTX, NULL_RTX);
11077 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11078 [(match_operand 1 "register_operand" "")
11079 (match_operand 2 "general_operand" "")])
11080 (match_operand 3 "" "")
11081 (match_operand 4 "" "")))
11082 (clobber (reg:CCFP FPSR_REG))
11083 (clobber (reg:CCFP FLAGS_REG))
11084 (clobber (match_scratch:HI 5 "=a"))]
11088 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11089 operands[3], operands[4], operands[5], NULL_RTX);
11093 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11094 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11095 ;; with a precedence over other operators and is always put in the first
11096 ;; place. Swap condition and operands to match ficom instruction.
11098 (define_insn "*fp_jcc_4_<mode>_387"
11101 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11102 [(match_operator 1 "float_operator"
11103 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11104 (match_operand 3 "register_operand" "f,f")])
11105 (label_ref (match_operand 4 "" ""))
11107 (clobber (reg:CCFP FPSR_REG))
11108 (clobber (reg:CCFP FLAGS_REG))
11109 (clobber (match_scratch:HI 5 "=a,a"))]
11110 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11111 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11112 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11113 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11120 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11121 [(match_operator 1 "float_operator"
11122 [(match_operand:SWI24 2 "memory_operand" "")])
11123 (match_operand 3 "register_operand" "")])
11124 (match_operand 4 "" "")
11125 (match_operand 5 "" "")))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 6 "=a"))]
11132 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11134 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11135 operands[3], operands[7],
11136 operands[4], operands[5], operands[6], NULL_RTX);
11140 ;; %%% Kill this when reload knows how to do it.
11144 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11145 [(match_operator 1 "float_operator"
11146 [(match_operand:SWI24 2 "register_operand" "")])
11147 (match_operand 3 "register_operand" "")])
11148 (match_operand 4 "" "")
11149 (match_operand 5 "" "")))
11150 (clobber (reg:CCFP FPSR_REG))
11151 (clobber (reg:CCFP FLAGS_REG))
11152 (clobber (match_scratch:HI 6 "=a"))]
11156 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11157 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11159 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11160 operands[3], operands[7],
11161 operands[4], operands[5], operands[6], operands[2]);
11165 ;; Unconditional and other jump instructions
11167 (define_insn "jump"
11169 (label_ref (match_operand 0 "" "")))]
11172 [(set_attr "type" "ibr")
11173 (set (attr "length")
11174 (if_then_else (and (ge (minus (match_dup 0) (pc))
11176 (lt (minus (match_dup 0) (pc))
11180 (set_attr "modrm" "0")])
11182 (define_expand "indirect_jump"
11183 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11185 (define_insn "*indirect_jump"
11186 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11189 [(set_attr "type" "ibr")
11190 (set_attr "length_immediate" "0")])
11192 (define_expand "tablejump"
11193 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11194 (use (label_ref (match_operand 1 "" "")))])]
11197 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11198 relative. Convert the relative address to an absolute address. */
11202 enum rtx_code code;
11204 /* We can't use @GOTOFF for text labels on VxWorks;
11205 see gotoff_operand. */
11206 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11210 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11212 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11216 op1 = pic_offset_table_rtx;
11221 op0 = pic_offset_table_rtx;
11225 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11228 else if (TARGET_X32)
11229 operands[0] = convert_memory_address (Pmode, operands[0]);
11232 (define_insn "*tablejump_1"
11233 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11234 (use (label_ref (match_operand 1 "" "")))]
11237 [(set_attr "type" "ibr")
11238 (set_attr "length_immediate" "0")])
11240 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11243 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11244 (set (match_operand:QI 1 "register_operand" "")
11245 (match_operator:QI 2 "ix86_comparison_operator"
11246 [(reg FLAGS_REG) (const_int 0)]))
11247 (set (match_operand 3 "q_regs_operand" "")
11248 (zero_extend (match_dup 1)))]
11249 "(peep2_reg_dead_p (3, operands[1])
11250 || operands_match_p (operands[1], operands[3]))
11251 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11252 [(set (match_dup 4) (match_dup 0))
11253 (set (strict_low_part (match_dup 5))
11256 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11257 operands[5] = gen_lowpart (QImode, operands[3]);
11258 ix86_expand_clear (operands[3]);
11261 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11264 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11265 (set (match_operand:QI 1 "register_operand" "")
11266 (match_operator:QI 2 "ix86_comparison_operator"
11267 [(reg FLAGS_REG) (const_int 0)]))
11268 (parallel [(set (match_operand 3 "q_regs_operand" "")
11269 (zero_extend (match_dup 1)))
11270 (clobber (reg:CC FLAGS_REG))])]
11271 "(peep2_reg_dead_p (3, operands[1])
11272 || operands_match_p (operands[1], operands[3]))
11273 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11274 [(set (match_dup 4) (match_dup 0))
11275 (set (strict_low_part (match_dup 5))
11278 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11279 operands[5] = gen_lowpart (QImode, operands[3]);
11280 ix86_expand_clear (operands[3]);
11283 ;; Call instructions.
11285 ;; The predicates normally associated with named expanders are not properly
11286 ;; checked for calls. This is a bug in the generic code, but it isn't that
11287 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11289 ;; P6 processors will jump to the address after the decrement when %esp
11290 ;; is used as a call operand, so they will execute return address as a code.
11291 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11293 ;; Register constraint for call instruction.
11294 (define_mode_attr c [(SI "l") (DI "r")])
11296 ;; Call subroutine returning no value.
11298 (define_expand "call"
11299 [(call (match_operand:QI 0 "" "")
11300 (match_operand 1 "" ""))
11301 (use (match_operand 2 "" ""))]
11304 ix86_expand_call (NULL, operands[0], operands[1],
11305 operands[2], NULL, false);
11309 (define_expand "sibcall"
11310 [(call (match_operand:QI 0 "" "")
11311 (match_operand 1 "" ""))
11312 (use (match_operand 2 "" ""))]
11315 ix86_expand_call (NULL, operands[0], operands[1],
11316 operands[2], NULL, true);
11320 (define_insn_and_split "*call_vzeroupper"
11321 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11322 (match_operand 1 "" ""))
11323 (unspec [(match_operand 2 "const_int_operand" "")]
11324 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11325 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11327 "&& reload_completed"
11329 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11330 [(set_attr "type" "call")])
11332 (define_insn "*call"
11333 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11334 (match_operand 1 "" ""))]
11335 "!SIBLING_CALL_P (insn)"
11336 "* return ix86_output_call_insn (insn, operands[0]);"
11337 [(set_attr "type" "call")])
11339 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11340 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11341 (match_operand 1 "" ""))
11342 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11343 (clobber (reg:TI XMM6_REG))
11344 (clobber (reg:TI XMM7_REG))
11345 (clobber (reg:TI XMM8_REG))
11346 (clobber (reg:TI XMM9_REG))
11347 (clobber (reg:TI XMM10_REG))
11348 (clobber (reg:TI XMM11_REG))
11349 (clobber (reg:TI XMM12_REG))
11350 (clobber (reg:TI XMM13_REG))
11351 (clobber (reg:TI XMM14_REG))
11352 (clobber (reg:TI XMM15_REG))
11353 (clobber (reg:DI SI_REG))
11354 (clobber (reg:DI DI_REG))
11355 (unspec [(match_operand 2 "const_int_operand" "")]
11356 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11357 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11359 "&& reload_completed"
11361 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11362 [(set_attr "type" "call")])
11364 (define_insn "*call_rex64_ms_sysv"
11365 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11366 (match_operand 1 "" ""))
11367 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11368 (clobber (reg:TI XMM6_REG))
11369 (clobber (reg:TI XMM7_REG))
11370 (clobber (reg:TI XMM8_REG))
11371 (clobber (reg:TI XMM9_REG))
11372 (clobber (reg:TI XMM10_REG))
11373 (clobber (reg:TI XMM11_REG))
11374 (clobber (reg:TI XMM12_REG))
11375 (clobber (reg:TI XMM13_REG))
11376 (clobber (reg:TI XMM14_REG))
11377 (clobber (reg:TI XMM15_REG))
11378 (clobber (reg:DI SI_REG))
11379 (clobber (reg:DI DI_REG))]
11380 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11381 "* return ix86_output_call_insn (insn, operands[0]);"
11382 [(set_attr "type" "call")])
11384 (define_insn_and_split "*sibcall_vzeroupper"
11385 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11386 (match_operand 1 "" ""))
11387 (unspec [(match_operand 2 "const_int_operand" "")]
11388 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11389 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11391 "&& reload_completed"
11393 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11394 [(set_attr "type" "call")])
11396 (define_insn "*sibcall"
11397 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11398 (match_operand 1 "" ""))]
11399 "SIBLING_CALL_P (insn)"
11400 "* return ix86_output_call_insn (insn, operands[0]);"
11401 [(set_attr "type" "call")])
11403 (define_expand "call_pop"
11404 [(parallel [(call (match_operand:QI 0 "" "")
11405 (match_operand:SI 1 "" ""))
11406 (set (reg:SI SP_REG)
11407 (plus:SI (reg:SI SP_REG)
11408 (match_operand:SI 3 "" "")))])]
11411 ix86_expand_call (NULL, operands[0], operands[1],
11412 operands[2], operands[3], false);
11416 (define_insn_and_split "*call_pop_vzeroupper"
11417 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11418 (match_operand:SI 1 "" ""))
11419 (set (reg:SI SP_REG)
11420 (plus:SI (reg:SI SP_REG)
11421 (match_operand:SI 2 "immediate_operand" "i")))
11422 (unspec [(match_operand 3 "const_int_operand" "")]
11423 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11424 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11426 "&& reload_completed"
11428 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11429 [(set_attr "type" "call")])
11431 (define_insn "*call_pop"
11432 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11433 (match_operand 1 "" ""))
11434 (set (reg:SI SP_REG)
11435 (plus:SI (reg:SI SP_REG)
11436 (match_operand:SI 2 "immediate_operand" "i")))]
11437 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11438 "* return ix86_output_call_insn (insn, operands[0]);"
11439 [(set_attr "type" "call")])
11441 (define_insn_and_split "*sibcall_pop_vzeroupper"
11442 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11443 (match_operand 1 "" ""))
11444 (set (reg:SI SP_REG)
11445 (plus:SI (reg:SI SP_REG)
11446 (match_operand:SI 2 "immediate_operand" "i")))
11447 (unspec [(match_operand 3 "const_int_operand" "")]
11448 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11449 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11451 "&& reload_completed"
11453 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11454 [(set_attr "type" "call")])
11456 (define_insn "*sibcall_pop"
11457 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11458 (match_operand 1 "" ""))
11459 (set (reg:SI SP_REG)
11460 (plus:SI (reg:SI SP_REG)
11461 (match_operand:SI 2 "immediate_operand" "i")))]
11462 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11463 "* return ix86_output_call_insn (insn, operands[0]);"
11464 [(set_attr "type" "call")])
11466 ;; Call subroutine, returning value in operand 0
11468 (define_expand "call_value"
11469 [(set (match_operand 0 "" "")
11470 (call (match_operand:QI 1 "" "")
11471 (match_operand 2 "" "")))
11472 (use (match_operand 3 "" ""))]
11475 ix86_expand_call (operands[0], operands[1], operands[2],
11476 operands[3], NULL, false);
11480 (define_expand "sibcall_value"
11481 [(set (match_operand 0 "" "")
11482 (call (match_operand:QI 1 "" "")
11483 (match_operand 2 "" "")))
11484 (use (match_operand 3 "" ""))]
11487 ix86_expand_call (operands[0], operands[1], operands[2],
11488 operands[3], NULL, true);
11492 (define_insn_and_split "*call_value_vzeroupper"
11493 [(set (match_operand 0 "" "")
11494 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11495 (match_operand 2 "" "")))
11496 (unspec [(match_operand 3 "const_int_operand" "")]
11497 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11498 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11500 "&& reload_completed"
11502 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11503 [(set_attr "type" "callv")])
11505 (define_insn "*call_value"
11506 [(set (match_operand 0 "" "")
11507 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11508 (match_operand 2 "" "")))]
11509 "!SIBLING_CALL_P (insn)"
11510 "* return ix86_output_call_insn (insn, operands[1]);"
11511 [(set_attr "type" "callv")])
11513 (define_insn_and_split "*sibcall_value_vzeroupper"
11514 [(set (match_operand 0 "" "")
11515 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11516 (match_operand 2 "" "")))
11517 (unspec [(match_operand 3 "const_int_operand" "")]
11518 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11519 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11521 "&& reload_completed"
11523 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11524 [(set_attr "type" "callv")])
11526 (define_insn "*sibcall_value"
11527 [(set (match_operand 0 "" "")
11528 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11529 (match_operand 2 "" "")))]
11530 "SIBLING_CALL_P (insn)"
11531 "* return ix86_output_call_insn (insn, operands[1]);"
11532 [(set_attr "type" "callv")])
11534 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11535 [(set (match_operand 0 "" "")
11536 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11537 (match_operand 2 "" "")))
11538 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11539 (clobber (reg:TI XMM6_REG))
11540 (clobber (reg:TI XMM7_REG))
11541 (clobber (reg:TI XMM8_REG))
11542 (clobber (reg:TI XMM9_REG))
11543 (clobber (reg:TI XMM10_REG))
11544 (clobber (reg:TI XMM11_REG))
11545 (clobber (reg:TI XMM12_REG))
11546 (clobber (reg:TI XMM13_REG))
11547 (clobber (reg:TI XMM14_REG))
11548 (clobber (reg:TI XMM15_REG))
11549 (clobber (reg:DI SI_REG))
11550 (clobber (reg:DI DI_REG))
11551 (unspec [(match_operand 3 "const_int_operand" "")]
11552 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11553 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555 "&& reload_completed"
11557 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11558 [(set_attr "type" "callv")])
11560 (define_insn "*call_value_rex64_ms_sysv"
11561 [(set (match_operand 0 "" "")
11562 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11563 (match_operand 2 "" "")))
11564 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11565 (clobber (reg:TI XMM6_REG))
11566 (clobber (reg:TI XMM7_REG))
11567 (clobber (reg:TI XMM8_REG))
11568 (clobber (reg:TI XMM9_REG))
11569 (clobber (reg:TI XMM10_REG))
11570 (clobber (reg:TI XMM11_REG))
11571 (clobber (reg:TI XMM12_REG))
11572 (clobber (reg:TI XMM13_REG))
11573 (clobber (reg:TI XMM14_REG))
11574 (clobber (reg:TI XMM15_REG))
11575 (clobber (reg:DI SI_REG))
11576 (clobber (reg:DI DI_REG))]
11577 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11578 "* return ix86_output_call_insn (insn, operands[1]);"
11579 [(set_attr "type" "callv")])
11581 (define_expand "call_value_pop"
11582 [(parallel [(set (match_operand 0 "" "")
11583 (call (match_operand:QI 1 "" "")
11584 (match_operand:SI 2 "" "")))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 4 "" "")))])]
11590 ix86_expand_call (operands[0], operands[1], operands[2],
11591 operands[3], operands[4], false);
11595 (define_insn_and_split "*call_value_pop_vzeroupper"
11596 [(set (match_operand 0 "" "")
11597 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11598 (match_operand 2 "" "")))
11599 (set (reg:SI SP_REG)
11600 (plus:SI (reg:SI SP_REG)
11601 (match_operand:SI 3 "immediate_operand" "i")))
11602 (unspec [(match_operand 4 "const_int_operand" "")]
11603 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11604 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11606 "&& reload_completed"
11608 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11609 [(set_attr "type" "callv")])
11611 (define_insn "*call_value_pop"
11612 [(set (match_operand 0 "" "")
11613 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11614 (match_operand 2 "" "")))
11615 (set (reg:SI SP_REG)
11616 (plus:SI (reg:SI SP_REG)
11617 (match_operand:SI 3 "immediate_operand" "i")))]
11618 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11619 "* return ix86_output_call_insn (insn, operands[1]);"
11620 [(set_attr "type" "callv")])
11622 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11623 [(set (match_operand 0 "" "")
11624 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11625 (match_operand 2 "" "")))
11626 (set (reg:SI SP_REG)
11627 (plus:SI (reg:SI SP_REG)
11628 (match_operand:SI 3 "immediate_operand" "i")))
11629 (unspec [(match_operand 4 "const_int_operand" "")]
11630 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11631 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11633 "&& reload_completed"
11635 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11636 [(set_attr "type" "callv")])
11638 (define_insn "*sibcall_value_pop"
11639 [(set (match_operand 0 "" "")
11640 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11641 (match_operand 2 "" "")))
11642 (set (reg:SI SP_REG)
11643 (plus:SI (reg:SI SP_REG)
11644 (match_operand:SI 3 "immediate_operand" "i")))]
11645 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11646 "* return ix86_output_call_insn (insn, operands[1]);"
11647 [(set_attr "type" "callv")])
11649 ;; Call subroutine returning any type.
11651 (define_expand "untyped_call"
11652 [(parallel [(call (match_operand 0 "" "")
11654 (match_operand 1 "" "")
11655 (match_operand 2 "" "")])]
11660 /* In order to give reg-stack an easier job in validating two
11661 coprocessor registers as containing a possible return value,
11662 simply pretend the untyped call returns a complex long double
11665 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11666 and should have the default ABI. */
11668 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11669 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11670 operands[0], const0_rtx,
11671 GEN_INT ((TARGET_64BIT
11672 ? (ix86_abi == SYSV_ABI
11673 ? X86_64_SSE_REGPARM_MAX
11674 : X86_64_MS_SSE_REGPARM_MAX)
11675 : X86_32_SSE_REGPARM_MAX)
11679 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11681 rtx set = XVECEXP (operands[2], 0, i);
11682 emit_move_insn (SET_DEST (set), SET_SRC (set));
11685 /* The optimizer does not know that the call sets the function value
11686 registers we stored in the result block. We avoid problems by
11687 claiming that all hard registers are used and clobbered at this
11689 emit_insn (gen_blockage ());
11694 ;; Prologue and epilogue instructions
11696 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11697 ;; all of memory. This blocks insns from being moved across this point.
11699 (define_insn "blockage"
11700 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11703 [(set_attr "length" "0")])
11705 ;; Do not schedule instructions accessing memory across this point.
11707 (define_expand "memory_blockage"
11708 [(set (match_dup 0)
11709 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11712 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11713 MEM_VOLATILE_P (operands[0]) = 1;
11716 (define_insn "*memory_blockage"
11717 [(set (match_operand:BLK 0 "" "")
11718 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11721 [(set_attr "length" "0")])
11723 ;; As USE insns aren't meaningful after reload, this is used instead
11724 ;; to prevent deleting instructions setting registers for PIC code
11725 (define_insn "prologue_use"
11726 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11729 [(set_attr "length" "0")])
11731 ;; Insn emitted into the body of a function to return from a function.
11732 ;; This is only done if the function's epilogue is known to be simple.
11733 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11735 (define_expand "return"
11737 "ix86_can_use_return_insn_p ()"
11739 ix86_maybe_emit_epilogue_vzeroupper ();
11740 if (crtl->args.pops_args)
11742 rtx popc = GEN_INT (crtl->args.pops_args);
11743 emit_jump_insn (gen_simple_return_pop_internal (popc));
11748 ;; We need to disable this for TARGET_SEH, as otherwise
11749 ;; shrink-wrapped prologue gets enabled too. This might exceed
11750 ;; the maximum size of prologue in unwind information.
11752 (define_expand "simple_return"
11756 ix86_maybe_emit_epilogue_vzeroupper ();
11757 if (crtl->args.pops_args)
11759 rtx popc = GEN_INT (crtl->args.pops_args);
11760 emit_jump_insn (gen_simple_return_pop_internal (popc));
11765 (define_insn "simple_return_internal"
11769 [(set_attr "length" "1")
11770 (set_attr "atom_unit" "jeu")
11771 (set_attr "length_immediate" "0")
11772 (set_attr "modrm" "0")])
11774 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11775 ;; instruction Athlon and K8 have.
11777 (define_insn "simple_return_internal_long"
11779 (unspec [(const_int 0)] UNSPEC_REP)]
11782 [(set_attr "length" "2")
11783 (set_attr "atom_unit" "jeu")
11784 (set_attr "length_immediate" "0")
11785 (set_attr "prefix_rep" "1")
11786 (set_attr "modrm" "0")])
11788 (define_insn "simple_return_pop_internal"
11790 (use (match_operand:SI 0 "const_int_operand" ""))]
11793 [(set_attr "length" "3")
11794 (set_attr "atom_unit" "jeu")
11795 (set_attr "length_immediate" "2")
11796 (set_attr "modrm" "0")])
11798 (define_insn "simple_return_indirect_internal"
11800 (use (match_operand:SI 0 "register_operand" "r"))]
11803 [(set_attr "type" "ibr")
11804 (set_attr "length_immediate" "0")])
11810 [(set_attr "length" "1")
11811 (set_attr "length_immediate" "0")
11812 (set_attr "modrm" "0")])
11814 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11815 (define_insn "nops"
11816 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11820 int num = INTVAL (operands[0]);
11822 gcc_assert (num >= 1 && num <= 8);
11825 fputs ("\tnop\n", asm_out_file);
11829 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11830 (set_attr "length_immediate" "0")
11831 (set_attr "modrm" "0")])
11833 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11834 ;; branch prediction penalty for the third jump in a 16-byte
11838 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11841 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11842 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11844 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11845 The align insn is used to avoid 3 jump instructions in the row to improve
11846 branch prediction and the benefits hardly outweigh the cost of extra 8
11847 nops on the average inserted by full alignment pseudo operation. */
11851 [(set_attr "length" "16")])
11853 (define_expand "prologue"
11856 "ix86_expand_prologue (); DONE;")
11858 (define_insn "set_got"
11859 [(set (match_operand:SI 0 "register_operand" "=r")
11860 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11861 (clobber (reg:CC FLAGS_REG))]
11863 "* return output_set_got (operands[0], NULL_RTX);"
11864 [(set_attr "type" "multi")
11865 (set_attr "length" "12")])
11867 (define_insn "set_got_labelled"
11868 [(set (match_operand:SI 0 "register_operand" "=r")
11869 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11871 (clobber (reg:CC FLAGS_REG))]
11873 "* return output_set_got (operands[0], operands[1]);"
11874 [(set_attr "type" "multi")
11875 (set_attr "length" "12")])
11877 (define_insn "set_got_rex64"
11878 [(set (match_operand:DI 0 "register_operand" "=r")
11879 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11881 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11882 [(set_attr "type" "lea")
11883 (set_attr "length_address" "4")
11884 (set_attr "mode" "DI")])
11886 (define_insn "set_rip_rex64"
11887 [(set (match_operand:DI 0 "register_operand" "=r")
11888 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11890 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11891 [(set_attr "type" "lea")
11892 (set_attr "length_address" "4")
11893 (set_attr "mode" "DI")])
11895 (define_insn "set_got_offset_rex64"
11896 [(set (match_operand:DI 0 "register_operand" "=r")
11898 [(label_ref (match_operand 1 "" ""))]
11899 UNSPEC_SET_GOT_OFFSET))]
11901 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11902 [(set_attr "type" "imov")
11903 (set_attr "length_immediate" "0")
11904 (set_attr "length_address" "8")
11905 (set_attr "mode" "DI")])
11907 (define_expand "epilogue"
11910 "ix86_expand_epilogue (1); DONE;")
11912 (define_expand "sibcall_epilogue"
11915 "ix86_expand_epilogue (0); DONE;")
11917 (define_expand "eh_return"
11918 [(use (match_operand 0 "register_operand" ""))]
11921 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11923 /* Tricky bit: we write the address of the handler to which we will
11924 be returning into someone else's stack frame, one word below the
11925 stack address we wish to restore. */
11926 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11927 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11928 tmp = gen_rtx_MEM (Pmode, tmp);
11929 emit_move_insn (tmp, ra);
11931 emit_jump_insn (gen_eh_return_internal ());
11936 (define_insn_and_split "eh_return_internal"
11940 "epilogue_completed"
11942 "ix86_expand_epilogue (2); DONE;")
11944 (define_insn "leave"
11945 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11946 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11947 (clobber (mem:BLK (scratch)))]
11950 [(set_attr "type" "leave")])
11952 (define_insn "leave_rex64"
11953 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11954 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11955 (clobber (mem:BLK (scratch)))]
11958 [(set_attr "type" "leave")])
11960 ;; Handle -fsplit-stack.
11962 (define_expand "split_stack_prologue"
11966 ix86_expand_split_stack_prologue ();
11970 ;; In order to support the call/return predictor, we use a return
11971 ;; instruction which the middle-end doesn't see.
11972 (define_insn "split_stack_return"
11973 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11974 UNSPECV_SPLIT_STACK_RETURN)]
11977 if (operands[0] == const0_rtx)
11982 [(set_attr "atom_unit" "jeu")
11983 (set_attr "modrm" "0")
11984 (set (attr "length")
11985 (if_then_else (match_operand:SI 0 "const0_operand" "")
11988 (set (attr "length_immediate")
11989 (if_then_else (match_operand:SI 0 "const0_operand" "")
11993 ;; If there are operand 0 bytes available on the stack, jump to
11996 (define_expand "split_stack_space_check"
11997 [(set (pc) (if_then_else
11998 (ltu (minus (reg SP_REG)
11999 (match_operand 0 "register_operand" ""))
12000 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12001 (label_ref (match_operand 1 "" ""))
12005 rtx reg, size, limit;
12007 reg = gen_reg_rtx (Pmode);
12008 size = force_reg (Pmode, operands[0]);
12009 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12010 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12011 UNSPEC_STACK_CHECK);
12012 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12013 ix86_expand_branch (GEU, reg, limit, operands[1]);
12018 ;; Bit manipulation instructions.
12020 (define_expand "ffs<mode>2"
12021 [(set (match_dup 2) (const_int -1))
12022 (parallel [(set (reg:CCZ FLAGS_REG)
12024 (match_operand:SWI48 1 "nonimmediate_operand" "")
12026 (set (match_operand:SWI48 0 "register_operand" "")
12027 (ctz:SWI48 (match_dup 1)))])
12028 (set (match_dup 0) (if_then_else:SWI48
12029 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12032 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12033 (clobber (reg:CC FLAGS_REG))])]
12036 if (<MODE>mode == SImode && !TARGET_CMOVE)
12038 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12041 operands[2] = gen_reg_rtx (<MODE>mode);
12044 (define_insn_and_split "ffssi2_no_cmove"
12045 [(set (match_operand:SI 0 "register_operand" "=r")
12046 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12047 (clobber (match_scratch:SI 2 "=&q"))
12048 (clobber (reg:CC FLAGS_REG))]
12051 "&& reload_completed"
12052 [(parallel [(set (reg:CCZ FLAGS_REG)
12053 (compare:CCZ (match_dup 1) (const_int 0)))
12054 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12055 (set (strict_low_part (match_dup 3))
12056 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12057 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12058 (clobber (reg:CC FLAGS_REG))])
12059 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12060 (clobber (reg:CC FLAGS_REG))])
12061 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12062 (clobber (reg:CC FLAGS_REG))])]
12064 operands[3] = gen_lowpart (QImode, operands[2]);
12065 ix86_expand_clear (operands[2]);
12068 (define_insn "*ffs<mode>_1"
12069 [(set (reg:CCZ FLAGS_REG)
12070 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12072 (set (match_operand:SWI48 0 "register_operand" "=r")
12073 (ctz:SWI48 (match_dup 1)))]
12075 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12076 [(set_attr "type" "alu1")
12077 (set_attr "prefix_0f" "1")
12078 (set_attr "mode" "<MODE>")])
12080 (define_insn "ctz<mode>2"
12081 [(set (match_operand:SWI248 0 "register_operand" "=r")
12082 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12083 (clobber (reg:CC FLAGS_REG))]
12087 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12089 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12091 [(set_attr "type" "alu1")
12092 (set_attr "prefix_0f" "1")
12093 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12094 (set_attr "mode" "<MODE>")])
12096 (define_expand "clz<mode>2"
12098 [(set (match_operand:SWI248 0 "register_operand" "")
12101 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12102 (clobber (reg:CC FLAGS_REG))])
12104 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12105 (clobber (reg:CC FLAGS_REG))])]
12110 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12113 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12116 (define_insn "clz<mode>2_lzcnt"
12117 [(set (match_operand:SWI248 0 "register_operand" "=r")
12118 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12122 [(set_attr "prefix_rep" "1")
12123 (set_attr "type" "bitmanip")
12124 (set_attr "mode" "<MODE>")])
12126 ;; BMI instructions.
12127 (define_insn "*bmi_andn_<mode>"
12128 [(set (match_operand:SWI48 0 "register_operand" "=r")
12131 (match_operand:SWI48 1 "register_operand" "r"))
12132 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12133 (clobber (reg:CC FLAGS_REG))]
12135 "andn\t{%2, %1, %0|%0, %1, %2}"
12136 [(set_attr "type" "bitmanip")
12137 (set_attr "mode" "<MODE>")])
12139 (define_insn "bmi_bextr_<mode>"
12140 [(set (match_operand:SWI48 0 "register_operand" "=r")
12141 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12142 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12144 (clobber (reg:CC FLAGS_REG))]
12146 "bextr\t{%2, %1, %0|%0, %1, %2}"
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "mode" "<MODE>")])
12150 (define_insn "*bmi_blsi_<mode>"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12156 (clobber (reg:CC FLAGS_REG))]
12158 "blsi\t{%1, %0|%0, %1}"
12159 [(set_attr "type" "bitmanip")
12160 (set_attr "mode" "<MODE>")])
12162 (define_insn "*bmi_blsmsk_<mode>"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12166 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12169 (clobber (reg:CC FLAGS_REG))]
12171 "blsmsk\t{%1, %0|%0, %1}"
12172 [(set_attr "type" "bitmanip")
12173 (set_attr "mode" "<MODE>")])
12175 (define_insn "*bmi_blsr_<mode>"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12179 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182 (clobber (reg:CC FLAGS_REG))]
12184 "blsr\t{%1, %0|%0, %1}"
12185 [(set_attr "type" "bitmanip")
12186 (set_attr "mode" "<MODE>")])
12188 ;; BMI2 instructions.
12189 (define_insn "bmi2_bzhi_<mode>3"
12190 [(set (match_operand:SWI48 0 "register_operand" "=r")
12191 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12192 (lshiftrt:SWI48 (const_int -1)
12193 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12194 (clobber (reg:CC FLAGS_REG))]
12196 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12197 [(set_attr "type" "bitmanip")
12198 (set_attr "prefix" "vex")
12199 (set_attr "mode" "<MODE>")])
12201 (define_insn "bmi2_pdep_<mode>3"
12202 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12204 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12207 "pdep\t{%2, %1, %0|%0, %1, %2}"
12208 [(set_attr "type" "bitmanip")
12209 (set_attr "prefix" "vex")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "bmi2_pext_<mode>3"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12214 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12215 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12218 "pext\t{%2, %1, %0|%0, %1, %2}"
12219 [(set_attr "type" "bitmanip")
12220 (set_attr "prefix" "vex")
12221 (set_attr "mode" "<MODE>")])
12223 ;; TBM instructions.
12224 (define_insn "tbm_bextri_<mode>"
12225 [(set (match_operand:SWI48 0 "register_operand" "=r")
12226 (zero_extract:SWI48
12227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12229 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12230 (clobber (reg:CC FLAGS_REG))]
12233 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12234 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12236 [(set_attr "type" "bitmanip")
12237 (set_attr "mode" "<MODE>")])
12239 (define_insn "*tbm_blcfill_<mode>"
12240 [(set (match_operand:SWI48 0 "register_operand" "=r")
12243 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246 (clobber (reg:CC FLAGS_REG))]
12248 "blcfill\t{%1, %0|%0, %1}"
12249 [(set_attr "type" "bitmanip")
12250 (set_attr "mode" "<MODE>")])
12252 (define_insn "*tbm_blci_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r")
12257 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260 (clobber (reg:CC FLAGS_REG))]
12262 "blci\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "bitmanip")
12264 (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_blcic_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274 (clobber (reg:CC FLAGS_REG))]
12276 "blcic\t{%1, %0|%0, %1}"
12277 [(set_attr "type" "bitmanip")
12278 (set_attr "mode" "<MODE>")])
12280 (define_insn "*tbm_blcmsk_<mode>"
12281 [(set (match_operand:SWI48 0 "register_operand" "=r")
12284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (clobber (reg:CC FLAGS_REG))]
12289 "blcmsk\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "bitmanip")
12291 (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_blcs_<mode>"
12294 [(set (match_operand:SWI48 0 "register_operand" "=r")
12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12300 (clobber (reg:CC FLAGS_REG))]
12302 "blcs\t{%1, %0|%0, %1}"
12303 [(set_attr "type" "bitmanip")
12304 (set_attr "mode" "<MODE>")])
12306 (define_insn "*tbm_blsfill_<mode>"
12307 [(set (match_operand:SWI48 0 "register_operand" "=r")
12310 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313 (clobber (reg:CC FLAGS_REG))]
12315 "blsfill\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "bitmanip")
12317 (set_attr "mode" "<MODE>")])
12319 (define_insn "*tbm_blsic_<mode>"
12320 [(set (match_operand:SWI48 0 "register_operand" "=r")
12323 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12327 (clobber (reg:CC FLAGS_REG))]
12329 "blsic\t{%1, %0|%0, %1}"
12330 [(set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12333 (define_insn "*tbm_t1mskc_<mode>"
12334 [(set (match_operand:SWI48 0 "register_operand" "=r")
12337 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12341 (clobber (reg:CC FLAGS_REG))]
12343 "t1mskc\t{%1, %0|%0, %1}"
12344 [(set_attr "type" "bitmanip")
12345 (set_attr "mode" "<MODE>")])
12347 (define_insn "*tbm_tzmsk_<mode>"
12348 [(set (match_operand:SWI48 0 "register_operand" "=r")
12351 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12355 (clobber (reg:CC FLAGS_REG))]
12357 "tzmsk\t{%1, %0|%0, %1}"
12358 [(set_attr "type" "bitmanip")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "bsr_rex64"
12362 [(set (match_operand:DI 0 "register_operand" "=r")
12363 (minus:DI (const_int 63)
12364 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12365 (clobber (reg:CC FLAGS_REG))]
12367 "bsr{q}\t{%1, %0|%0, %1}"
12368 [(set_attr "type" "alu1")
12369 (set_attr "prefix_0f" "1")
12370 (set_attr "mode" "DI")])
12373 [(set (match_operand:SI 0 "register_operand" "=r")
12374 (minus:SI (const_int 31)
12375 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12376 (clobber (reg:CC FLAGS_REG))]
12378 "bsr{l}\t{%1, %0|%0, %1}"
12379 [(set_attr "type" "alu1")
12380 (set_attr "prefix_0f" "1")
12381 (set_attr "mode" "SI")])
12383 (define_insn "*bsrhi"
12384 [(set (match_operand:HI 0 "register_operand" "=r")
12385 (minus:HI (const_int 15)
12386 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12387 (clobber (reg:CC FLAGS_REG))]
12389 "bsr{w}\t{%1, %0|%0, %1}"
12390 [(set_attr "type" "alu1")
12391 (set_attr "prefix_0f" "1")
12392 (set_attr "mode" "HI")])
12394 (define_insn "popcount<mode>2"
12395 [(set (match_operand:SWI248 0 "register_operand" "=r")
12397 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12398 (clobber (reg:CC FLAGS_REG))]
12402 return "popcnt\t{%1, %0|%0, %1}";
12404 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12407 [(set_attr "prefix_rep" "1")
12408 (set_attr "type" "bitmanip")
12409 (set_attr "mode" "<MODE>")])
12411 (define_insn "*popcount<mode>2_cmp"
12412 [(set (reg FLAGS_REG)
12415 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12417 (set (match_operand:SWI248 0 "register_operand" "=r")
12418 (popcount:SWI248 (match_dup 1)))]
12419 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12422 return "popcnt\t{%1, %0|%0, %1}";
12424 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12427 [(set_attr "prefix_rep" "1")
12428 (set_attr "type" "bitmanip")
12429 (set_attr "mode" "<MODE>")])
12431 (define_insn "*popcountsi2_cmp_zext"
12432 [(set (reg FLAGS_REG)
12434 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12436 (set (match_operand:DI 0 "register_operand" "=r")
12437 (zero_extend:DI(popcount:SI (match_dup 1))))]
12438 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12441 return "popcnt\t{%1, %0|%0, %1}";
12443 return "popcnt{l}\t{%1, %0|%0, %1}";
12446 [(set_attr "prefix_rep" "1")
12447 (set_attr "type" "bitmanip")
12448 (set_attr "mode" "SI")])
12450 (define_expand "bswap<mode>2"
12451 [(set (match_operand:SWI48 0 "register_operand" "")
12452 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12455 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12457 rtx x = operands[0];
12459 emit_move_insn (x, operands[1]);
12460 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12461 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12462 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12467 (define_insn "*bswap<mode>2_movbe"
12468 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12469 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12471 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12474 movbe\t{%1, %0|%0, %1}
12475 movbe\t{%1, %0|%0, %1}"
12476 [(set_attr "type" "bitmanip,imov,imov")
12477 (set_attr "modrm" "0,1,1")
12478 (set_attr "prefix_0f" "*,1,1")
12479 (set_attr "prefix_extra" "*,1,1")
12480 (set_attr "mode" "<MODE>")])
12482 (define_insn "*bswap<mode>2_1"
12483 [(set (match_operand:SWI48 0 "register_operand" "=r")
12484 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12487 [(set_attr "type" "bitmanip")
12488 (set_attr "modrm" "0")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "*bswaphi_lowpart_1"
12492 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12493 (bswap:HI (match_dup 0)))
12494 (clobber (reg:CC FLAGS_REG))]
12495 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12497 xchg{b}\t{%h0, %b0|%b0, %h0}
12498 rol{w}\t{$8, %0|%0, 8}"
12499 [(set_attr "length" "2,4")
12500 (set_attr "mode" "QI,HI")])
12502 (define_insn "bswaphi_lowpart"
12503 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12504 (bswap:HI (match_dup 0)))
12505 (clobber (reg:CC FLAGS_REG))]
12507 "rol{w}\t{$8, %0|%0, 8}"
12508 [(set_attr "length" "4")
12509 (set_attr "mode" "HI")])
12511 (define_expand "paritydi2"
12512 [(set (match_operand:DI 0 "register_operand" "")
12513 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12516 rtx scratch = gen_reg_rtx (QImode);
12519 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12520 NULL_RTX, operands[1]));
12522 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12523 gen_rtx_REG (CCmode, FLAGS_REG),
12525 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12528 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12531 rtx tmp = gen_reg_rtx (SImode);
12533 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12534 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12539 (define_expand "paritysi2"
12540 [(set (match_operand:SI 0 "register_operand" "")
12541 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12544 rtx scratch = gen_reg_rtx (QImode);
12547 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12549 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12550 gen_rtx_REG (CCmode, FLAGS_REG),
12552 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12554 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12558 (define_insn_and_split "paritydi2_cmp"
12559 [(set (reg:CC FLAGS_REG)
12560 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12562 (clobber (match_scratch:DI 0 "=r"))
12563 (clobber (match_scratch:SI 1 "=&r"))
12564 (clobber (match_scratch:HI 2 "=Q"))]
12567 "&& reload_completed"
12569 [(set (match_dup 1)
12570 (xor:SI (match_dup 1) (match_dup 4)))
12571 (clobber (reg:CC FLAGS_REG))])
12573 [(set (reg:CC FLAGS_REG)
12574 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12575 (clobber (match_dup 1))
12576 (clobber (match_dup 2))])]
12578 operands[4] = gen_lowpart (SImode, operands[3]);
12582 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12583 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12586 operands[1] = gen_highpart (SImode, operands[3]);
12589 (define_insn_and_split "paritysi2_cmp"
12590 [(set (reg:CC FLAGS_REG)
12591 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12593 (clobber (match_scratch:SI 0 "=r"))
12594 (clobber (match_scratch:HI 1 "=&Q"))]
12597 "&& reload_completed"
12599 [(set (match_dup 1)
12600 (xor:HI (match_dup 1) (match_dup 3)))
12601 (clobber (reg:CC FLAGS_REG))])
12603 [(set (reg:CC FLAGS_REG)
12604 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12605 (clobber (match_dup 1))])]
12607 operands[3] = gen_lowpart (HImode, operands[2]);
12609 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12610 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12613 (define_insn "*parityhi2_cmp"
12614 [(set (reg:CC FLAGS_REG)
12615 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12617 (clobber (match_scratch:HI 0 "=Q"))]
12619 "xor{b}\t{%h0, %b0|%b0, %h0}"
12620 [(set_attr "length" "2")
12621 (set_attr "mode" "HI")])
12624 ;; Thread-local storage patterns for ELF.
12626 ;; Note that these code sequences must appear exactly as shown
12627 ;; in order to allow linker relaxation.
12629 (define_insn "*tls_global_dynamic_32_gnu"
12630 [(set (match_operand:SI 0 "register_operand" "=a")
12632 [(match_operand:SI 1 "register_operand" "b")
12633 (match_operand:SI 2 "tls_symbolic_operand" "")
12634 (match_operand:SI 3 "constant_call_address_operand" "z")]
12636 (clobber (match_scratch:SI 4 "=d"))
12637 (clobber (match_scratch:SI 5 "=c"))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "!TARGET_64BIT && TARGET_GNU_TLS"
12642 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12643 if (TARGET_SUN_TLS)
12644 #ifdef HAVE_AS_IX86_TLSGDPLT
12645 return "call\t%a2@tlsgdplt";
12647 return "call\t%p3@plt";
12649 return "call\t%P3";
12651 [(set_attr "type" "multi")
12652 (set_attr "length" "12")])
12654 (define_expand "tls_global_dynamic_32"
12656 [(set (match_operand:SI 0 "register_operand" "")
12657 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12658 (match_operand:SI 1 "tls_symbolic_operand" "")
12659 (match_operand:SI 3 "constant_call_address_operand" "")]
12661 (clobber (match_scratch:SI 4 ""))
12662 (clobber (match_scratch:SI 5 ""))
12663 (clobber (reg:CC FLAGS_REG))])])
12665 (define_insn "*tls_global_dynamic_64"
12666 [(set (match_operand:DI 0 "register_operand" "=a")
12668 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12669 (match_operand:DI 3 "" "")))
12670 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12675 fputs (ASM_BYTE "0x66\n", asm_out_file);
12677 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12678 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12679 fputs ("\trex64\n", asm_out_file);
12680 if (TARGET_SUN_TLS)
12681 return "call\t%p2@plt";
12682 return "call\t%P2";
12684 [(set_attr "type" "multi")
12685 (set (attr "length")
12686 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12688 (define_expand "tls_global_dynamic_64"
12690 [(set (match_operand:DI 0 "register_operand" "")
12692 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12694 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12697 (define_insn "*tls_local_dynamic_base_32_gnu"
12698 [(set (match_operand:SI 0 "register_operand" "=a")
12700 [(match_operand:SI 1 "register_operand" "b")
12701 (match_operand:SI 2 "constant_call_address_operand" "z")]
12702 UNSPEC_TLS_LD_BASE))
12703 (clobber (match_scratch:SI 3 "=d"))
12704 (clobber (match_scratch:SI 4 "=c"))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "!TARGET_64BIT && TARGET_GNU_TLS"
12709 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12710 if (TARGET_SUN_TLS)
12711 #ifdef HAVE_AS_IX86_TLSLDMPLT
12712 return "call\t%&@tlsldmplt";
12714 return "call\t%p2@plt";
12716 return "call\t%P2";
12718 [(set_attr "type" "multi")
12719 (set_attr "length" "11")])
12721 (define_expand "tls_local_dynamic_base_32"
12723 [(set (match_operand:SI 0 "register_operand" "")
12725 [(match_operand:SI 1 "register_operand" "")
12726 (match_operand:SI 2 "constant_call_address_operand" "")]
12727 UNSPEC_TLS_LD_BASE))
12728 (clobber (match_scratch:SI 3 ""))
12729 (clobber (match_scratch:SI 4 ""))
12730 (clobber (reg:CC FLAGS_REG))])])
12732 (define_insn "*tls_local_dynamic_base_64"
12733 [(set (match_operand:DI 0 "register_operand" "=a")
12735 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12736 (match_operand:DI 2 "" "")))
12737 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12741 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12742 if (TARGET_SUN_TLS)
12743 return "call\t%p1@plt";
12744 return "call\t%P1";
12746 [(set_attr "type" "multi")
12747 (set_attr "length" "12")])
12749 (define_expand "tls_local_dynamic_base_64"
12751 [(set (match_operand:DI 0 "register_operand" "")
12753 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12755 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12757 ;; Local dynamic of a single variable is a lose. Show combine how
12758 ;; to convert that back to global dynamic.
12760 (define_insn_and_split "*tls_local_dynamic_32_once"
12761 [(set (match_operand:SI 0 "register_operand" "=a")
12763 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12764 (match_operand:SI 2 "constant_call_address_operand" "z")]
12765 UNSPEC_TLS_LD_BASE)
12766 (const:SI (unspec:SI
12767 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12769 (clobber (match_scratch:SI 4 "=d"))
12770 (clobber (match_scratch:SI 5 "=c"))
12771 (clobber (reg:CC FLAGS_REG))]
12776 [(set (match_dup 0)
12777 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12779 (clobber (match_dup 4))
12780 (clobber (match_dup 5))
12781 (clobber (reg:CC FLAGS_REG))])])
12783 ;; Segment register for the thread base ptr load
12784 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12786 ;; Load and add the thread base pointer from %<tp_seg>:0.
12787 (define_insn "*load_tp_x32"
12788 [(set (match_operand:SI 0 "register_operand" "=r")
12789 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12791 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12792 [(set_attr "type" "imov")
12793 (set_attr "modrm" "0")
12794 (set_attr "length" "7")
12795 (set_attr "memory" "load")
12796 (set_attr "imm_disp" "false")])
12798 (define_insn "*load_tp_x32_zext"
12799 [(set (match_operand:DI 0 "register_operand" "=r")
12800 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12802 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12803 [(set_attr "type" "imov")
12804 (set_attr "modrm" "0")
12805 (set_attr "length" "7")
12806 (set_attr "memory" "load")
12807 (set_attr "imm_disp" "false")])
12809 (define_insn "*load_tp_<mode>"
12810 [(set (match_operand:P 0 "register_operand" "=r")
12811 (unspec:P [(const_int 0)] UNSPEC_TP))]
12813 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12814 [(set_attr "type" "imov")
12815 (set_attr "modrm" "0")
12816 (set_attr "length" "7")
12817 (set_attr "memory" "load")
12818 (set_attr "imm_disp" "false")])
12820 (define_insn "*add_tp_x32"
12821 [(set (match_operand:SI 0 "register_operand" "=r")
12822 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12823 (match_operand:SI 1 "register_operand" "0")))
12824 (clobber (reg:CC FLAGS_REG))]
12826 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12827 [(set_attr "type" "alu")
12828 (set_attr "modrm" "0")
12829 (set_attr "length" "7")
12830 (set_attr "memory" "load")
12831 (set_attr "imm_disp" "false")])
12833 (define_insn "*add_tp_x32_zext"
12834 [(set (match_operand:DI 0 "register_operand" "=r")
12836 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12837 (match_operand:SI 1 "register_operand" "0"))))
12838 (clobber (reg:CC FLAGS_REG))]
12840 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12841 [(set_attr "type" "alu")
12842 (set_attr "modrm" "0")
12843 (set_attr "length" "7")
12844 (set_attr "memory" "load")
12845 (set_attr "imm_disp" "false")])
12847 (define_insn "*add_tp_<mode>"
12848 [(set (match_operand:P 0 "register_operand" "=r")
12849 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12850 (match_operand:P 1 "register_operand" "0")))
12851 (clobber (reg:CC FLAGS_REG))]
12853 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12854 [(set_attr "type" "alu")
12855 (set_attr "modrm" "0")
12856 (set_attr "length" "7")
12857 (set_attr "memory" "load")
12858 (set_attr "imm_disp" "false")])
12860 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12861 ;; %rax as destination of the initial executable code sequence.
12862 (define_insn "tls_initial_exec_64_sun"
12863 [(set (match_operand:DI 0 "register_operand" "=a")
12865 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12866 UNSPEC_TLS_IE_SUN))
12867 (clobber (reg:CC FLAGS_REG))]
12868 "TARGET_64BIT && TARGET_SUN_TLS"
12871 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12872 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12874 [(set_attr "type" "multi")])
12876 ;; GNU2 TLS patterns can be split.
12878 (define_expand "tls_dynamic_gnu2_32"
12879 [(set (match_dup 3)
12880 (plus:SI (match_operand:SI 2 "register_operand" "")
12882 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12885 [(set (match_operand:SI 0 "register_operand" "")
12886 (unspec:SI [(match_dup 1) (match_dup 3)
12887 (match_dup 2) (reg:SI SP_REG)]
12889 (clobber (reg:CC FLAGS_REG))])]
12890 "!TARGET_64BIT && TARGET_GNU2_TLS"
12892 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12893 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12896 (define_insn "*tls_dynamic_gnu2_lea_32"
12897 [(set (match_operand:SI 0 "register_operand" "=r")
12898 (plus:SI (match_operand:SI 1 "register_operand" "b")
12900 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12901 UNSPEC_TLSDESC))))]
12902 "!TARGET_64BIT && TARGET_GNU2_TLS"
12903 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12904 [(set_attr "type" "lea")
12905 (set_attr "mode" "SI")
12906 (set_attr "length" "6")
12907 (set_attr "length_address" "4")])
12909 (define_insn "*tls_dynamic_gnu2_call_32"
12910 [(set (match_operand:SI 0 "register_operand" "=a")
12911 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12912 (match_operand:SI 2 "register_operand" "0")
12913 ;; we have to make sure %ebx still points to the GOT
12914 (match_operand:SI 3 "register_operand" "b")
12917 (clobber (reg:CC FLAGS_REG))]
12918 "!TARGET_64BIT && TARGET_GNU2_TLS"
12919 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12920 [(set_attr "type" "call")
12921 (set_attr "length" "2")
12922 (set_attr "length_address" "0")])
12924 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12925 [(set (match_operand:SI 0 "register_operand" "=&a")
12927 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12928 (match_operand:SI 4 "" "")
12929 (match_operand:SI 2 "register_operand" "b")
12932 (const:SI (unspec:SI
12933 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12935 (clobber (reg:CC FLAGS_REG))]
12936 "!TARGET_64BIT && TARGET_GNU2_TLS"
12939 [(set (match_dup 0) (match_dup 5))]
12941 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12942 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12945 (define_expand "tls_dynamic_gnu2_64"
12946 [(set (match_dup 2)
12947 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12950 [(set (match_operand:DI 0 "register_operand" "")
12951 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12953 (clobber (reg:CC FLAGS_REG))])]
12954 "TARGET_64BIT && TARGET_GNU2_TLS"
12956 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12957 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12960 (define_insn "*tls_dynamic_gnu2_lea_64"
12961 [(set (match_operand:DI 0 "register_operand" "=r")
12962 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12964 "TARGET_64BIT && TARGET_GNU2_TLS"
12965 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12966 [(set_attr "type" "lea")
12967 (set_attr "mode" "DI")
12968 (set_attr "length" "7")
12969 (set_attr "length_address" "4")])
12971 (define_insn "*tls_dynamic_gnu2_call_64"
12972 [(set (match_operand:DI 0 "register_operand" "=a")
12973 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12974 (match_operand:DI 2 "register_operand" "0")
12977 (clobber (reg:CC FLAGS_REG))]
12978 "TARGET_64BIT && TARGET_GNU2_TLS"
12979 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12980 [(set_attr "type" "call")
12981 (set_attr "length" "2")
12982 (set_attr "length_address" "0")])
12984 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12985 [(set (match_operand:DI 0 "register_operand" "=&a")
12987 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12988 (match_operand:DI 3 "" "")
12991 (const:DI (unspec:DI
12992 [(match_operand 1 "tls_symbolic_operand" "")]
12994 (clobber (reg:CC FLAGS_REG))]
12995 "TARGET_64BIT && TARGET_GNU2_TLS"
12998 [(set (match_dup 0) (match_dup 4))]
13000 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13001 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13004 ;; These patterns match the binary 387 instructions for addM3, subM3,
13005 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13006 ;; SFmode. The first is the normal insn, the second the same insn but
13007 ;; with one operand a conversion, and the third the same insn but with
13008 ;; the other operand a conversion. The conversion may be SFmode or
13009 ;; SImode if the target mode DFmode, but only SImode if the target mode
13012 ;; Gcc is slightly more smart about handling normal two address instructions
13013 ;; so use special patterns for add and mull.
13015 (define_insn "*fop_<mode>_comm_mixed"
13016 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13017 (match_operator:MODEF 3 "binary_fp_operator"
13018 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13019 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13020 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13021 && COMMUTATIVE_ARITH_P (operands[3])
13022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13023 "* return output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (if_then_else (eq_attr "alternative" "1,2")
13026 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13027 (const_string "ssemul")
13028 (const_string "sseadd"))
13029 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13030 (const_string "fmul")
13031 (const_string "fop"))))
13032 (set_attr "isa" "*,noavx,avx")
13033 (set_attr "prefix" "orig,orig,vex")
13034 (set_attr "mode" "<MODE>")])
13036 (define_insn "*fop_<mode>_comm_sse"
13037 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13038 (match_operator:MODEF 3 "binary_fp_operator"
13039 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13040 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13041 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13042 && COMMUTATIVE_ARITH_P (operands[3])
13043 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13044 "* return output_387_binary_op (insn, operands);"
13045 [(set (attr "type")
13046 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13047 (const_string "ssemul")
13048 (const_string "sseadd")))
13049 (set_attr "isa" "noavx,avx")
13050 (set_attr "prefix" "orig,vex")
13051 (set_attr "mode" "<MODE>")])
13053 (define_insn "*fop_<mode>_comm_i387"
13054 [(set (match_operand:MODEF 0 "register_operand" "=f")
13055 (match_operator:MODEF 3 "binary_fp_operator"
13056 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13057 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13058 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13059 && COMMUTATIVE_ARITH_P (operands[3])
13060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13061 "* return output_387_binary_op (insn, operands);"
13062 [(set (attr "type")
13063 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13064 (const_string "fmul")
13065 (const_string "fop")))
13066 (set_attr "mode" "<MODE>")])
13068 (define_insn "*fop_<mode>_1_mixed"
13069 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13070 (match_operator:MODEF 3 "binary_fp_operator"
13071 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13072 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13074 && !COMMUTATIVE_ARITH_P (operands[3])
13075 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13076 "* return output_387_binary_op (insn, operands);"
13077 [(set (attr "type")
13078 (cond [(and (eq_attr "alternative" "2,3")
13079 (match_operand:MODEF 3 "mult_operator" ""))
13080 (const_string "ssemul")
13081 (and (eq_attr "alternative" "2,3")
13082 (match_operand:MODEF 3 "div_operator" ""))
13083 (const_string "ssediv")
13084 (eq_attr "alternative" "2,3")
13085 (const_string "sseadd")
13086 (match_operand:MODEF 3 "mult_operator" "")
13087 (const_string "fmul")
13088 (match_operand:MODEF 3 "div_operator" "")
13089 (const_string "fdiv")
13091 (const_string "fop")))
13092 (set_attr "isa" "*,*,noavx,avx")
13093 (set_attr "prefix" "orig,orig,orig,vex")
13094 (set_attr "mode" "<MODE>")])
13096 (define_insn "*rcpsf2_sse"
13097 [(set (match_operand:SF 0 "register_operand" "=x")
13098 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13101 "%vrcpss\t{%1, %d0|%d0, %1}"
13102 [(set_attr "type" "sse")
13103 (set_attr "atom_sse_attr" "rcp")
13104 (set_attr "prefix" "maybe_vex")
13105 (set_attr "mode" "SF")])
13107 (define_insn "*fop_<mode>_1_sse"
13108 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13109 (match_operator:MODEF 3 "binary_fp_operator"
13110 [(match_operand:MODEF 1 "register_operand" "0,x")
13111 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13112 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13113 && !COMMUTATIVE_ARITH_P (operands[3])"
13114 "* return output_387_binary_op (insn, operands);"
13115 [(set (attr "type")
13116 (cond [(match_operand:MODEF 3 "mult_operator" "")
13117 (const_string "ssemul")
13118 (match_operand:MODEF 3 "div_operator" "")
13119 (const_string "ssediv")
13121 (const_string "sseadd")))
13122 (set_attr "isa" "noavx,avx")
13123 (set_attr "prefix" "orig,vex")
13124 (set_attr "mode" "<MODE>")])
13126 ;; This pattern is not fully shadowed by the pattern above.
13127 (define_insn "*fop_<mode>_1_i387"
13128 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13129 (match_operator:MODEF 3 "binary_fp_operator"
13130 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13131 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13132 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13133 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13134 && !COMMUTATIVE_ARITH_P (operands[3])
13135 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13136 "* return output_387_binary_op (insn, operands);"
13137 [(set (attr "type")
13138 (cond [(match_operand:MODEF 3 "mult_operator" "")
13139 (const_string "fmul")
13140 (match_operand:MODEF 3 "div_operator" "")
13141 (const_string "fdiv")
13143 (const_string "fop")))
13144 (set_attr "mode" "<MODE>")])
13146 ;; ??? Add SSE splitters for these!
13147 (define_insn "*fop_<MODEF:mode>_2_i387"
13148 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13149 (match_operator:MODEF 3 "binary_fp_operator"
13151 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13152 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13153 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13154 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13155 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13156 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13157 [(set (attr "type")
13158 (cond [(match_operand:MODEF 3 "mult_operator" "")
13159 (const_string "fmul")
13160 (match_operand:MODEF 3 "div_operator" "")
13161 (const_string "fdiv")
13163 (const_string "fop")))
13164 (set_attr "fp_int_src" "true")
13165 (set_attr "mode" "<SWI24:MODE>")])
13167 (define_insn "*fop_<MODEF:mode>_3_i387"
13168 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13169 (match_operator:MODEF 3 "binary_fp_operator"
13170 [(match_operand:MODEF 1 "register_operand" "0,0")
13172 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13173 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13174 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13175 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13176 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13177 [(set (attr "type")
13178 (cond [(match_operand:MODEF 3 "mult_operator" "")
13179 (const_string "fmul")
13180 (match_operand:MODEF 3 "div_operator" "")
13181 (const_string "fdiv")
13183 (const_string "fop")))
13184 (set_attr "fp_int_src" "true")
13185 (set_attr "mode" "<MODE>")])
13187 (define_insn "*fop_df_4_i387"
13188 [(set (match_operand:DF 0 "register_operand" "=f,f")
13189 (match_operator:DF 3 "binary_fp_operator"
13191 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13192 (match_operand:DF 2 "register_operand" "0,f")]))]
13193 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13194 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13195 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13196 "* return output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:DF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (match_operand:DF 3 "div_operator" "")
13201 (const_string "fdiv")
13203 (const_string "fop")))
13204 (set_attr "mode" "SF")])
13206 (define_insn "*fop_df_5_i387"
13207 [(set (match_operand:DF 0 "register_operand" "=f,f")
13208 (match_operator:DF 3 "binary_fp_operator"
13209 [(match_operand:DF 1 "register_operand" "0,f")
13211 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13212 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13213 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13214 "* return output_387_binary_op (insn, operands);"
13215 [(set (attr "type")
13216 (cond [(match_operand:DF 3 "mult_operator" "")
13217 (const_string "fmul")
13218 (match_operand:DF 3 "div_operator" "")
13219 (const_string "fdiv")
13221 (const_string "fop")))
13222 (set_attr "mode" "SF")])
13224 (define_insn "*fop_df_6_i387"
13225 [(set (match_operand:DF 0 "register_operand" "=f,f")
13226 (match_operator:DF 3 "binary_fp_operator"
13228 (match_operand:SF 1 "register_operand" "0,f"))
13230 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13231 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13232 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13233 "* return output_387_binary_op (insn, operands);"
13234 [(set (attr "type")
13235 (cond [(match_operand:DF 3 "mult_operator" "")
13236 (const_string "fmul")
13237 (match_operand:DF 3 "div_operator" "")
13238 (const_string "fdiv")
13240 (const_string "fop")))
13241 (set_attr "mode" "SF")])
13243 (define_insn "*fop_xf_comm_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f")
13245 (match_operator:XF 3 "binary_fp_operator"
13246 [(match_operand:XF 1 "register_operand" "%0")
13247 (match_operand:XF 2 "register_operand" "f")]))]
13249 && COMMUTATIVE_ARITH_P (operands[3])"
13250 "* return output_387_binary_op (insn, operands);"
13251 [(set (attr "type")
13252 (if_then_else (match_operand:XF 3 "mult_operator" "")
13253 (const_string "fmul")
13254 (const_string "fop")))
13255 (set_attr "mode" "XF")])
13257 (define_insn "*fop_xf_1_i387"
13258 [(set (match_operand:XF 0 "register_operand" "=f,f")
13259 (match_operator:XF 3 "binary_fp_operator"
13260 [(match_operand:XF 1 "register_operand" "0,f")
13261 (match_operand:XF 2 "register_operand" "f,0")]))]
13263 && !COMMUTATIVE_ARITH_P (operands[3])"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (cond [(match_operand:XF 3 "mult_operator" "")
13267 (const_string "fmul")
13268 (match_operand:XF 3 "div_operator" "")
13269 (const_string "fdiv")
13271 (const_string "fop")))
13272 (set_attr "mode" "XF")])
13274 (define_insn "*fop_xf_2_i387"
13275 [(set (match_operand:XF 0 "register_operand" "=f,f")
13276 (match_operator:XF 3 "binary_fp_operator"
13278 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13279 (match_operand:XF 2 "register_operand" "0,0")]))]
13280 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13281 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13282 [(set (attr "type")
13283 (cond [(match_operand:XF 3 "mult_operator" "")
13284 (const_string "fmul")
13285 (match_operand:XF 3 "div_operator" "")
13286 (const_string "fdiv")
13288 (const_string "fop")))
13289 (set_attr "fp_int_src" "true")
13290 (set_attr "mode" "<MODE>")])
13292 (define_insn "*fop_xf_3_i387"
13293 [(set (match_operand:XF 0 "register_operand" "=f,f")
13294 (match_operator:XF 3 "binary_fp_operator"
13295 [(match_operand:XF 1 "register_operand" "0,0")
13297 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13298 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13299 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13300 [(set (attr "type")
13301 (cond [(match_operand:XF 3 "mult_operator" "")
13302 (const_string "fmul")
13303 (match_operand:XF 3 "div_operator" "")
13304 (const_string "fdiv")
13306 (const_string "fop")))
13307 (set_attr "fp_int_src" "true")
13308 (set_attr "mode" "<MODE>")])
13310 (define_insn "*fop_xf_4_i387"
13311 [(set (match_operand:XF 0 "register_operand" "=f,f")
13312 (match_operator:XF 3 "binary_fp_operator"
13314 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13315 (match_operand:XF 2 "register_operand" "0,f")]))]
13317 "* return output_387_binary_op (insn, operands);"
13318 [(set (attr "type")
13319 (cond [(match_operand:XF 3 "mult_operator" "")
13320 (const_string "fmul")
13321 (match_operand:XF 3 "div_operator" "")
13322 (const_string "fdiv")
13324 (const_string "fop")))
13325 (set_attr "mode" "<MODE>")])
13327 (define_insn "*fop_xf_5_i387"
13328 [(set (match_operand:XF 0 "register_operand" "=f,f")
13329 (match_operator:XF 3 "binary_fp_operator"
13330 [(match_operand:XF 1 "register_operand" "0,f")
13332 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13334 "* return output_387_binary_op (insn, operands);"
13335 [(set (attr "type")
13336 (cond [(match_operand:XF 3 "mult_operator" "")
13337 (const_string "fmul")
13338 (match_operand:XF 3 "div_operator" "")
13339 (const_string "fdiv")
13341 (const_string "fop")))
13342 (set_attr "mode" "<MODE>")])
13344 (define_insn "*fop_xf_6_i387"
13345 [(set (match_operand:XF 0 "register_operand" "=f,f")
13346 (match_operator:XF 3 "binary_fp_operator"
13348 (match_operand:MODEF 1 "register_operand" "0,f"))
13350 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13352 "* return output_387_binary_op (insn, operands);"
13353 [(set (attr "type")
13354 (cond [(match_operand:XF 3 "mult_operator" "")
13355 (const_string "fmul")
13356 (match_operand:XF 3 "div_operator" "")
13357 (const_string "fdiv")
13359 (const_string "fop")))
13360 (set_attr "mode" "<MODE>")])
13363 [(set (match_operand 0 "register_operand" "")
13364 (match_operator 3 "binary_fp_operator"
13365 [(float (match_operand:SWI24 1 "register_operand" ""))
13366 (match_operand 2 "register_operand" "")]))]
13368 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13369 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13372 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13373 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13374 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13375 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13376 GET_MODE (operands[3]),
13379 ix86_free_from_memory (GET_MODE (operands[1]));
13384 [(set (match_operand 0 "register_operand" "")
13385 (match_operator 3 "binary_fp_operator"
13386 [(match_operand 1 "register_operand" "")
13387 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13389 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13390 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13393 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13394 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13395 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13396 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13397 GET_MODE (operands[3]),
13400 ix86_free_from_memory (GET_MODE (operands[2]));
13404 ;; FPU special functions.
13406 ;; This pattern implements a no-op XFmode truncation for
13407 ;; all fancy i386 XFmode math functions.
13409 (define_insn "truncxf<mode>2_i387_noop_unspec"
13410 [(set (match_operand:MODEF 0 "register_operand" "=f")
13411 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13412 UNSPEC_TRUNC_NOOP))]
13413 "TARGET_USE_FANCY_MATH_387"
13414 "* return output_387_reg_move (insn, operands);"
13415 [(set_attr "type" "fmov")
13416 (set_attr "mode" "<MODE>")])
13418 (define_insn "sqrtxf2"
13419 [(set (match_operand:XF 0 "register_operand" "=f")
13420 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13421 "TARGET_USE_FANCY_MATH_387"
13423 [(set_attr "type" "fpspc")
13424 (set_attr "mode" "XF")
13425 (set_attr "athlon_decode" "direct")
13426 (set_attr "amdfam10_decode" "direct")
13427 (set_attr "bdver1_decode" "direct")])
13429 (define_insn "sqrt_extend<mode>xf2_i387"
13430 [(set (match_operand:XF 0 "register_operand" "=f")
13433 (match_operand:MODEF 1 "register_operand" "0"))))]
13434 "TARGET_USE_FANCY_MATH_387"
13436 [(set_attr "type" "fpspc")
13437 (set_attr "mode" "XF")
13438 (set_attr "athlon_decode" "direct")
13439 (set_attr "amdfam10_decode" "direct")
13440 (set_attr "bdver1_decode" "direct")])
13442 (define_insn "*rsqrtsf2_sse"
13443 [(set (match_operand:SF 0 "register_operand" "=x")
13444 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13447 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13448 [(set_attr "type" "sse")
13449 (set_attr "atom_sse_attr" "rcp")
13450 (set_attr "prefix" "maybe_vex")
13451 (set_attr "mode" "SF")])
13453 (define_expand "rsqrtsf2"
13454 [(set (match_operand:SF 0 "register_operand" "")
13455 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13459 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13463 (define_insn "*sqrt<mode>2_sse"
13464 [(set (match_operand:MODEF 0 "register_operand" "=x")
13466 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13467 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13468 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13469 [(set_attr "type" "sse")
13470 (set_attr "atom_sse_attr" "sqrt")
13471 (set_attr "prefix" "maybe_vex")
13472 (set_attr "mode" "<MODE>")
13473 (set_attr "athlon_decode" "*")
13474 (set_attr "amdfam10_decode" "*")
13475 (set_attr "bdver1_decode" "*")])
13477 (define_expand "sqrt<mode>2"
13478 [(set (match_operand:MODEF 0 "register_operand" "")
13480 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13481 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13482 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13484 if (<MODE>mode == SFmode
13486 && TARGET_RECIP_SQRT
13487 && !optimize_function_for_size_p (cfun)
13488 && flag_finite_math_only && !flag_trapping_math
13489 && flag_unsafe_math_optimizations)
13491 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13495 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13497 rtx op0 = gen_reg_rtx (XFmode);
13498 rtx op1 = force_reg (<MODE>mode, operands[1]);
13500 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13501 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13506 (define_insn "fpremxf4_i387"
13507 [(set (match_operand:XF 0 "register_operand" "=f")
13508 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13509 (match_operand:XF 3 "register_operand" "1")]
13511 (set (match_operand:XF 1 "register_operand" "=u")
13512 (unspec:XF [(match_dup 2) (match_dup 3)]
13514 (set (reg:CCFP FPSR_REG)
13515 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13517 "TARGET_USE_FANCY_MATH_387"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13522 (define_expand "fmodxf3"
13523 [(use (match_operand:XF 0 "register_operand" ""))
13524 (use (match_operand:XF 1 "general_operand" ""))
13525 (use (match_operand:XF 2 "general_operand" ""))]
13526 "TARGET_USE_FANCY_MATH_387"
13528 rtx label = gen_label_rtx ();
13530 rtx op1 = gen_reg_rtx (XFmode);
13531 rtx op2 = gen_reg_rtx (XFmode);
13533 emit_move_insn (op2, operands[2]);
13534 emit_move_insn (op1, operands[1]);
13536 emit_label (label);
13537 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13538 ix86_emit_fp_unordered_jump (label);
13539 LABEL_NUSES (label) = 1;
13541 emit_move_insn (operands[0], op1);
13545 (define_expand "fmod<mode>3"
13546 [(use (match_operand:MODEF 0 "register_operand" ""))
13547 (use (match_operand:MODEF 1 "general_operand" ""))
13548 (use (match_operand:MODEF 2 "general_operand" ""))]
13549 "TARGET_USE_FANCY_MATH_387"
13551 rtx (*gen_truncxf) (rtx, rtx);
13553 rtx label = gen_label_rtx ();
13555 rtx op1 = gen_reg_rtx (XFmode);
13556 rtx op2 = gen_reg_rtx (XFmode);
13558 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13561 emit_label (label);
13562 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13563 ix86_emit_fp_unordered_jump (label);
13564 LABEL_NUSES (label) = 1;
13566 /* Truncate the result properly for strict SSE math. */
13567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13568 && !TARGET_MIX_SSE_I387)
13569 gen_truncxf = gen_truncxf<mode>2;
13571 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13573 emit_insn (gen_truncxf (operands[0], op1));
13577 (define_insn "fprem1xf4_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f")
13579 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13580 (match_operand:XF 3 "register_operand" "1")]
13582 (set (match_operand:XF 1 "register_operand" "=u")
13583 (unspec:XF [(match_dup 2) (match_dup 3)]
13585 (set (reg:CCFP FPSR_REG)
13586 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13588 "TARGET_USE_FANCY_MATH_387"
13590 [(set_attr "type" "fpspc")
13591 (set_attr "mode" "XF")])
13593 (define_expand "remainderxf3"
13594 [(use (match_operand:XF 0 "register_operand" ""))
13595 (use (match_operand:XF 1 "general_operand" ""))
13596 (use (match_operand:XF 2 "general_operand" ""))]
13597 "TARGET_USE_FANCY_MATH_387"
13599 rtx label = gen_label_rtx ();
13601 rtx op1 = gen_reg_rtx (XFmode);
13602 rtx op2 = gen_reg_rtx (XFmode);
13604 emit_move_insn (op2, operands[2]);
13605 emit_move_insn (op1, operands[1]);
13607 emit_label (label);
13608 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13609 ix86_emit_fp_unordered_jump (label);
13610 LABEL_NUSES (label) = 1;
13612 emit_move_insn (operands[0], op1);
13616 (define_expand "remainder<mode>3"
13617 [(use (match_operand:MODEF 0 "register_operand" ""))
13618 (use (match_operand:MODEF 1 "general_operand" ""))
13619 (use (match_operand:MODEF 2 "general_operand" ""))]
13620 "TARGET_USE_FANCY_MATH_387"
13622 rtx (*gen_truncxf) (rtx, rtx);
13624 rtx label = gen_label_rtx ();
13626 rtx op1 = gen_reg_rtx (XFmode);
13627 rtx op2 = gen_reg_rtx (XFmode);
13629 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13630 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13632 emit_label (label);
13634 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13635 ix86_emit_fp_unordered_jump (label);
13636 LABEL_NUSES (label) = 1;
13638 /* Truncate the result properly for strict SSE math. */
13639 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13640 && !TARGET_MIX_SSE_I387)
13641 gen_truncxf = gen_truncxf<mode>2;
13643 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13645 emit_insn (gen_truncxf (operands[0], op1));
13649 (define_insn "*sinxf2_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13652 "TARGET_USE_FANCY_MATH_387
13653 && flag_unsafe_math_optimizations"
13655 [(set_attr "type" "fpspc")
13656 (set_attr "mode" "XF")])
13658 (define_insn "*sin_extend<mode>xf2_i387"
13659 [(set (match_operand:XF 0 "register_operand" "=f")
13660 (unspec:XF [(float_extend:XF
13661 (match_operand:MODEF 1 "register_operand" "0"))]
13663 "TARGET_USE_FANCY_MATH_387
13664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13665 || TARGET_MIX_SSE_I387)
13666 && flag_unsafe_math_optimizations"
13668 [(set_attr "type" "fpspc")
13669 (set_attr "mode" "XF")])
13671 (define_insn "*cosxf2_i387"
13672 [(set (match_operand:XF 0 "register_operand" "=f")
13673 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13674 "TARGET_USE_FANCY_MATH_387
13675 && flag_unsafe_math_optimizations"
13677 [(set_attr "type" "fpspc")
13678 (set_attr "mode" "XF")])
13680 (define_insn "*cos_extend<mode>xf2_i387"
13681 [(set (match_operand:XF 0 "register_operand" "=f")
13682 (unspec:XF [(float_extend:XF
13683 (match_operand:MODEF 1 "register_operand" "0"))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13687 || TARGET_MIX_SSE_I387)
13688 && flag_unsafe_math_optimizations"
13690 [(set_attr "type" "fpspc")
13691 (set_attr "mode" "XF")])
13693 ;; When sincos pattern is defined, sin and cos builtin functions will be
13694 ;; expanded to sincos pattern with one of its outputs left unused.
13695 ;; CSE pass will figure out if two sincos patterns can be combined,
13696 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13697 ;; depending on the unused output.
13699 (define_insn "sincosxf3"
13700 [(set (match_operand:XF 0 "register_operand" "=f")
13701 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13702 UNSPEC_SINCOS_COS))
13703 (set (match_operand:XF 1 "register_operand" "=u")
13704 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13705 "TARGET_USE_FANCY_MATH_387
13706 && flag_unsafe_math_optimizations"
13708 [(set_attr "type" "fpspc")
13709 (set_attr "mode" "XF")])
13712 [(set (match_operand:XF 0 "register_operand" "")
13713 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13714 UNSPEC_SINCOS_COS))
13715 (set (match_operand:XF 1 "register_operand" "")
13716 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13717 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13718 && can_create_pseudo_p ()"
13719 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13722 [(set (match_operand:XF 0 "register_operand" "")
13723 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13724 UNSPEC_SINCOS_COS))
13725 (set (match_operand:XF 1 "register_operand" "")
13726 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13727 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13728 && can_create_pseudo_p ()"
13729 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13731 (define_insn "sincos_extend<mode>xf3_i387"
13732 [(set (match_operand:XF 0 "register_operand" "=f")
13733 (unspec:XF [(float_extend:XF
13734 (match_operand:MODEF 2 "register_operand" "0"))]
13735 UNSPEC_SINCOS_COS))
13736 (set (match_operand:XF 1 "register_operand" "=u")
13737 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13738 "TARGET_USE_FANCY_MATH_387
13739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13740 || TARGET_MIX_SSE_I387)
13741 && flag_unsafe_math_optimizations"
13743 [(set_attr "type" "fpspc")
13744 (set_attr "mode" "XF")])
13747 [(set (match_operand:XF 0 "register_operand" "")
13748 (unspec:XF [(float_extend:XF
13749 (match_operand:MODEF 2 "register_operand" ""))]
13750 UNSPEC_SINCOS_COS))
13751 (set (match_operand:XF 1 "register_operand" "")
13752 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13753 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13754 && can_create_pseudo_p ()"
13755 [(set (match_dup 1)
13756 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13759 [(set (match_operand:XF 0 "register_operand" "")
13760 (unspec:XF [(float_extend:XF
13761 (match_operand:MODEF 2 "register_operand" ""))]
13762 UNSPEC_SINCOS_COS))
13763 (set (match_operand:XF 1 "register_operand" "")
13764 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13765 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13766 && can_create_pseudo_p ()"
13767 [(set (match_dup 0)
13768 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13770 (define_expand "sincos<mode>3"
13771 [(use (match_operand:MODEF 0 "register_operand" ""))
13772 (use (match_operand:MODEF 1 "register_operand" ""))
13773 (use (match_operand:MODEF 2 "register_operand" ""))]
13774 "TARGET_USE_FANCY_MATH_387
13775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13776 || TARGET_MIX_SSE_I387)
13777 && flag_unsafe_math_optimizations"
13779 rtx op0 = gen_reg_rtx (XFmode);
13780 rtx op1 = gen_reg_rtx (XFmode);
13782 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13788 (define_insn "fptanxf4_i387"
13789 [(set (match_operand:XF 0 "register_operand" "=f")
13790 (match_operand:XF 3 "const_double_operand" "F"))
13791 (set (match_operand:XF 1 "register_operand" "=u")
13792 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13794 "TARGET_USE_FANCY_MATH_387
13795 && flag_unsafe_math_optimizations
13796 && standard_80387_constant_p (operands[3]) == 2"
13798 [(set_attr "type" "fpspc")
13799 (set_attr "mode" "XF")])
13801 (define_insn "fptan_extend<mode>xf4_i387"
13802 [(set (match_operand:MODEF 0 "register_operand" "=f")
13803 (match_operand:MODEF 3 "const_double_operand" "F"))
13804 (set (match_operand:XF 1 "register_operand" "=u")
13805 (unspec:XF [(float_extend:XF
13806 (match_operand:MODEF 2 "register_operand" "0"))]
13808 "TARGET_USE_FANCY_MATH_387
13809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810 || TARGET_MIX_SSE_I387)
13811 && flag_unsafe_math_optimizations
13812 && standard_80387_constant_p (operands[3]) == 2"
13814 [(set_attr "type" "fpspc")
13815 (set_attr "mode" "XF")])
13817 (define_expand "tanxf2"
13818 [(use (match_operand:XF 0 "register_operand" ""))
13819 (use (match_operand:XF 1 "register_operand" ""))]
13820 "TARGET_USE_FANCY_MATH_387
13821 && flag_unsafe_math_optimizations"
13823 rtx one = gen_reg_rtx (XFmode);
13824 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13826 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13830 (define_expand "tan<mode>2"
13831 [(use (match_operand:MODEF 0 "register_operand" ""))
13832 (use (match_operand:MODEF 1 "register_operand" ""))]
13833 "TARGET_USE_FANCY_MATH_387
13834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13835 || TARGET_MIX_SSE_I387)
13836 && flag_unsafe_math_optimizations"
13838 rtx op0 = gen_reg_rtx (XFmode);
13840 rtx one = gen_reg_rtx (<MODE>mode);
13841 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13843 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13844 operands[1], op2));
13845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13849 (define_insn "*fpatanxf3_i387"
13850 [(set (match_operand:XF 0 "register_operand" "=f")
13851 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13852 (match_operand:XF 2 "register_operand" "u")]
13854 (clobber (match_scratch:XF 3 "=2"))]
13855 "TARGET_USE_FANCY_MATH_387
13856 && flag_unsafe_math_optimizations"
13858 [(set_attr "type" "fpspc")
13859 (set_attr "mode" "XF")])
13861 (define_insn "fpatan_extend<mode>xf3_i387"
13862 [(set (match_operand:XF 0 "register_operand" "=f")
13863 (unspec:XF [(float_extend:XF
13864 (match_operand:MODEF 1 "register_operand" "0"))
13866 (match_operand:MODEF 2 "register_operand" "u"))]
13868 (clobber (match_scratch:XF 3 "=2"))]
13869 "TARGET_USE_FANCY_MATH_387
13870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13871 || TARGET_MIX_SSE_I387)
13872 && flag_unsafe_math_optimizations"
13874 [(set_attr "type" "fpspc")
13875 (set_attr "mode" "XF")])
13877 (define_expand "atan2xf3"
13878 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13879 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13880 (match_operand:XF 1 "register_operand" "")]
13882 (clobber (match_scratch:XF 3 ""))])]
13883 "TARGET_USE_FANCY_MATH_387
13884 && flag_unsafe_math_optimizations")
13886 (define_expand "atan2<mode>3"
13887 [(use (match_operand:MODEF 0 "register_operand" ""))
13888 (use (match_operand:MODEF 1 "register_operand" ""))
13889 (use (match_operand:MODEF 2 "register_operand" ""))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13895 rtx op0 = gen_reg_rtx (XFmode);
13897 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13898 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13902 (define_expand "atanxf2"
13903 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13904 (unspec:XF [(match_dup 2)
13905 (match_operand:XF 1 "register_operand" "")]
13907 (clobber (match_scratch:XF 3 ""))])]
13908 "TARGET_USE_FANCY_MATH_387
13909 && flag_unsafe_math_optimizations"
13911 operands[2] = gen_reg_rtx (XFmode);
13912 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13915 (define_expand "atan<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand" ""))
13917 (use (match_operand:MODEF 1 "register_operand" ""))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13925 rtx op2 = gen_reg_rtx (<MODE>mode);
13926 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13928 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13933 (define_expand "asinxf2"
13934 [(set (match_dup 2)
13935 (mult:XF (match_operand:XF 1 "register_operand" "")
13937 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13938 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13939 (parallel [(set (match_operand:XF 0 "register_operand" "")
13940 (unspec:XF [(match_dup 5) (match_dup 1)]
13942 (clobber (match_scratch:XF 6 ""))])]
13943 "TARGET_USE_FANCY_MATH_387
13944 && flag_unsafe_math_optimizations"
13948 if (optimize_insn_for_size_p ())
13951 for (i = 2; i < 6; i++)
13952 operands[i] = gen_reg_rtx (XFmode);
13954 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13957 (define_expand "asin<mode>2"
13958 [(use (match_operand:MODEF 0 "register_operand" ""))
13959 (use (match_operand:MODEF 1 "general_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13965 rtx op0 = gen_reg_rtx (XFmode);
13966 rtx op1 = gen_reg_rtx (XFmode);
13968 if (optimize_insn_for_size_p ())
13971 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13972 emit_insn (gen_asinxf2 (op0, op1));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 (define_expand "acosxf2"
13978 [(set (match_dup 2)
13979 (mult:XF (match_operand:XF 1 "register_operand" "")
13981 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13982 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13983 (parallel [(set (match_operand:XF 0 "register_operand" "")
13984 (unspec:XF [(match_dup 1) (match_dup 5)]
13986 (clobber (match_scratch:XF 6 ""))])]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13992 if (optimize_insn_for_size_p ())
13995 for (i = 2; i < 6; i++)
13996 operands[i] = gen_reg_rtx (XFmode);
13998 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14001 (define_expand "acos<mode>2"
14002 [(use (match_operand:MODEF 0 "register_operand" ""))
14003 (use (match_operand:MODEF 1 "general_operand" ""))]
14004 "TARGET_USE_FANCY_MATH_387
14005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14006 || TARGET_MIX_SSE_I387)
14007 && flag_unsafe_math_optimizations"
14009 rtx op0 = gen_reg_rtx (XFmode);
14010 rtx op1 = gen_reg_rtx (XFmode);
14012 if (optimize_insn_for_size_p ())
14015 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14016 emit_insn (gen_acosxf2 (op0, op1));
14017 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14021 (define_insn "fyl2xxf3_i387"
14022 [(set (match_operand:XF 0 "register_operand" "=f")
14023 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14024 (match_operand:XF 2 "register_operand" "u")]
14026 (clobber (match_scratch:XF 3 "=2"))]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14030 [(set_attr "type" "fpspc")
14031 (set_attr "mode" "XF")])
14033 (define_insn "fyl2x_extend<mode>xf3_i387"
14034 [(set (match_operand:XF 0 "register_operand" "=f")
14035 (unspec:XF [(float_extend:XF
14036 (match_operand:MODEF 1 "register_operand" "0"))
14037 (match_operand:XF 2 "register_operand" "u")]
14039 (clobber (match_scratch:XF 3 "=2"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 [(set_attr "type" "fpspc")
14046 (set_attr "mode" "XF")])
14048 (define_expand "logxf2"
14049 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14050 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14051 (match_dup 2)] UNSPEC_FYL2X))
14052 (clobber (match_scratch:XF 3 ""))])]
14053 "TARGET_USE_FANCY_MATH_387
14054 && flag_unsafe_math_optimizations"
14056 operands[2] = gen_reg_rtx (XFmode);
14057 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14060 (define_expand "log<mode>2"
14061 [(use (match_operand:MODEF 0 "register_operand" ""))
14062 (use (match_operand:MODEF 1 "register_operand" ""))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065 || TARGET_MIX_SSE_I387)
14066 && flag_unsafe_math_optimizations"
14068 rtx op0 = gen_reg_rtx (XFmode);
14070 rtx op2 = gen_reg_rtx (XFmode);
14071 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14073 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14074 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14078 (define_expand "log10xf2"
14079 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14080 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14081 (match_dup 2)] UNSPEC_FYL2X))
14082 (clobber (match_scratch:XF 3 ""))])]
14083 "TARGET_USE_FANCY_MATH_387
14084 && flag_unsafe_math_optimizations"
14086 operands[2] = gen_reg_rtx (XFmode);
14087 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14090 (define_expand "log10<mode>2"
14091 [(use (match_operand:MODEF 0 "register_operand" ""))
14092 (use (match_operand:MODEF 1 "register_operand" ""))]
14093 "TARGET_USE_FANCY_MATH_387
14094 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14095 || TARGET_MIX_SSE_I387)
14096 && flag_unsafe_math_optimizations"
14098 rtx op0 = gen_reg_rtx (XFmode);
14100 rtx op2 = gen_reg_rtx (XFmode);
14101 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14103 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108 (define_expand "log2xf2"
14109 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14110 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14111 (match_dup 2)] UNSPEC_FYL2X))
14112 (clobber (match_scratch:XF 3 ""))])]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14116 operands[2] = gen_reg_rtx (XFmode);
14117 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14120 (define_expand "log2<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand" ""))
14122 (use (match_operand:MODEF 1 "register_operand" ""))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14128 rtx op0 = gen_reg_rtx (XFmode);
14130 rtx op2 = gen_reg_rtx (XFmode);
14131 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14133 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14138 (define_insn "fyl2xp1xf3_i387"
14139 [(set (match_operand:XF 0 "register_operand" "=f")
14140 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14141 (match_operand:XF 2 "register_operand" "u")]
14143 (clobber (match_scratch:XF 3 "=2"))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && flag_unsafe_math_optimizations"
14147 [(set_attr "type" "fpspc")
14148 (set_attr "mode" "XF")])
14150 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14151 [(set (match_operand:XF 0 "register_operand" "=f")
14152 (unspec:XF [(float_extend:XF
14153 (match_operand:MODEF 1 "register_operand" "0"))
14154 (match_operand:XF 2 "register_operand" "u")]
14156 (clobber (match_scratch:XF 3 "=2"))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159 || TARGET_MIX_SSE_I387)
14160 && flag_unsafe_math_optimizations"
14162 [(set_attr "type" "fpspc")
14163 (set_attr "mode" "XF")])
14165 (define_expand "log1pxf2"
14166 [(use (match_operand:XF 0 "register_operand" ""))
14167 (use (match_operand:XF 1 "register_operand" ""))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && flag_unsafe_math_optimizations"
14171 if (optimize_insn_for_size_p ())
14174 ix86_emit_i387_log1p (operands[0], operands[1]);
14178 (define_expand "log1p<mode>2"
14179 [(use (match_operand:MODEF 0 "register_operand" ""))
14180 (use (match_operand:MODEF 1 "register_operand" ""))]
14181 "TARGET_USE_FANCY_MATH_387
14182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183 || TARGET_MIX_SSE_I387)
14184 && flag_unsafe_math_optimizations"
14188 if (optimize_insn_for_size_p ())
14191 op0 = gen_reg_rtx (XFmode);
14193 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14195 ix86_emit_i387_log1p (op0, operands[1]);
14196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14200 (define_insn "fxtractxf3_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14203 UNSPEC_XTRACT_FRACT))
14204 (set (match_operand:XF 1 "register_operand" "=u")
14205 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14206 "TARGET_USE_FANCY_MATH_387
14207 && flag_unsafe_math_optimizations"
14209 [(set_attr "type" "fpspc")
14210 (set_attr "mode" "XF")])
14212 (define_insn "fxtract_extend<mode>xf3_i387"
14213 [(set (match_operand:XF 0 "register_operand" "=f")
14214 (unspec:XF [(float_extend:XF
14215 (match_operand:MODEF 2 "register_operand" "0"))]
14216 UNSPEC_XTRACT_FRACT))
14217 (set (match_operand:XF 1 "register_operand" "=u")
14218 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221 || TARGET_MIX_SSE_I387)
14222 && flag_unsafe_math_optimizations"
14224 [(set_attr "type" "fpspc")
14225 (set_attr "mode" "XF")])
14227 (define_expand "logbxf2"
14228 [(parallel [(set (match_dup 2)
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14230 UNSPEC_XTRACT_FRACT))
14231 (set (match_operand:XF 0 "register_operand" "")
14232 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14235 "operands[2] = gen_reg_rtx (XFmode);")
14237 (define_expand "logb<mode>2"
14238 [(use (match_operand:MODEF 0 "register_operand" ""))
14239 (use (match_operand:MODEF 1 "register_operand" ""))]
14240 "TARGET_USE_FANCY_MATH_387
14241 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14242 || TARGET_MIX_SSE_I387)
14243 && flag_unsafe_math_optimizations"
14245 rtx op0 = gen_reg_rtx (XFmode);
14246 rtx op1 = gen_reg_rtx (XFmode);
14248 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14249 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14253 (define_expand "ilogbxf2"
14254 [(use (match_operand:SI 0 "register_operand" ""))
14255 (use (match_operand:XF 1 "register_operand" ""))]
14256 "TARGET_USE_FANCY_MATH_387
14257 && flag_unsafe_math_optimizations"
14261 if (optimize_insn_for_size_p ())
14264 op0 = gen_reg_rtx (XFmode);
14265 op1 = gen_reg_rtx (XFmode);
14267 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14268 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14272 (define_expand "ilogb<mode>2"
14273 [(use (match_operand:SI 0 "register_operand" ""))
14274 (use (match_operand:MODEF 1 "register_operand" ""))]
14275 "TARGET_USE_FANCY_MATH_387
14276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277 || TARGET_MIX_SSE_I387)
14278 && flag_unsafe_math_optimizations"
14282 if (optimize_insn_for_size_p ())
14285 op0 = gen_reg_rtx (XFmode);
14286 op1 = gen_reg_rtx (XFmode);
14288 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14289 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14293 (define_insn "*f2xm1xf2_i387"
14294 [(set (match_operand:XF 0 "register_operand" "=f")
14295 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14300 [(set_attr "type" "fpspc")
14301 (set_attr "mode" "XF")])
14303 (define_insn "*fscalexf4_i387"
14304 [(set (match_operand:XF 0 "register_operand" "=f")
14305 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14306 (match_operand:XF 3 "register_operand" "1")]
14307 UNSPEC_FSCALE_FRACT))
14308 (set (match_operand:XF 1 "register_operand" "=u")
14309 (unspec:XF [(match_dup 2) (match_dup 3)]
14310 UNSPEC_FSCALE_EXP))]
14311 "TARGET_USE_FANCY_MATH_387
14312 && flag_unsafe_math_optimizations"
14314 [(set_attr "type" "fpspc")
14315 (set_attr "mode" "XF")])
14317 (define_expand "expNcorexf3"
14318 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14319 (match_operand:XF 2 "register_operand" "")))
14320 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14321 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14322 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14323 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14324 (parallel [(set (match_operand:XF 0 "register_operand" "")
14325 (unspec:XF [(match_dup 8) (match_dup 4)]
14326 UNSPEC_FSCALE_FRACT))
14328 (unspec:XF [(match_dup 8) (match_dup 4)]
14329 UNSPEC_FSCALE_EXP))])]
14330 "TARGET_USE_FANCY_MATH_387
14331 && flag_unsafe_math_optimizations"
14335 if (optimize_insn_for_size_p ())
14338 for (i = 3; i < 10; i++)
14339 operands[i] = gen_reg_rtx (XFmode);
14341 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14344 (define_expand "expxf2"
14345 [(use (match_operand:XF 0 "register_operand" ""))
14346 (use (match_operand:XF 1 "register_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && flag_unsafe_math_optimizations"
14352 if (optimize_insn_for_size_p ())
14355 op2 = gen_reg_rtx (XFmode);
14356 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14358 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14362 (define_expand "exp<mode>2"
14363 [(use (match_operand:MODEF 0 "register_operand" ""))
14364 (use (match_operand:MODEF 1 "general_operand" ""))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14367 || TARGET_MIX_SSE_I387)
14368 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 op0 = gen_reg_rtx (XFmode);
14376 op1 = gen_reg_rtx (XFmode);
14378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14379 emit_insn (gen_expxf2 (op0, op1));
14380 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14384 (define_expand "exp10xf2"
14385 [(use (match_operand:XF 0 "register_operand" ""))
14386 (use (match_operand:XF 1 "register_operand" ""))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && flag_unsafe_math_optimizations"
14392 if (optimize_insn_for_size_p ())
14395 op2 = gen_reg_rtx (XFmode);
14396 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14398 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14402 (define_expand "exp10<mode>2"
14403 [(use (match_operand:MODEF 0 "register_operand" ""))
14404 (use (match_operand:MODEF 1 "general_operand" ""))]
14405 "TARGET_USE_FANCY_MATH_387
14406 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14407 || TARGET_MIX_SSE_I387)
14408 && flag_unsafe_math_optimizations"
14412 if (optimize_insn_for_size_p ())
14415 op0 = gen_reg_rtx (XFmode);
14416 op1 = gen_reg_rtx (XFmode);
14418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14419 emit_insn (gen_exp10xf2 (op0, op1));
14420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14424 (define_expand "exp2xf2"
14425 [(use (match_operand:XF 0 "register_operand" ""))
14426 (use (match_operand:XF 1 "register_operand" ""))]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14432 if (optimize_insn_for_size_p ())
14435 op2 = gen_reg_rtx (XFmode);
14436 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14438 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14442 (define_expand "exp2<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand" ""))
14444 (use (match_operand:MODEF 1 "general_operand" ""))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14452 if (optimize_insn_for_size_p ())
14455 op0 = gen_reg_rtx (XFmode);
14456 op1 = gen_reg_rtx (XFmode);
14458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14459 emit_insn (gen_exp2xf2 (op0, op1));
14460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14464 (define_expand "expm1xf2"
14465 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14467 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14468 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14469 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14470 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14471 (parallel [(set (match_dup 7)
14472 (unspec:XF [(match_dup 6) (match_dup 4)]
14473 UNSPEC_FSCALE_FRACT))
14475 (unspec:XF [(match_dup 6) (match_dup 4)]
14476 UNSPEC_FSCALE_EXP))])
14477 (parallel [(set (match_dup 10)
14478 (unspec:XF [(match_dup 9) (match_dup 8)]
14479 UNSPEC_FSCALE_FRACT))
14480 (set (match_dup 11)
14481 (unspec:XF [(match_dup 9) (match_dup 8)]
14482 UNSPEC_FSCALE_EXP))])
14483 (set (match_dup 12) (minus:XF (match_dup 10)
14484 (float_extend:XF (match_dup 13))))
14485 (set (match_operand:XF 0 "register_operand" "")
14486 (plus:XF (match_dup 12) (match_dup 7)))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && flag_unsafe_math_optimizations"
14492 if (optimize_insn_for_size_p ())
14495 for (i = 2; i < 13; i++)
14496 operands[i] = gen_reg_rtx (XFmode);
14499 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14501 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14504 (define_expand "expm1<mode>2"
14505 [(use (match_operand:MODEF 0 "register_operand" ""))
14506 (use (match_operand:MODEF 1 "general_operand" ""))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14514 if (optimize_insn_for_size_p ())
14517 op0 = gen_reg_rtx (XFmode);
14518 op1 = gen_reg_rtx (XFmode);
14520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14521 emit_insn (gen_expm1xf2 (op0, op1));
14522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14526 (define_expand "ldexpxf3"
14527 [(set (match_dup 3)
14528 (float:XF (match_operand:SI 2 "register_operand" "")))
14529 (parallel [(set (match_operand:XF 0 " register_operand" "")
14530 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14532 UNSPEC_FSCALE_FRACT))
14534 (unspec:XF [(match_dup 1) (match_dup 3)]
14535 UNSPEC_FSCALE_EXP))])]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations"
14539 if (optimize_insn_for_size_p ())
14542 operands[3] = gen_reg_rtx (XFmode);
14543 operands[4] = gen_reg_rtx (XFmode);
14546 (define_expand "ldexp<mode>3"
14547 [(use (match_operand:MODEF 0 "register_operand" ""))
14548 (use (match_operand:MODEF 1 "general_operand" ""))
14549 (use (match_operand:SI 2 "register_operand" ""))]
14550 "TARGET_USE_FANCY_MATH_387
14551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14552 || TARGET_MIX_SSE_I387)
14553 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 op0 = gen_reg_rtx (XFmode);
14561 op1 = gen_reg_rtx (XFmode);
14563 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14564 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14565 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14569 (define_expand "scalbxf3"
14570 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14571 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14572 (match_operand:XF 2 "register_operand" "")]
14573 UNSPEC_FSCALE_FRACT))
14575 (unspec:XF [(match_dup 1) (match_dup 2)]
14576 UNSPEC_FSCALE_EXP))])]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14580 if (optimize_insn_for_size_p ())
14583 operands[3] = gen_reg_rtx (XFmode);
14586 (define_expand "scalb<mode>3"
14587 [(use (match_operand:MODEF 0 "register_operand" ""))
14588 (use (match_operand:MODEF 1 "general_operand" ""))
14589 (use (match_operand:MODEF 2 "general_operand" ""))]
14590 "TARGET_USE_FANCY_MATH_387
14591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592 || TARGET_MIX_SSE_I387)
14593 && flag_unsafe_math_optimizations"
14597 if (optimize_insn_for_size_p ())
14600 op0 = gen_reg_rtx (XFmode);
14601 op1 = gen_reg_rtx (XFmode);
14602 op2 = gen_reg_rtx (XFmode);
14604 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14605 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14606 emit_insn (gen_scalbxf3 (op0, op1, op2));
14607 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14611 (define_expand "significandxf2"
14612 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14613 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14614 UNSPEC_XTRACT_FRACT))
14616 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations"
14619 "operands[2] = gen_reg_rtx (XFmode);")
14621 (define_expand "significand<mode>2"
14622 [(use (match_operand:MODEF 0 "register_operand" ""))
14623 (use (match_operand:MODEF 1 "register_operand" ""))]
14624 "TARGET_USE_FANCY_MATH_387
14625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14626 || TARGET_MIX_SSE_I387)
14627 && flag_unsafe_math_optimizations"
14629 rtx op0 = gen_reg_rtx (XFmode);
14630 rtx op1 = gen_reg_rtx (XFmode);
14632 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14633 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14638 (define_insn "sse4_1_round<mode>2"
14639 [(set (match_operand:MODEF 0 "register_operand" "=x")
14640 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14641 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14644 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14645 [(set_attr "type" "ssecvt")
14646 (set_attr "prefix_extra" "1")
14647 (set_attr "prefix" "maybe_vex")
14648 (set_attr "mode" "<MODE>")])
14650 (define_insn "rintxf2"
14651 [(set (match_operand:XF 0 "register_operand" "=f")
14652 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14654 "TARGET_USE_FANCY_MATH_387
14655 && flag_unsafe_math_optimizations"
14657 [(set_attr "type" "fpspc")
14658 (set_attr "mode" "XF")])
14660 (define_expand "rint<mode>2"
14661 [(use (match_operand:MODEF 0 "register_operand" ""))
14662 (use (match_operand:MODEF 1 "register_operand" ""))]
14663 "(TARGET_USE_FANCY_MATH_387
14664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14665 || TARGET_MIX_SSE_I387)
14666 && flag_unsafe_math_optimizations)
14667 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14668 && !flag_trapping_math)"
14670 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14671 && !flag_trapping_math)
14674 emit_insn (gen_sse4_1_round<mode>2
14675 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14676 else if (optimize_insn_for_size_p ())
14679 ix86_expand_rint (operands[0], operands[1]);
14683 rtx op0 = gen_reg_rtx (XFmode);
14684 rtx op1 = gen_reg_rtx (XFmode);
14686 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14687 emit_insn (gen_rintxf2 (op0, op1));
14689 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14694 (define_expand "round<mode>2"
14695 [(match_operand:X87MODEF 0 "register_operand" "")
14696 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14697 "(TARGET_USE_FANCY_MATH_387
14698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699 || TARGET_MIX_SSE_I387)
14700 && flag_unsafe_math_optimizations)
14701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14702 && !flag_trapping_math && !flag_rounding_math)"
14704 if (optimize_insn_for_size_p ())
14707 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14708 && !flag_trapping_math && !flag_rounding_math)
14712 operands[1] = force_reg (<MODE>mode, operands[1]);
14713 ix86_expand_round_sse4 (operands[0], operands[1]);
14715 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14716 ix86_expand_round (operands[0], operands[1]);
14718 ix86_expand_rounddf_32 (operands[0], operands[1]);
14722 operands[1] = force_reg (<MODE>mode, operands[1]);
14723 ix86_emit_i387_round (operands[0], operands[1]);
14728 (define_insn_and_split "*fistdi2_1"
14729 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14732 "TARGET_USE_FANCY_MATH_387
14733 && can_create_pseudo_p ()"
14738 if (memory_operand (operands[0], VOIDmode))
14739 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14742 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14743 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14748 [(set_attr "type" "fpspc")
14749 (set_attr "mode" "DI")])
14751 (define_insn "fistdi2"
14752 [(set (match_operand:DI 0 "memory_operand" "=m")
14753 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14755 (clobber (match_scratch:XF 2 "=&1f"))]
14756 "TARGET_USE_FANCY_MATH_387"
14757 "* return output_fix_trunc (insn, operands, false);"
14758 [(set_attr "type" "fpspc")
14759 (set_attr "mode" "DI")])
14761 (define_insn "fistdi2_with_temp"
14762 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14763 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14765 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14766 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14767 "TARGET_USE_FANCY_MATH_387"
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "DI")])
14773 [(set (match_operand:DI 0 "register_operand" "")
14774 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14776 (clobber (match_operand:DI 2 "memory_operand" ""))
14777 (clobber (match_scratch 3 ""))]
14779 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14780 (clobber (match_dup 3))])
14781 (set (match_dup 0) (match_dup 2))])
14784 [(set (match_operand:DI 0 "memory_operand" "")
14785 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14787 (clobber (match_operand:DI 2 "memory_operand" ""))
14788 (clobber (match_scratch 3 ""))]
14790 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14791 (clobber (match_dup 3))])])
14793 (define_insn_and_split "*fist<mode>2_1"
14794 [(set (match_operand:SWI24 0 "register_operand" "")
14795 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14797 "TARGET_USE_FANCY_MATH_387
14798 && can_create_pseudo_p ()"
14803 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14804 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14808 [(set_attr "type" "fpspc")
14809 (set_attr "mode" "<MODE>")])
14811 (define_insn "fist<mode>2"
14812 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14813 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14815 "TARGET_USE_FANCY_MATH_387"
14816 "* return output_fix_trunc (insn, operands, false);"
14817 [(set_attr "type" "fpspc")
14818 (set_attr "mode" "<MODE>")])
14820 (define_insn "fist<mode>2_with_temp"
14821 [(set (match_operand:SWI24 0 "register_operand" "=r")
14822 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14824 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14825 "TARGET_USE_FANCY_MATH_387"
14827 [(set_attr "type" "fpspc")
14828 (set_attr "mode" "<MODE>")])
14831 [(set (match_operand:SWI24 0 "register_operand" "")
14832 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14834 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14836 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14837 (set (match_dup 0) (match_dup 2))])
14840 [(set (match_operand:SWI24 0 "memory_operand" "")
14841 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14843 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14845 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14847 (define_expand "lrintxf<mode>2"
14848 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14849 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14851 "TARGET_USE_FANCY_MATH_387")
14853 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14854 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14855 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14856 UNSPEC_FIX_NOTRUNC))]
14857 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14858 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14860 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14861 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14862 (match_operand:X87MODEF 1 "register_operand" "")]
14863 "(TARGET_USE_FANCY_MATH_387
14864 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14865 || TARGET_MIX_SSE_I387)
14866 && flag_unsafe_math_optimizations)
14867 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14868 && <SWI248x:MODE>mode != HImode
14869 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14870 && !flag_trapping_math && !flag_rounding_math)"
14872 if (optimize_insn_for_size_p ())
14875 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14876 && <SWI248x:MODE>mode != HImode
14877 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14878 && !flag_trapping_math && !flag_rounding_math)
14879 ix86_expand_lround (operands[0], operands[1]);
14881 ix86_emit_i387_round (operands[0], operands[1]);
14885 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14886 (define_insn_and_split "frndintxf2_floor"
14887 [(set (match_operand:XF 0 "register_operand" "")
14888 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14889 UNSPEC_FRNDINT_FLOOR))
14890 (clobber (reg:CC FLAGS_REG))]
14891 "TARGET_USE_FANCY_MATH_387
14892 && flag_unsafe_math_optimizations
14893 && can_create_pseudo_p ()"
14898 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14900 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14901 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14903 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14904 operands[2], operands[3]));
14907 [(set_attr "type" "frndint")
14908 (set_attr "i387_cw" "floor")
14909 (set_attr "mode" "XF")])
14911 (define_insn "frndintxf2_floor_i387"
14912 [(set (match_operand:XF 0 "register_operand" "=f")
14913 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14914 UNSPEC_FRNDINT_FLOOR))
14915 (use (match_operand:HI 2 "memory_operand" "m"))
14916 (use (match_operand:HI 3 "memory_operand" "m"))]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14919 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14920 [(set_attr "type" "frndint")
14921 (set_attr "i387_cw" "floor")
14922 (set_attr "mode" "XF")])
14924 (define_expand "floorxf2"
14925 [(use (match_operand:XF 0 "register_operand" ""))
14926 (use (match_operand:XF 1 "register_operand" ""))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations"
14930 if (optimize_insn_for_size_p ())
14932 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14936 (define_expand "floor<mode>2"
14937 [(use (match_operand:MODEF 0 "register_operand" ""))
14938 (use (match_operand:MODEF 1 "register_operand" ""))]
14939 "(TARGET_USE_FANCY_MATH_387
14940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14941 || TARGET_MIX_SSE_I387)
14942 && flag_unsafe_math_optimizations)
14943 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14944 && !flag_trapping_math)"
14946 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14947 && !flag_trapping_math)
14950 emit_insn (gen_sse4_1_round<mode>2
14951 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14952 else if (optimize_insn_for_size_p ())
14954 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14955 ix86_expand_floorceil (operands[0], operands[1], true);
14957 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14963 if (optimize_insn_for_size_p ())
14966 op0 = gen_reg_rtx (XFmode);
14967 op1 = gen_reg_rtx (XFmode);
14968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14969 emit_insn (gen_frndintxf2_floor (op0, op1));
14971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14976 (define_insn_and_split "*fist<mode>2_floor_1"
14977 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14978 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14979 UNSPEC_FIST_FLOOR))
14980 (clobber (reg:CC FLAGS_REG))]
14981 "TARGET_USE_FANCY_MATH_387
14982 && flag_unsafe_math_optimizations
14983 && can_create_pseudo_p ()"
14988 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14990 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14991 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14992 if (memory_operand (operands[0], VOIDmode))
14993 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14994 operands[2], operands[3]));
14997 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14998 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14999 operands[2], operands[3],
15004 [(set_attr "type" "fistp")
15005 (set_attr "i387_cw" "floor")
15006 (set_attr "mode" "<MODE>")])
15008 (define_insn "fistdi2_floor"
15009 [(set (match_operand:DI 0 "memory_operand" "=m")
15010 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15011 UNSPEC_FIST_FLOOR))
15012 (use (match_operand:HI 2 "memory_operand" "m"))
15013 (use (match_operand:HI 3 "memory_operand" "m"))
15014 (clobber (match_scratch:XF 4 "=&1f"))]
15015 "TARGET_USE_FANCY_MATH_387
15016 && flag_unsafe_math_optimizations"
15017 "* return output_fix_trunc (insn, operands, false);"
15018 [(set_attr "type" "fistp")
15019 (set_attr "i387_cw" "floor")
15020 (set_attr "mode" "DI")])
15022 (define_insn "fistdi2_floor_with_temp"
15023 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15024 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15025 UNSPEC_FIST_FLOOR))
15026 (use (match_operand:HI 2 "memory_operand" "m,m"))
15027 (use (match_operand:HI 3 "memory_operand" "m,m"))
15028 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15029 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15030 "TARGET_USE_FANCY_MATH_387
15031 && flag_unsafe_math_optimizations"
15033 [(set_attr "type" "fistp")
15034 (set_attr "i387_cw" "floor")
15035 (set_attr "mode" "DI")])
15038 [(set (match_operand:DI 0 "register_operand" "")
15039 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15040 UNSPEC_FIST_FLOOR))
15041 (use (match_operand:HI 2 "memory_operand" ""))
15042 (use (match_operand:HI 3 "memory_operand" ""))
15043 (clobber (match_operand:DI 4 "memory_operand" ""))
15044 (clobber (match_scratch 5 ""))]
15046 [(parallel [(set (match_dup 4)
15047 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15048 (use (match_dup 2))
15049 (use (match_dup 3))
15050 (clobber (match_dup 5))])
15051 (set (match_dup 0) (match_dup 4))])
15054 [(set (match_operand:DI 0 "memory_operand" "")
15055 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15056 UNSPEC_FIST_FLOOR))
15057 (use (match_operand:HI 2 "memory_operand" ""))
15058 (use (match_operand:HI 3 "memory_operand" ""))
15059 (clobber (match_operand:DI 4 "memory_operand" ""))
15060 (clobber (match_scratch 5 ""))]
15062 [(parallel [(set (match_dup 0)
15063 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15064 (use (match_dup 2))
15065 (use (match_dup 3))
15066 (clobber (match_dup 5))])])
15068 (define_insn "fist<mode>2_floor"
15069 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15070 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15071 UNSPEC_FIST_FLOOR))
15072 (use (match_operand:HI 2 "memory_operand" "m"))
15073 (use (match_operand:HI 3 "memory_operand" "m"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_unsafe_math_optimizations"
15076 "* return output_fix_trunc (insn, operands, false);"
15077 [(set_attr "type" "fistp")
15078 (set_attr "i387_cw" "floor")
15079 (set_attr "mode" "<MODE>")])
15081 (define_insn "fist<mode>2_floor_with_temp"
15082 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15083 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15084 UNSPEC_FIST_FLOOR))
15085 (use (match_operand:HI 2 "memory_operand" "m,m"))
15086 (use (match_operand:HI 3 "memory_operand" "m,m"))
15087 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15088 "TARGET_USE_FANCY_MATH_387
15089 && flag_unsafe_math_optimizations"
15091 [(set_attr "type" "fistp")
15092 (set_attr "i387_cw" "floor")
15093 (set_attr "mode" "<MODE>")])
15096 [(set (match_operand:SWI24 0 "register_operand" "")
15097 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15098 UNSPEC_FIST_FLOOR))
15099 (use (match_operand:HI 2 "memory_operand" ""))
15100 (use (match_operand:HI 3 "memory_operand" ""))
15101 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15103 [(parallel [(set (match_dup 4)
15104 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15105 (use (match_dup 2))
15106 (use (match_dup 3))])
15107 (set (match_dup 0) (match_dup 4))])
15110 [(set (match_operand:SWI24 0 "memory_operand" "")
15111 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15112 UNSPEC_FIST_FLOOR))
15113 (use (match_operand:HI 2 "memory_operand" ""))
15114 (use (match_operand:HI 3 "memory_operand" ""))
15115 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15117 [(parallel [(set (match_dup 0)
15118 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15119 (use (match_dup 2))
15120 (use (match_dup 3))])])
15122 (define_expand "lfloorxf<mode>2"
15123 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15124 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15125 UNSPEC_FIST_FLOOR))
15126 (clobber (reg:CC FLAGS_REG))])]
15127 "TARGET_USE_FANCY_MATH_387
15128 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15129 && flag_unsafe_math_optimizations")
15131 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15132 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15133 (match_operand:MODEF 1 "register_operand" "")]
15134 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15135 && !flag_trapping_math"
15137 if (TARGET_64BIT && optimize_insn_for_size_p ())
15139 ix86_expand_lfloorceil (operands[0], operands[1], true);
15143 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15144 (define_insn_and_split "frndintxf2_ceil"
15145 [(set (match_operand:XF 0 "register_operand" "")
15146 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15147 UNSPEC_FRNDINT_CEIL))
15148 (clobber (reg:CC FLAGS_REG))]
15149 "TARGET_USE_FANCY_MATH_387
15150 && flag_unsafe_math_optimizations
15151 && can_create_pseudo_p ()"
15156 ix86_optimize_mode_switching[I387_CEIL] = 1;
15158 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15159 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15161 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15162 operands[2], operands[3]));
15165 [(set_attr "type" "frndint")
15166 (set_attr "i387_cw" "ceil")
15167 (set_attr "mode" "XF")])
15169 (define_insn "frndintxf2_ceil_i387"
15170 [(set (match_operand:XF 0 "register_operand" "=f")
15171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15172 UNSPEC_FRNDINT_CEIL))
15173 (use (match_operand:HI 2 "memory_operand" "m"))
15174 (use (match_operand:HI 3 "memory_operand" "m"))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations"
15177 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15178 [(set_attr "type" "frndint")
15179 (set_attr "i387_cw" "ceil")
15180 (set_attr "mode" "XF")])
15182 (define_expand "ceilxf2"
15183 [(use (match_operand:XF 0 "register_operand" ""))
15184 (use (match_operand:XF 1 "register_operand" ""))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && flag_unsafe_math_optimizations"
15188 if (optimize_insn_for_size_p ())
15190 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15194 (define_expand "ceil<mode>2"
15195 [(use (match_operand:MODEF 0 "register_operand" ""))
15196 (use (match_operand:MODEF 1 "register_operand" ""))]
15197 "(TARGET_USE_FANCY_MATH_387
15198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199 || TARGET_MIX_SSE_I387)
15200 && flag_unsafe_math_optimizations)
15201 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15202 && !flag_trapping_math)"
15204 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15205 && !flag_trapping_math)
15208 emit_insn (gen_sse4_1_round<mode>2
15209 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15210 else if (optimize_insn_for_size_p ())
15212 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15213 ix86_expand_floorceil (operands[0], operands[1], false);
15215 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15221 if (optimize_insn_for_size_p ())
15224 op0 = gen_reg_rtx (XFmode);
15225 op1 = gen_reg_rtx (XFmode);
15226 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15227 emit_insn (gen_frndintxf2_ceil (op0, op1));
15229 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15234 (define_insn_and_split "*fist<mode>2_ceil_1"
15235 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15236 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15238 (clobber (reg:CC FLAGS_REG))]
15239 "TARGET_USE_FANCY_MATH_387
15240 && flag_unsafe_math_optimizations
15241 && can_create_pseudo_p ()"
15246 ix86_optimize_mode_switching[I387_CEIL] = 1;
15248 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15249 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15250 if (memory_operand (operands[0], VOIDmode))
15251 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15252 operands[2], operands[3]));
15255 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15256 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15257 operands[2], operands[3],
15262 [(set_attr "type" "fistp")
15263 (set_attr "i387_cw" "ceil")
15264 (set_attr "mode" "<MODE>")])
15266 (define_insn "fistdi2_ceil"
15267 [(set (match_operand:DI 0 "memory_operand" "=m")
15268 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15270 (use (match_operand:HI 2 "memory_operand" "m"))
15271 (use (match_operand:HI 3 "memory_operand" "m"))
15272 (clobber (match_scratch:XF 4 "=&1f"))]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations"
15275 "* return output_fix_trunc (insn, operands, false);"
15276 [(set_attr "type" "fistp")
15277 (set_attr "i387_cw" "ceil")
15278 (set_attr "mode" "DI")])
15280 (define_insn "fistdi2_ceil_with_temp"
15281 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15282 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15284 (use (match_operand:HI 2 "memory_operand" "m,m"))
15285 (use (match_operand:HI 3 "memory_operand" "m,m"))
15286 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15287 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && flag_unsafe_math_optimizations"
15291 [(set_attr "type" "fistp")
15292 (set_attr "i387_cw" "ceil")
15293 (set_attr "mode" "DI")])
15296 [(set (match_operand:DI 0 "register_operand" "")
15297 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15299 (use (match_operand:HI 2 "memory_operand" ""))
15300 (use (match_operand:HI 3 "memory_operand" ""))
15301 (clobber (match_operand:DI 4 "memory_operand" ""))
15302 (clobber (match_scratch 5 ""))]
15304 [(parallel [(set (match_dup 4)
15305 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15306 (use (match_dup 2))
15307 (use (match_dup 3))
15308 (clobber (match_dup 5))])
15309 (set (match_dup 0) (match_dup 4))])
15312 [(set (match_operand:DI 0 "memory_operand" "")
15313 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15315 (use (match_operand:HI 2 "memory_operand" ""))
15316 (use (match_operand:HI 3 "memory_operand" ""))
15317 (clobber (match_operand:DI 4 "memory_operand" ""))
15318 (clobber (match_scratch 5 ""))]
15320 [(parallel [(set (match_dup 0)
15321 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15322 (use (match_dup 2))
15323 (use (match_dup 3))
15324 (clobber (match_dup 5))])])
15326 (define_insn "fist<mode>2_ceil"
15327 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15328 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15330 (use (match_operand:HI 2 "memory_operand" "m"))
15331 (use (match_operand:HI 3 "memory_operand" "m"))]
15332 "TARGET_USE_FANCY_MATH_387
15333 && flag_unsafe_math_optimizations"
15334 "* return output_fix_trunc (insn, operands, false);"
15335 [(set_attr "type" "fistp")
15336 (set_attr "i387_cw" "ceil")
15337 (set_attr "mode" "<MODE>")])
15339 (define_insn "fist<mode>2_ceil_with_temp"
15340 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15341 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15343 (use (match_operand:HI 2 "memory_operand" "m,m"))
15344 (use (match_operand:HI 3 "memory_operand" "m,m"))
15345 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15346 "TARGET_USE_FANCY_MATH_387
15347 && flag_unsafe_math_optimizations"
15349 [(set_attr "type" "fistp")
15350 (set_attr "i387_cw" "ceil")
15351 (set_attr "mode" "<MODE>")])
15354 [(set (match_operand:SWI24 0 "register_operand" "")
15355 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15357 (use (match_operand:HI 2 "memory_operand" ""))
15358 (use (match_operand:HI 3 "memory_operand" ""))
15359 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15361 [(parallel [(set (match_dup 4)
15362 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15363 (use (match_dup 2))
15364 (use (match_dup 3))])
15365 (set (match_dup 0) (match_dup 4))])
15368 [(set (match_operand:SWI24 0 "memory_operand" "")
15369 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15371 (use (match_operand:HI 2 "memory_operand" ""))
15372 (use (match_operand:HI 3 "memory_operand" ""))
15373 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15375 [(parallel [(set (match_dup 0)
15376 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15377 (use (match_dup 2))
15378 (use (match_dup 3))])])
15380 (define_expand "lceilxf<mode>2"
15381 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15382 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15384 (clobber (reg:CC FLAGS_REG))])]
15385 "TARGET_USE_FANCY_MATH_387
15386 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15387 && flag_unsafe_math_optimizations")
15389 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15390 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15391 (match_operand:MODEF 1 "register_operand" "")]
15392 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15393 && !flag_trapping_math"
15395 ix86_expand_lfloorceil (operands[0], operands[1], false);
15399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15400 (define_insn_and_split "frndintxf2_trunc"
15401 [(set (match_operand:XF 0 "register_operand" "")
15402 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15403 UNSPEC_FRNDINT_TRUNC))
15404 (clobber (reg:CC FLAGS_REG))]
15405 "TARGET_USE_FANCY_MATH_387
15406 && flag_unsafe_math_optimizations
15407 && can_create_pseudo_p ()"
15412 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15414 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15415 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15417 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15418 operands[2], operands[3]));
15421 [(set_attr "type" "frndint")
15422 (set_attr "i387_cw" "trunc")
15423 (set_attr "mode" "XF")])
15425 (define_insn "frndintxf2_trunc_i387"
15426 [(set (match_operand:XF 0 "register_operand" "=f")
15427 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15428 UNSPEC_FRNDINT_TRUNC))
15429 (use (match_operand:HI 2 "memory_operand" "m"))
15430 (use (match_operand:HI 3 "memory_operand" "m"))]
15431 "TARGET_USE_FANCY_MATH_387
15432 && flag_unsafe_math_optimizations"
15433 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15434 [(set_attr "type" "frndint")
15435 (set_attr "i387_cw" "trunc")
15436 (set_attr "mode" "XF")])
15438 (define_expand "btruncxf2"
15439 [(use (match_operand:XF 0 "register_operand" ""))
15440 (use (match_operand:XF 1 "register_operand" ""))]
15441 "TARGET_USE_FANCY_MATH_387
15442 && flag_unsafe_math_optimizations"
15444 if (optimize_insn_for_size_p ())
15446 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15450 (define_expand "btrunc<mode>2"
15451 [(use (match_operand:MODEF 0 "register_operand" ""))
15452 (use (match_operand:MODEF 1 "register_operand" ""))]
15453 "(TARGET_USE_FANCY_MATH_387
15454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15455 || TARGET_MIX_SSE_I387)
15456 && flag_unsafe_math_optimizations)
15457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15458 && !flag_trapping_math)"
15460 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15461 && !flag_trapping_math)
15464 emit_insn (gen_sse4_1_round<mode>2
15465 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15466 else if (optimize_insn_for_size_p ())
15468 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15469 ix86_expand_trunc (operands[0], operands[1]);
15471 ix86_expand_truncdf_32 (operands[0], operands[1]);
15477 if (optimize_insn_for_size_p ())
15480 op0 = gen_reg_rtx (XFmode);
15481 op1 = gen_reg_rtx (XFmode);
15482 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15483 emit_insn (gen_frndintxf2_trunc (op0, op1));
15485 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15491 (define_insn_and_split "frndintxf2_mask_pm"
15492 [(set (match_operand:XF 0 "register_operand" "")
15493 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15494 UNSPEC_FRNDINT_MASK_PM))
15495 (clobber (reg:CC FLAGS_REG))]
15496 "TARGET_USE_FANCY_MATH_387
15497 && flag_unsafe_math_optimizations
15498 && can_create_pseudo_p ()"
15503 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15505 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15506 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15508 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15509 operands[2], operands[3]));
15512 [(set_attr "type" "frndint")
15513 (set_attr "i387_cw" "mask_pm")
15514 (set_attr "mode" "XF")])
15516 (define_insn "frndintxf2_mask_pm_i387"
15517 [(set (match_operand:XF 0 "register_operand" "=f")
15518 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15519 UNSPEC_FRNDINT_MASK_PM))
15520 (use (match_operand:HI 2 "memory_operand" "m"))
15521 (use (match_operand:HI 3 "memory_operand" "m"))]
15522 "TARGET_USE_FANCY_MATH_387
15523 && flag_unsafe_math_optimizations"
15524 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15525 [(set_attr "type" "frndint")
15526 (set_attr "i387_cw" "mask_pm")
15527 (set_attr "mode" "XF")])
15529 (define_expand "nearbyintxf2"
15530 [(use (match_operand:XF 0 "register_operand" ""))
15531 (use (match_operand:XF 1 "register_operand" ""))]
15532 "TARGET_USE_FANCY_MATH_387
15533 && flag_unsafe_math_optimizations"
15535 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15539 (define_expand "nearbyint<mode>2"
15540 [(use (match_operand:MODEF 0 "register_operand" ""))
15541 (use (match_operand:MODEF 1 "register_operand" ""))]
15542 "TARGET_USE_FANCY_MATH_387
15543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15544 || TARGET_MIX_SSE_I387)
15545 && flag_unsafe_math_optimizations"
15547 rtx op0 = gen_reg_rtx (XFmode);
15548 rtx op1 = gen_reg_rtx (XFmode);
15550 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15551 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15557 (define_insn "fxam<mode>2_i387"
15558 [(set (match_operand:HI 0 "register_operand" "=a")
15560 [(match_operand:X87MODEF 1 "register_operand" "f")]
15562 "TARGET_USE_FANCY_MATH_387"
15563 "fxam\n\tfnstsw\t%0"
15564 [(set_attr "type" "multi")
15565 (set_attr "length" "4")
15566 (set_attr "unit" "i387")
15567 (set_attr "mode" "<MODE>")])
15569 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15570 [(set (match_operand:HI 0 "register_operand" "")
15572 [(match_operand:MODEF 1 "memory_operand" "")]
15574 "TARGET_USE_FANCY_MATH_387
15575 && can_create_pseudo_p ()"
15578 [(set (match_dup 2)(match_dup 1))
15580 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15582 operands[2] = gen_reg_rtx (<MODE>mode);
15584 MEM_VOLATILE_P (operands[1]) = 1;
15586 [(set_attr "type" "multi")
15587 (set_attr "unit" "i387")
15588 (set_attr "mode" "<MODE>")])
15590 (define_expand "isinfxf2"
15591 [(use (match_operand:SI 0 "register_operand" ""))
15592 (use (match_operand:XF 1 "register_operand" ""))]
15593 "TARGET_USE_FANCY_MATH_387
15594 && TARGET_C99_FUNCTIONS"
15596 rtx mask = GEN_INT (0x45);
15597 rtx val = GEN_INT (0x05);
15601 rtx scratch = gen_reg_rtx (HImode);
15602 rtx res = gen_reg_rtx (QImode);
15604 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15606 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15607 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15608 cond = gen_rtx_fmt_ee (EQ, QImode,
15609 gen_rtx_REG (CCmode, FLAGS_REG),
15611 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15612 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15616 (define_expand "isinf<mode>2"
15617 [(use (match_operand:SI 0 "register_operand" ""))
15618 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15619 "TARGET_USE_FANCY_MATH_387
15620 && TARGET_C99_FUNCTIONS
15621 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15623 rtx mask = GEN_INT (0x45);
15624 rtx val = GEN_INT (0x05);
15628 rtx scratch = gen_reg_rtx (HImode);
15629 rtx res = gen_reg_rtx (QImode);
15631 /* Remove excess precision by forcing value through memory. */
15632 if (memory_operand (operands[1], VOIDmode))
15633 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15636 enum ix86_stack_slot slot = (virtuals_instantiated
15639 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15641 emit_move_insn (temp, operands[1]);
15642 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15645 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15646 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15647 cond = gen_rtx_fmt_ee (EQ, QImode,
15648 gen_rtx_REG (CCmode, FLAGS_REG),
15650 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15651 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15655 (define_expand "signbitxf2"
15656 [(use (match_operand:SI 0 "register_operand" ""))
15657 (use (match_operand:XF 1 "register_operand" ""))]
15658 "TARGET_USE_FANCY_MATH_387"
15660 rtx scratch = gen_reg_rtx (HImode);
15662 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15663 emit_insn (gen_andsi3 (operands[0],
15664 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15668 (define_insn "movmsk_df"
15669 [(set (match_operand:SI 0 "register_operand" "=r")
15671 [(match_operand:DF 1 "register_operand" "x")]
15673 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15674 "%vmovmskpd\t{%1, %0|%0, %1}"
15675 [(set_attr "type" "ssemov")
15676 (set_attr "prefix" "maybe_vex")
15677 (set_attr "mode" "DF")])
15679 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15680 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15681 (define_expand "signbitdf2"
15682 [(use (match_operand:SI 0 "register_operand" ""))
15683 (use (match_operand:DF 1 "register_operand" ""))]
15684 "TARGET_USE_FANCY_MATH_387
15685 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15687 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15689 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15690 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15694 rtx scratch = gen_reg_rtx (HImode);
15696 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15697 emit_insn (gen_andsi3 (operands[0],
15698 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15703 (define_expand "signbitsf2"
15704 [(use (match_operand:SI 0 "register_operand" ""))
15705 (use (match_operand:SF 1 "register_operand" ""))]
15706 "TARGET_USE_FANCY_MATH_387
15707 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15709 rtx scratch = gen_reg_rtx (HImode);
15711 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15712 emit_insn (gen_andsi3 (operands[0],
15713 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15717 ;; Block operation instructions
15720 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15723 [(set_attr "length" "1")
15724 (set_attr "length_immediate" "0")
15725 (set_attr "modrm" "0")])
15727 (define_expand "movmem<mode>"
15728 [(use (match_operand:BLK 0 "memory_operand" ""))
15729 (use (match_operand:BLK 1 "memory_operand" ""))
15730 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15731 (use (match_operand:SWI48 3 "const_int_operand" ""))
15732 (use (match_operand:SI 4 "const_int_operand" ""))
15733 (use (match_operand:SI 5 "const_int_operand" ""))]
15736 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15737 operands[4], operands[5]))
15743 ;; Most CPUs don't like single string operations
15744 ;; Handle this case here to simplify previous expander.
15746 (define_expand "strmov"
15747 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15748 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15749 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15750 (clobber (reg:CC FLAGS_REG))])
15751 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15752 (clobber (reg:CC FLAGS_REG))])]
15755 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15757 /* If .md ever supports :P for Pmode, these can be directly
15758 in the pattern above. */
15759 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15760 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15762 /* Can't use this if the user has appropriated esi or edi. */
15763 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15764 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15766 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15767 operands[2], operands[3],
15768 operands[5], operands[6]));
15772 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15775 (define_expand "strmov_singleop"
15776 [(parallel [(set (match_operand 1 "memory_operand" "")
15777 (match_operand 3 "memory_operand" ""))
15778 (set (match_operand 0 "register_operand" "")
15779 (match_operand 4 "" ""))
15780 (set (match_operand 2 "register_operand" "")
15781 (match_operand 5 "" ""))])]
15783 "ix86_current_function_needs_cld = 1;")
15785 (define_insn "*strmovdi_rex_1"
15786 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15787 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15788 (set (match_operand:DI 0 "register_operand" "=D")
15789 (plus:DI (match_dup 2)
15791 (set (match_operand:DI 1 "register_operand" "=S")
15792 (plus:DI (match_dup 3)
15795 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15797 [(set_attr "type" "str")
15798 (set_attr "memory" "both")
15799 (set_attr "mode" "DI")])
15801 (define_insn "*strmovsi_1"
15802 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15803 (mem:SI (match_operand:P 3 "register_operand" "1")))
15804 (set (match_operand:P 0 "register_operand" "=D")
15805 (plus:P (match_dup 2)
15807 (set (match_operand:P 1 "register_operand" "=S")
15808 (plus:P (match_dup 3)
15810 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 [(set_attr "type" "str")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "SI")])
15816 (define_insn "*strmovhi_1"
15817 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15818 (mem:HI (match_operand:P 3 "register_operand" "1")))
15819 (set (match_operand:P 0 "register_operand" "=D")
15820 (plus:P (match_dup 2)
15822 (set (match_operand:P 1 "register_operand" "=S")
15823 (plus:P (match_dup 3)
15825 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15827 [(set_attr "type" "str")
15828 (set_attr "memory" "both")
15829 (set_attr "mode" "HI")])
15831 (define_insn "*strmovqi_1"
15832 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15833 (mem:QI (match_operand:P 3 "register_operand" "1")))
15834 (set (match_operand:P 0 "register_operand" "=D")
15835 (plus:P (match_dup 2)
15837 (set (match_operand:P 1 "register_operand" "=S")
15838 (plus:P (match_dup 3)
15840 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15842 [(set_attr "type" "str")
15843 (set_attr "memory" "both")
15844 (set (attr "prefix_rex")
15846 (match_test "<P:MODE>mode == DImode")
15848 (const_string "*")))
15849 (set_attr "mode" "QI")])
15851 (define_expand "rep_mov"
15852 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15853 (set (match_operand 0 "register_operand" "")
15854 (match_operand 5 "" ""))
15855 (set (match_operand 2 "register_operand" "")
15856 (match_operand 6 "" ""))
15857 (set (match_operand 1 "memory_operand" "")
15858 (match_operand 3 "memory_operand" ""))
15859 (use (match_dup 4))])]
15861 "ix86_current_function_needs_cld = 1;")
15863 (define_insn "*rep_movdi_rex64"
15864 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15865 (set (match_operand:DI 0 "register_operand" "=D")
15866 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15868 (match_operand:DI 3 "register_operand" "0")))
15869 (set (match_operand:DI 1 "register_operand" "=S")
15870 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15871 (match_operand:DI 4 "register_operand" "1")))
15872 (set (mem:BLK (match_dup 3))
15873 (mem:BLK (match_dup 4)))
15874 (use (match_dup 5))]
15876 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15878 [(set_attr "type" "str")
15879 (set_attr "prefix_rep" "1")
15880 (set_attr "memory" "both")
15881 (set_attr "mode" "DI")])
15883 (define_insn "*rep_movsi"
15884 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15885 (set (match_operand:P 0 "register_operand" "=D")
15886 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15888 (match_operand:P 3 "register_operand" "0")))
15889 (set (match_operand:P 1 "register_operand" "=S")
15890 (plus:P (ashift:P (match_dup 5) (const_int 2))
15891 (match_operand:P 4 "register_operand" "1")))
15892 (set (mem:BLK (match_dup 3))
15893 (mem:BLK (match_dup 4)))
15894 (use (match_dup 5))]
15895 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15896 "rep{%;} movs{l|d}"
15897 [(set_attr "type" "str")
15898 (set_attr "prefix_rep" "1")
15899 (set_attr "memory" "both")
15900 (set_attr "mode" "SI")])
15902 (define_insn "*rep_movqi"
15903 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15904 (set (match_operand:P 0 "register_operand" "=D")
15905 (plus:P (match_operand:P 3 "register_operand" "0")
15906 (match_operand:P 5 "register_operand" "2")))
15907 (set (match_operand:P 1 "register_operand" "=S")
15908 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15909 (set (mem:BLK (match_dup 3))
15910 (mem:BLK (match_dup 4)))
15911 (use (match_dup 5))]
15912 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15914 [(set_attr "type" "str")
15915 (set_attr "prefix_rep" "1")
15916 (set_attr "memory" "both")
15917 (set_attr "mode" "QI")])
15919 (define_expand "setmem<mode>"
15920 [(use (match_operand:BLK 0 "memory_operand" ""))
15921 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15922 (use (match_operand:QI 2 "nonmemory_operand" ""))
15923 (use (match_operand 3 "const_int_operand" ""))
15924 (use (match_operand:SI 4 "const_int_operand" ""))
15925 (use (match_operand:SI 5 "const_int_operand" ""))]
15928 if (ix86_expand_setmem (operands[0], operands[1],
15929 operands[2], operands[3],
15930 operands[4], operands[5]))
15936 ;; Most CPUs don't like single string operations
15937 ;; Handle this case here to simplify previous expander.
15939 (define_expand "strset"
15940 [(set (match_operand 1 "memory_operand" "")
15941 (match_operand 2 "register_operand" ""))
15942 (parallel [(set (match_operand 0 "register_operand" "")
15944 (clobber (reg:CC FLAGS_REG))])]
15947 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15948 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15950 /* If .md ever supports :P for Pmode, this can be directly
15951 in the pattern above. */
15952 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15953 GEN_INT (GET_MODE_SIZE (GET_MODE
15955 /* Can't use this if the user has appropriated eax or edi. */
15956 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15957 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15959 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15965 (define_expand "strset_singleop"
15966 [(parallel [(set (match_operand 1 "memory_operand" "")
15967 (match_operand 2 "register_operand" ""))
15968 (set (match_operand 0 "register_operand" "")
15969 (match_operand 3 "" ""))])]
15971 "ix86_current_function_needs_cld = 1;")
15973 (define_insn "*strsetdi_rex_1"
15974 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15975 (match_operand:DI 2 "register_operand" "a"))
15976 (set (match_operand:DI 0 "register_operand" "=D")
15977 (plus:DI (match_dup 1)
15980 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15982 [(set_attr "type" "str")
15983 (set_attr "memory" "store")
15984 (set_attr "mode" "DI")])
15986 (define_insn "*strsetsi_1"
15987 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15988 (match_operand:SI 2 "register_operand" "a"))
15989 (set (match_operand:P 0 "register_operand" "=D")
15990 (plus:P (match_dup 1)
15992 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15994 [(set_attr "type" "str")
15995 (set_attr "memory" "store")
15996 (set_attr "mode" "SI")])
15998 (define_insn "*strsethi_1"
15999 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16000 (match_operand:HI 2 "register_operand" "a"))
16001 (set (match_operand:P 0 "register_operand" "=D")
16002 (plus:P (match_dup 1)
16004 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16006 [(set_attr "type" "str")
16007 (set_attr "memory" "store")
16008 (set_attr "mode" "HI")])
16010 (define_insn "*strsetqi_1"
16011 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16012 (match_operand:QI 2 "register_operand" "a"))
16013 (set (match_operand:P 0 "register_operand" "=D")
16014 (plus:P (match_dup 1)
16016 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16018 [(set_attr "type" "str")
16019 (set_attr "memory" "store")
16020 (set (attr "prefix_rex")
16022 (match_test "<P:MODE>mode == DImode")
16024 (const_string "*")))
16025 (set_attr "mode" "QI")])
16027 (define_expand "rep_stos"
16028 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16029 (set (match_operand 0 "register_operand" "")
16030 (match_operand 4 "" ""))
16031 (set (match_operand 2 "memory_operand" "") (const_int 0))
16032 (use (match_operand 3 "register_operand" ""))
16033 (use (match_dup 1))])]
16035 "ix86_current_function_needs_cld = 1;")
16037 (define_insn "*rep_stosdi_rex64"
16038 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16039 (set (match_operand:DI 0 "register_operand" "=D")
16040 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16042 (match_operand:DI 3 "register_operand" "0")))
16043 (set (mem:BLK (match_dup 3))
16045 (use (match_operand:DI 2 "register_operand" "a"))
16046 (use (match_dup 4))]
16048 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16050 [(set_attr "type" "str")
16051 (set_attr "prefix_rep" "1")
16052 (set_attr "memory" "store")
16053 (set_attr "mode" "DI")])
16055 (define_insn "*rep_stossi"
16056 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16057 (set (match_operand:P 0 "register_operand" "=D")
16058 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16060 (match_operand:P 3 "register_operand" "0")))
16061 (set (mem:BLK (match_dup 3))
16063 (use (match_operand:SI 2 "register_operand" "a"))
16064 (use (match_dup 4))]
16065 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16066 "rep{%;} stos{l|d}"
16067 [(set_attr "type" "str")
16068 (set_attr "prefix_rep" "1")
16069 (set_attr "memory" "store")
16070 (set_attr "mode" "SI")])
16072 (define_insn "*rep_stosqi"
16073 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16074 (set (match_operand:P 0 "register_operand" "=D")
16075 (plus:P (match_operand:P 3 "register_operand" "0")
16076 (match_operand:P 4 "register_operand" "1")))
16077 (set (mem:BLK (match_dup 3))
16079 (use (match_operand:QI 2 "register_operand" "a"))
16080 (use (match_dup 4))]
16081 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16083 [(set_attr "type" "str")
16084 (set_attr "prefix_rep" "1")
16085 (set_attr "memory" "store")
16086 (set (attr "prefix_rex")
16088 (match_test "<P:MODE>mode == DImode")
16090 (const_string "*")))
16091 (set_attr "mode" "QI")])
16093 (define_expand "cmpstrnsi"
16094 [(set (match_operand:SI 0 "register_operand" "")
16095 (compare:SI (match_operand:BLK 1 "general_operand" "")
16096 (match_operand:BLK 2 "general_operand" "")))
16097 (use (match_operand 3 "general_operand" ""))
16098 (use (match_operand 4 "immediate_operand" ""))]
16101 rtx addr1, addr2, out, outlow, count, countreg, align;
16103 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16106 /* Can't use this if the user has appropriated ecx, esi or edi. */
16107 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16112 out = gen_reg_rtx (SImode);
16114 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16115 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16116 if (addr1 != XEXP (operands[1], 0))
16117 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16118 if (addr2 != XEXP (operands[2], 0))
16119 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16121 count = operands[3];
16122 countreg = ix86_zero_extend_to_Pmode (count);
16124 /* %%% Iff we are testing strict equality, we can use known alignment
16125 to good advantage. This may be possible with combine, particularly
16126 once cc0 is dead. */
16127 align = operands[4];
16129 if (CONST_INT_P (count))
16131 if (INTVAL (count) == 0)
16133 emit_move_insn (operands[0], const0_rtx);
16136 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16137 operands[1], operands[2]));
16141 rtx (*gen_cmp) (rtx, rtx);
16143 gen_cmp = (TARGET_64BIT
16144 ? gen_cmpdi_1 : gen_cmpsi_1);
16146 emit_insn (gen_cmp (countreg, countreg));
16147 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16148 operands[1], operands[2]));
16151 outlow = gen_lowpart (QImode, out);
16152 emit_insn (gen_cmpintqi (outlow));
16153 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16155 if (operands[0] != out)
16156 emit_move_insn (operands[0], out);
16161 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16163 (define_expand "cmpintqi"
16164 [(set (match_dup 1)
16165 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16167 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16168 (parallel [(set (match_operand:QI 0 "register_operand" "")
16169 (minus:QI (match_dup 1)
16171 (clobber (reg:CC FLAGS_REG))])]
16174 operands[1] = gen_reg_rtx (QImode);
16175 operands[2] = gen_reg_rtx (QImode);
16178 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16179 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16181 (define_expand "cmpstrnqi_nz_1"
16182 [(parallel [(set (reg:CC FLAGS_REG)
16183 (compare:CC (match_operand 4 "memory_operand" "")
16184 (match_operand 5 "memory_operand" "")))
16185 (use (match_operand 2 "register_operand" ""))
16186 (use (match_operand:SI 3 "immediate_operand" ""))
16187 (clobber (match_operand 0 "register_operand" ""))
16188 (clobber (match_operand 1 "register_operand" ""))
16189 (clobber (match_dup 2))])]
16191 "ix86_current_function_needs_cld = 1;")
16193 (define_insn "*cmpstrnqi_nz_1"
16194 [(set (reg:CC FLAGS_REG)
16195 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16196 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16197 (use (match_operand:P 6 "register_operand" "2"))
16198 (use (match_operand:SI 3 "immediate_operand" "i"))
16199 (clobber (match_operand:P 0 "register_operand" "=S"))
16200 (clobber (match_operand:P 1 "register_operand" "=D"))
16201 (clobber (match_operand:P 2 "register_operand" "=c"))]
16202 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16204 [(set_attr "type" "str")
16205 (set_attr "mode" "QI")
16206 (set (attr "prefix_rex")
16208 (match_test "<P:MODE>mode == DImode")
16210 (const_string "*")))
16211 (set_attr "prefix_rep" "1")])
16213 ;; The same, but the count is not known to not be zero.
16215 (define_expand "cmpstrnqi_1"
16216 [(parallel [(set (reg:CC FLAGS_REG)
16217 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16219 (compare:CC (match_operand 4 "memory_operand" "")
16220 (match_operand 5 "memory_operand" ""))
16222 (use (match_operand:SI 3 "immediate_operand" ""))
16223 (use (reg:CC FLAGS_REG))
16224 (clobber (match_operand 0 "register_operand" ""))
16225 (clobber (match_operand 1 "register_operand" ""))
16226 (clobber (match_dup 2))])]
16228 "ix86_current_function_needs_cld = 1;")
16230 (define_insn "*cmpstrnqi_1"
16231 [(set (reg:CC FLAGS_REG)
16232 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16234 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16235 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16237 (use (match_operand:SI 3 "immediate_operand" "i"))
16238 (use (reg:CC FLAGS_REG))
16239 (clobber (match_operand:P 0 "register_operand" "=S"))
16240 (clobber (match_operand:P 1 "register_operand" "=D"))
16241 (clobber (match_operand:P 2 "register_operand" "=c"))]
16242 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16244 [(set_attr "type" "str")
16245 (set_attr "mode" "QI")
16246 (set (attr "prefix_rex")
16248 (match_test "<P:MODE>mode == DImode")
16250 (const_string "*")))
16251 (set_attr "prefix_rep" "1")])
16253 (define_expand "strlen<mode>"
16254 [(set (match_operand:P 0 "register_operand" "")
16255 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16256 (match_operand:QI 2 "immediate_operand" "")
16257 (match_operand 3 "immediate_operand" "")]
16261 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16267 (define_expand "strlenqi_1"
16268 [(parallel [(set (match_operand 0 "register_operand" "")
16269 (match_operand 2 "" ""))
16270 (clobber (match_operand 1 "register_operand" ""))
16271 (clobber (reg:CC FLAGS_REG))])]
16273 "ix86_current_function_needs_cld = 1;")
16275 (define_insn "*strlenqi_1"
16276 [(set (match_operand:P 0 "register_operand" "=&c")
16277 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16278 (match_operand:QI 2 "register_operand" "a")
16279 (match_operand:P 3 "immediate_operand" "i")
16280 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16281 (clobber (match_operand:P 1 "register_operand" "=D"))
16282 (clobber (reg:CC FLAGS_REG))]
16283 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16285 [(set_attr "type" "str")
16286 (set_attr "mode" "QI")
16287 (set (attr "prefix_rex")
16289 (match_test "<P:MODE>mode == DImode")
16291 (const_string "*")))
16292 (set_attr "prefix_rep" "1")])
16294 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16295 ;; handled in combine, but it is not currently up to the task.
16296 ;; When used for their truth value, the cmpstrn* expanders generate
16305 ;; The intermediate three instructions are unnecessary.
16307 ;; This one handles cmpstrn*_nz_1...
16310 (set (reg:CC FLAGS_REG)
16311 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16312 (mem:BLK (match_operand 5 "register_operand" ""))))
16313 (use (match_operand 6 "register_operand" ""))
16314 (use (match_operand:SI 3 "immediate_operand" ""))
16315 (clobber (match_operand 0 "register_operand" ""))
16316 (clobber (match_operand 1 "register_operand" ""))
16317 (clobber (match_operand 2 "register_operand" ""))])
16318 (set (match_operand:QI 7 "register_operand" "")
16319 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16320 (set (match_operand:QI 8 "register_operand" "")
16321 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16322 (set (reg FLAGS_REG)
16323 (compare (match_dup 7) (match_dup 8)))
16325 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16327 (set (reg:CC FLAGS_REG)
16328 (compare:CC (mem:BLK (match_dup 4))
16329 (mem:BLK (match_dup 5))))
16330 (use (match_dup 6))
16331 (use (match_dup 3))
16332 (clobber (match_dup 0))
16333 (clobber (match_dup 1))
16334 (clobber (match_dup 2))])])
16336 ;; ...and this one handles cmpstrn*_1.
16339 (set (reg:CC FLAGS_REG)
16340 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16342 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16343 (mem:BLK (match_operand 5 "register_operand" "")))
16345 (use (match_operand:SI 3 "immediate_operand" ""))
16346 (use (reg:CC FLAGS_REG))
16347 (clobber (match_operand 0 "register_operand" ""))
16348 (clobber (match_operand 1 "register_operand" ""))
16349 (clobber (match_operand 2 "register_operand" ""))])
16350 (set (match_operand:QI 7 "register_operand" "")
16351 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16352 (set (match_operand:QI 8 "register_operand" "")
16353 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16354 (set (reg FLAGS_REG)
16355 (compare (match_dup 7) (match_dup 8)))
16357 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16359 (set (reg:CC FLAGS_REG)
16360 (if_then_else:CC (ne (match_dup 6)
16362 (compare:CC (mem:BLK (match_dup 4))
16363 (mem:BLK (match_dup 5)))
16365 (use (match_dup 3))
16366 (use (reg:CC FLAGS_REG))
16367 (clobber (match_dup 0))
16368 (clobber (match_dup 1))
16369 (clobber (match_dup 2))])])
16371 ;; Conditional move instructions.
16373 (define_expand "mov<mode>cc"
16374 [(set (match_operand:SWIM 0 "register_operand" "")
16375 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16376 (match_operand:SWIM 2 "<general_operand>" "")
16377 (match_operand:SWIM 3 "<general_operand>" "")))]
16379 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16381 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16382 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16383 ;; So just document what we're doing explicitly.
16385 (define_expand "x86_mov<mode>cc_0_m1"
16387 [(set (match_operand:SWI48 0 "register_operand" "")
16388 (if_then_else:SWI48
16389 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16390 [(match_operand 1 "flags_reg_operand" "")
16394 (clobber (reg:CC FLAGS_REG))])])
16396 (define_insn "*x86_mov<mode>cc_0_m1"
16397 [(set (match_operand:SWI48 0 "register_operand" "=r")
16398 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16399 [(reg FLAGS_REG) (const_int 0)])
16402 (clobber (reg:CC FLAGS_REG))]
16404 "sbb{<imodesuffix>}\t%0, %0"
16405 ; Since we don't have the proper number of operands for an alu insn,
16406 ; fill in all the blanks.
16407 [(set_attr "type" "alu")
16408 (set_attr "use_carry" "1")
16409 (set_attr "pent_pair" "pu")
16410 (set_attr "memory" "none")
16411 (set_attr "imm_disp" "false")
16412 (set_attr "mode" "<MODE>")
16413 (set_attr "length_immediate" "0")])
16415 (define_insn "*x86_mov<mode>cc_0_m1_se"
16416 [(set (match_operand:SWI48 0 "register_operand" "=r")
16417 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16421 (clobber (reg:CC FLAGS_REG))]
16423 "sbb{<imodesuffix>}\t%0, %0"
16424 [(set_attr "type" "alu")
16425 (set_attr "use_carry" "1")
16426 (set_attr "pent_pair" "pu")
16427 (set_attr "memory" "none")
16428 (set_attr "imm_disp" "false")
16429 (set_attr "mode" "<MODE>")
16430 (set_attr "length_immediate" "0")])
16432 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16433 [(set (match_operand:SWI48 0 "register_operand" "=r")
16434 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16435 [(reg FLAGS_REG) (const_int 0)])))]
16437 "sbb{<imodesuffix>}\t%0, %0"
16438 [(set_attr "type" "alu")
16439 (set_attr "use_carry" "1")
16440 (set_attr "pent_pair" "pu")
16441 (set_attr "memory" "none")
16442 (set_attr "imm_disp" "false")
16443 (set_attr "mode" "<MODE>")
16444 (set_attr "length_immediate" "0")])
16446 (define_insn "*mov<mode>cc_noc"
16447 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16448 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16451 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16452 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16454 cmov%O2%C1\t{%2, %0|%0, %2}
16455 cmov%O2%c1\t{%3, %0|%0, %3}"
16456 [(set_attr "type" "icmov")
16457 (set_attr "mode" "<MODE>")])
16459 (define_insn_and_split "*movqicc_noc"
16460 [(set (match_operand:QI 0 "register_operand" "=r,r")
16461 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16462 [(match_operand 4 "flags_reg_operand" "")
16464 (match_operand:QI 2 "register_operand" "r,0")
16465 (match_operand:QI 3 "register_operand" "0,r")))]
16466 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16468 "&& reload_completed"
16469 [(set (match_dup 0)
16470 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16473 "operands[0] = gen_lowpart (SImode, operands[0]);
16474 operands[2] = gen_lowpart (SImode, operands[2]);
16475 operands[3] = gen_lowpart (SImode, operands[3]);"
16476 [(set_attr "type" "icmov")
16477 (set_attr "mode" "SI")])
16479 (define_expand "mov<mode>cc"
16480 [(set (match_operand:X87MODEF 0 "register_operand" "")
16481 (if_then_else:X87MODEF
16482 (match_operand 1 "ix86_fp_comparison_operator" "")
16483 (match_operand:X87MODEF 2 "register_operand" "")
16484 (match_operand:X87MODEF 3 "register_operand" "")))]
16485 "(TARGET_80387 && TARGET_CMOVE)
16486 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16487 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16489 (define_insn "*movxfcc_1"
16490 [(set (match_operand:XF 0 "register_operand" "=f,f")
16491 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16492 [(reg FLAGS_REG) (const_int 0)])
16493 (match_operand:XF 2 "register_operand" "f,0")
16494 (match_operand:XF 3 "register_operand" "0,f")))]
16495 "TARGET_80387 && TARGET_CMOVE"
16497 fcmov%F1\t{%2, %0|%0, %2}
16498 fcmov%f1\t{%3, %0|%0, %3}"
16499 [(set_attr "type" "fcmov")
16500 (set_attr "mode" "XF")])
16502 (define_insn "*movdfcc_1_rex64"
16503 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16504 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16505 [(reg FLAGS_REG) (const_int 0)])
16506 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16507 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16508 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16509 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16511 fcmov%F1\t{%2, %0|%0, %2}
16512 fcmov%f1\t{%3, %0|%0, %3}
16513 cmov%O2%C1\t{%2, %0|%0, %2}
16514 cmov%O2%c1\t{%3, %0|%0, %3}"
16515 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16516 (set_attr "mode" "DF,DF,DI,DI")])
16518 (define_insn "*movdfcc_1"
16519 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16520 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16523 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16525 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16527 fcmov%F1\t{%2, %0|%0, %2}
16528 fcmov%f1\t{%3, %0|%0, %3}
16531 [(set_attr "type" "fcmov,fcmov,multi,multi")
16532 (set_attr "mode" "DF,DF,DI,DI")])
16535 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16536 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16537 [(match_operand 4 "flags_reg_operand" "")
16539 (match_operand:DF 2 "nonimmediate_operand" "")
16540 (match_operand:DF 3 "nonimmediate_operand" "")))]
16541 "!TARGET_64BIT && reload_completed"
16542 [(set (match_dup 2)
16543 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16547 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16551 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16552 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16555 (define_insn "*movsfcc_1_387"
16556 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16557 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16558 [(reg FLAGS_REG) (const_int 0)])
16559 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16560 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16561 "TARGET_80387 && TARGET_CMOVE
16562 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16564 fcmov%F1\t{%2, %0|%0, %2}
16565 fcmov%f1\t{%3, %0|%0, %3}
16566 cmov%O2%C1\t{%2, %0|%0, %2}
16567 cmov%O2%c1\t{%3, %0|%0, %3}"
16568 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16569 (set_attr "mode" "SF,SF,SI,SI")])
16571 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16572 ;; the scalar versions to have only XMM registers as operands.
16574 ;; XOP conditional move
16575 (define_insn "*xop_pcmov_<mode>"
16576 [(set (match_operand:MODEF 0 "register_operand" "=x")
16577 (if_then_else:MODEF
16578 (match_operand:MODEF 1 "register_operand" "x")
16579 (match_operand:MODEF 2 "register_operand" "x")
16580 (match_operand:MODEF 3 "register_operand" "x")))]
16582 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16583 [(set_attr "type" "sse4arg")])
16585 ;; These versions of the min/max patterns are intentionally ignorant of
16586 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16587 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16588 ;; are undefined in this condition, we're certain this is correct.
16590 (define_insn "<code><mode>3"
16591 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16593 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16594 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16595 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16597 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16598 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16599 [(set_attr "isa" "noavx,avx")
16600 (set_attr "prefix" "orig,vex")
16601 (set_attr "type" "sseadd")
16602 (set_attr "mode" "<MODE>")])
16604 ;; These versions of the min/max patterns implement exactly the operations
16605 ;; min = (op1 < op2 ? op1 : op2)
16606 ;; max = (!(op1 < op2) ? op1 : op2)
16607 ;; Their operands are not commutative, and thus they may be used in the
16608 ;; presence of -0.0 and NaN.
16610 (define_insn "*ieee_smin<mode>3"
16611 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16613 [(match_operand:MODEF 1 "register_operand" "0,x")
16614 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16616 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16618 min<ssemodesuffix>\t{%2, %0|%0, %2}
16619 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16620 [(set_attr "isa" "noavx,avx")
16621 (set_attr "prefix" "orig,vex")
16622 (set_attr "type" "sseadd")
16623 (set_attr "mode" "<MODE>")])
16625 (define_insn "*ieee_smax<mode>3"
16626 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16628 [(match_operand:MODEF 1 "register_operand" "0,x")
16629 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16633 max<ssemodesuffix>\t{%2, %0|%0, %2}
16634 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16635 [(set_attr "isa" "noavx,avx")
16636 (set_attr "prefix" "orig,vex")
16637 (set_attr "type" "sseadd")
16638 (set_attr "mode" "<MODE>")])
16640 ;; Make two stack loads independent:
16642 ;; fld %st(0) -> fld bb
16643 ;; fmul bb fmul %st(1), %st
16645 ;; Actually we only match the last two instructions for simplicity.
16647 [(set (match_operand 0 "fp_register_operand" "")
16648 (match_operand 1 "fp_register_operand" ""))
16650 (match_operator 2 "binary_fp_operator"
16652 (match_operand 3 "memory_operand" "")]))]
16653 "REGNO (operands[0]) != REGNO (operands[1])"
16654 [(set (match_dup 0) (match_dup 3))
16655 (set (match_dup 0) (match_dup 4))]
16657 ;; The % modifier is not operational anymore in peephole2's, so we have to
16658 ;; swap the operands manually in the case of addition and multiplication.
16662 if (COMMUTATIVE_ARITH_P (operands[2]))
16663 op0 = operands[0], op1 = operands[1];
16665 op0 = operands[1], op1 = operands[0];
16667 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16668 GET_MODE (operands[2]),
16672 ;; Conditional addition patterns
16673 (define_expand "add<mode>cc"
16674 [(match_operand:SWI 0 "register_operand" "")
16675 (match_operand 1 "ordered_comparison_operator" "")
16676 (match_operand:SWI 2 "register_operand" "")
16677 (match_operand:SWI 3 "const_int_operand" "")]
16679 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16681 ;; Misc patterns (?)
16683 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16684 ;; Otherwise there will be nothing to keep
16686 ;; [(set (reg ebp) (reg esp))]
16687 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16688 ;; (clobber (eflags)]
16689 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16691 ;; in proper program order.
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16694 [(set (match_operand:P 0 "register_operand" "=r,r")
16695 (plus:P (match_operand:P 1 "register_operand" "0,r")
16696 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16697 (clobber (reg:CC FLAGS_REG))
16698 (clobber (mem:BLK (scratch)))]
16701 switch (get_attr_type (insn))
16704 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16707 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16708 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16709 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16711 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16714 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16715 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16718 [(set (attr "type")
16719 (cond [(and (eq_attr "alternative" "0")
16720 (not (match_test "TARGET_OPT_AGU")))
16721 (const_string "alu")
16722 (match_operand:<MODE> 2 "const0_operand" "")
16723 (const_string "imov")
16725 (const_string "lea")))
16726 (set (attr "length_immediate")
16727 (cond [(eq_attr "type" "imov")
16729 (and (eq_attr "type" "alu")
16730 (match_operand 2 "const128_operand" ""))
16733 (const_string "*")))
16734 (set_attr "mode" "<MODE>")])
16736 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16737 [(set (match_operand:P 0 "register_operand" "=r")
16738 (minus:P (match_operand:P 1 "register_operand" "0")
16739 (match_operand:P 2 "register_operand" "r")))
16740 (clobber (reg:CC FLAGS_REG))
16741 (clobber (mem:BLK (scratch)))]
16743 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16744 [(set_attr "type" "alu")
16745 (set_attr "mode" "<MODE>")])
16747 (define_insn "allocate_stack_worker_probe_<mode>"
16748 [(set (match_operand:P 0 "register_operand" "=a")
16749 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16750 UNSPECV_STACK_PROBE))
16751 (clobber (reg:CC FLAGS_REG))]
16752 "ix86_target_stack_probe ()"
16753 "call\t___chkstk_ms"
16754 [(set_attr "type" "multi")
16755 (set_attr "length" "5")])
16757 (define_expand "allocate_stack"
16758 [(match_operand 0 "register_operand" "")
16759 (match_operand 1 "general_operand" "")]
16760 "ix86_target_stack_probe ()"
16764 #ifndef CHECK_STACK_LIMIT
16765 #define CHECK_STACK_LIMIT 0
16768 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16769 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16771 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16772 stack_pointer_rtx, 0, OPTAB_DIRECT);
16773 if (x != stack_pointer_rtx)
16774 emit_move_insn (stack_pointer_rtx, x);
16778 x = copy_to_mode_reg (Pmode, operands[1]);
16780 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16782 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16783 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16784 stack_pointer_rtx, 0, OPTAB_DIRECT);
16785 if (x != stack_pointer_rtx)
16786 emit_move_insn (stack_pointer_rtx, x);
16789 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16793 ;; Use IOR for stack probes, this is shorter.
16794 (define_expand "probe_stack"
16795 [(match_operand 0 "memory_operand" "")]
16798 rtx (*gen_ior3) (rtx, rtx, rtx);
16800 gen_ior3 = (GET_MODE (operands[0]) == DImode
16801 ? gen_iordi3 : gen_iorsi3);
16803 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16807 (define_insn "adjust_stack_and_probe<mode>"
16808 [(set (match_operand:P 0 "register_operand" "=r")
16809 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16810 UNSPECV_PROBE_STACK_RANGE))
16811 (set (reg:P SP_REG)
16812 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16813 (clobber (reg:CC FLAGS_REG))
16814 (clobber (mem:BLK (scratch)))]
16816 "* return output_adjust_stack_and_probe (operands[0]);"
16817 [(set_attr "type" "multi")])
16819 (define_insn "probe_stack_range<mode>"
16820 [(set (match_operand:P 0 "register_operand" "=r")
16821 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16822 (match_operand:P 2 "const_int_operand" "n")]
16823 UNSPECV_PROBE_STACK_RANGE))
16824 (clobber (reg:CC FLAGS_REG))]
16826 "* return output_probe_stack_range (operands[0], operands[2]);"
16827 [(set_attr "type" "multi")])
16829 (define_expand "builtin_setjmp_receiver"
16830 [(label_ref (match_operand 0 "" ""))]
16831 "!TARGET_64BIT && flag_pic"
16837 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16838 rtx label_rtx = gen_label_rtx ();
16839 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16840 xops[0] = xops[1] = picreg;
16841 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16842 ix86_expand_binary_operator (MINUS, SImode, xops);
16846 emit_insn (gen_set_got (pic_offset_table_rtx));
16850 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16853 [(set (match_operand 0 "register_operand" "")
16854 (match_operator 3 "promotable_binary_operator"
16855 [(match_operand 1 "register_operand" "")
16856 (match_operand 2 "aligned_operand" "")]))
16857 (clobber (reg:CC FLAGS_REG))]
16858 "! TARGET_PARTIAL_REG_STALL && reload_completed
16859 && ((GET_MODE (operands[0]) == HImode
16860 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16861 /* ??? next two lines just !satisfies_constraint_K (...) */
16862 || !CONST_INT_P (operands[2])
16863 || satisfies_constraint_K (operands[2])))
16864 || (GET_MODE (operands[0]) == QImode
16865 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16866 [(parallel [(set (match_dup 0)
16867 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16868 (clobber (reg:CC FLAGS_REG))])]
16870 operands[0] = gen_lowpart (SImode, operands[0]);
16871 operands[1] = gen_lowpart (SImode, operands[1]);
16872 if (GET_CODE (operands[3]) != ASHIFT)
16873 operands[2] = gen_lowpart (SImode, operands[2]);
16874 PUT_MODE (operands[3], SImode);
16877 ; Promote the QImode tests, as i386 has encoding of the AND
16878 ; instruction with 32-bit sign-extended immediate and thus the
16879 ; instruction size is unchanged, except in the %eax case for
16880 ; which it is increased by one byte, hence the ! optimize_size.
16882 [(set (match_operand 0 "flags_reg_operand" "")
16883 (match_operator 2 "compare_operator"
16884 [(and (match_operand 3 "aligned_operand" "")
16885 (match_operand 4 "const_int_operand" ""))
16887 (set (match_operand 1 "register_operand" "")
16888 (and (match_dup 3) (match_dup 4)))]
16889 "! TARGET_PARTIAL_REG_STALL && reload_completed
16890 && optimize_insn_for_speed_p ()
16891 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16892 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16893 /* Ensure that the operand will remain sign-extended immediate. */
16894 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16895 [(parallel [(set (match_dup 0)
16896 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16899 (and:SI (match_dup 3) (match_dup 4)))])]
16902 = gen_int_mode (INTVAL (operands[4])
16903 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16904 operands[1] = gen_lowpart (SImode, operands[1]);
16905 operands[3] = gen_lowpart (SImode, operands[3]);
16908 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16909 ; the TEST instruction with 32-bit sign-extended immediate and thus
16910 ; the instruction size would at least double, which is not what we
16911 ; want even with ! optimize_size.
16913 [(set (match_operand 0 "flags_reg_operand" "")
16914 (match_operator 1 "compare_operator"
16915 [(and (match_operand:HI 2 "aligned_operand" "")
16916 (match_operand:HI 3 "const_int_operand" ""))
16918 "! TARGET_PARTIAL_REG_STALL && reload_completed
16919 && ! TARGET_FAST_PREFIX
16920 && optimize_insn_for_speed_p ()
16921 /* Ensure that the operand will remain sign-extended immediate. */
16922 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16923 [(set (match_dup 0)
16924 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16928 = gen_int_mode (INTVAL (operands[3])
16929 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16930 operands[2] = gen_lowpart (SImode, operands[2]);
16934 [(set (match_operand 0 "register_operand" "")
16935 (neg (match_operand 1 "register_operand" "")))
16936 (clobber (reg:CC FLAGS_REG))]
16937 "! TARGET_PARTIAL_REG_STALL && reload_completed
16938 && (GET_MODE (operands[0]) == HImode
16939 || (GET_MODE (operands[0]) == QImode
16940 && (TARGET_PROMOTE_QImode
16941 || optimize_insn_for_size_p ())))"
16942 [(parallel [(set (match_dup 0)
16943 (neg:SI (match_dup 1)))
16944 (clobber (reg:CC FLAGS_REG))])]
16946 operands[0] = gen_lowpart (SImode, operands[0]);
16947 operands[1] = gen_lowpart (SImode, operands[1]);
16951 [(set (match_operand 0 "register_operand" "")
16952 (not (match_operand 1 "register_operand" "")))]
16953 "! TARGET_PARTIAL_REG_STALL && reload_completed
16954 && (GET_MODE (operands[0]) == HImode
16955 || (GET_MODE (operands[0]) == QImode
16956 && (TARGET_PROMOTE_QImode
16957 || optimize_insn_for_size_p ())))"
16958 [(set (match_dup 0)
16959 (not:SI (match_dup 1)))]
16961 operands[0] = gen_lowpart (SImode, operands[0]);
16962 operands[1] = gen_lowpart (SImode, operands[1]);
16966 [(set (match_operand 0 "register_operand" "")
16967 (if_then_else (match_operator 1 "ordered_comparison_operator"
16968 [(reg FLAGS_REG) (const_int 0)])
16969 (match_operand 2 "register_operand" "")
16970 (match_operand 3 "register_operand" "")))]
16971 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16972 && (GET_MODE (operands[0]) == HImode
16973 || (GET_MODE (operands[0]) == QImode
16974 && (TARGET_PROMOTE_QImode
16975 || optimize_insn_for_size_p ())))"
16976 [(set (match_dup 0)
16977 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16979 operands[0] = gen_lowpart (SImode, operands[0]);
16980 operands[2] = gen_lowpart (SImode, operands[2]);
16981 operands[3] = gen_lowpart (SImode, operands[3]);
16984 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16985 ;; transform a complex memory operation into two memory to register operations.
16987 ;; Don't push memory operands
16989 [(set (match_operand:SWI 0 "push_operand" "")
16990 (match_operand:SWI 1 "memory_operand" ""))
16991 (match_scratch:SWI 2 "<r>")]
16992 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16993 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16994 [(set (match_dup 2) (match_dup 1))
16995 (set (match_dup 0) (match_dup 2))])
16997 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17000 [(set (match_operand:SF 0 "push_operand" "")
17001 (match_operand:SF 1 "memory_operand" ""))
17002 (match_scratch:SF 2 "r")]
17003 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17004 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17005 [(set (match_dup 2) (match_dup 1))
17006 (set (match_dup 0) (match_dup 2))])
17008 ;; Don't move an immediate directly to memory when the instruction
17011 [(match_scratch:SWI124 1 "<r>")
17012 (set (match_operand:SWI124 0 "memory_operand" "")
17014 "optimize_insn_for_speed_p ()
17015 && !TARGET_USE_MOV0
17016 && TARGET_SPLIT_LONG_MOVES
17017 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17018 && peep2_regno_dead_p (0, FLAGS_REG)"
17019 [(parallel [(set (match_dup 2) (const_int 0))
17020 (clobber (reg:CC FLAGS_REG))])
17021 (set (match_dup 0) (match_dup 1))]
17022 "operands[2] = gen_lowpart (SImode, operands[1]);")
17025 [(match_scratch:SWI124 2 "<r>")
17026 (set (match_operand:SWI124 0 "memory_operand" "")
17027 (match_operand:SWI124 1 "immediate_operand" ""))]
17028 "optimize_insn_for_speed_p ()
17029 && TARGET_SPLIT_LONG_MOVES
17030 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17031 [(set (match_dup 2) (match_dup 1))
17032 (set (match_dup 0) (match_dup 2))])
17034 ;; Don't compare memory with zero, load and use a test instead.
17036 [(set (match_operand 0 "flags_reg_operand" "")
17037 (match_operator 1 "compare_operator"
17038 [(match_operand:SI 2 "memory_operand" "")
17040 (match_scratch:SI 3 "r")]
17041 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17042 [(set (match_dup 3) (match_dup 2))
17043 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17045 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17046 ;; Don't split NOTs with a displacement operand, because resulting XOR
17047 ;; will not be pairable anyway.
17049 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17050 ;; represented using a modRM byte. The XOR replacement is long decoded,
17051 ;; so this split helps here as well.
17053 ;; Note: Can't do this as a regular split because we can't get proper
17054 ;; lifetime information then.
17057 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17058 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17059 "optimize_insn_for_speed_p ()
17060 && ((TARGET_NOT_UNPAIRABLE
17061 && (!MEM_P (operands[0])
17062 || !memory_displacement_operand (operands[0], <MODE>mode)))
17063 || (TARGET_NOT_VECTORMODE
17064 && long_memory_operand (operands[0], <MODE>mode)))
17065 && peep2_regno_dead_p (0, FLAGS_REG)"
17066 [(parallel [(set (match_dup 0)
17067 (xor:SWI124 (match_dup 1) (const_int -1)))
17068 (clobber (reg:CC FLAGS_REG))])])
17070 ;; Non pairable "test imm, reg" instructions can be translated to
17071 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17072 ;; byte opcode instead of two, have a short form for byte operands),
17073 ;; so do it for other CPUs as well. Given that the value was dead,
17074 ;; this should not create any new dependencies. Pass on the sub-word
17075 ;; versions if we're concerned about partial register stalls.
17078 [(set (match_operand 0 "flags_reg_operand" "")
17079 (match_operator 1 "compare_operator"
17080 [(and:SI (match_operand:SI 2 "register_operand" "")
17081 (match_operand:SI 3 "immediate_operand" ""))
17083 "ix86_match_ccmode (insn, CCNOmode)
17084 && (true_regnum (operands[2]) != AX_REG
17085 || satisfies_constraint_K (operands[3]))
17086 && peep2_reg_dead_p (1, operands[2])"
17088 [(set (match_dup 0)
17089 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17092 (and:SI (match_dup 2) (match_dup 3)))])])
17094 ;; We don't need to handle HImode case, because it will be promoted to SImode
17095 ;; on ! TARGET_PARTIAL_REG_STALL
17098 [(set (match_operand 0 "flags_reg_operand" "")
17099 (match_operator 1 "compare_operator"
17100 [(and:QI (match_operand:QI 2 "register_operand" "")
17101 (match_operand:QI 3 "immediate_operand" ""))
17103 "! TARGET_PARTIAL_REG_STALL
17104 && ix86_match_ccmode (insn, CCNOmode)
17105 && true_regnum (operands[2]) != AX_REG
17106 && peep2_reg_dead_p (1, operands[2])"
17108 [(set (match_dup 0)
17109 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17112 (and:QI (match_dup 2) (match_dup 3)))])])
17115 [(set (match_operand 0 "flags_reg_operand" "")
17116 (match_operator 1 "compare_operator"
17119 (match_operand 2 "ext_register_operand" "")
17122 (match_operand 3 "const_int_operand" ""))
17124 "! TARGET_PARTIAL_REG_STALL
17125 && ix86_match_ccmode (insn, CCNOmode)
17126 && true_regnum (operands[2]) != AX_REG
17127 && peep2_reg_dead_p (1, operands[2])"
17128 [(parallel [(set (match_dup 0)
17137 (set (zero_extract:SI (match_dup 2)
17145 (match_dup 3)))])])
17147 ;; Don't do logical operations with memory inputs.
17149 [(match_scratch:SI 2 "r")
17150 (parallel [(set (match_operand:SI 0 "register_operand" "")
17151 (match_operator:SI 3 "arith_or_logical_operator"
17153 (match_operand:SI 1 "memory_operand" "")]))
17154 (clobber (reg:CC FLAGS_REG))])]
17155 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17156 [(set (match_dup 2) (match_dup 1))
17157 (parallel [(set (match_dup 0)
17158 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17159 (clobber (reg:CC FLAGS_REG))])])
17162 [(match_scratch:SI 2 "r")
17163 (parallel [(set (match_operand:SI 0 "register_operand" "")
17164 (match_operator:SI 3 "arith_or_logical_operator"
17165 [(match_operand:SI 1 "memory_operand" "")
17167 (clobber (reg:CC FLAGS_REG))])]
17168 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17169 [(set (match_dup 2) (match_dup 1))
17170 (parallel [(set (match_dup 0)
17171 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17172 (clobber (reg:CC FLAGS_REG))])])
17174 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17175 ;; refers to the destination of the load!
17178 [(set (match_operand:SI 0 "register_operand" "")
17179 (match_operand:SI 1 "register_operand" ""))
17180 (parallel [(set (match_dup 0)
17181 (match_operator:SI 3 "commutative_operator"
17183 (match_operand:SI 2 "memory_operand" "")]))
17184 (clobber (reg:CC FLAGS_REG))])]
17185 "REGNO (operands[0]) != REGNO (operands[1])
17186 && GENERAL_REGNO_P (REGNO (operands[0]))
17187 && GENERAL_REGNO_P (REGNO (operands[1]))"
17188 [(set (match_dup 0) (match_dup 4))
17189 (parallel [(set (match_dup 0)
17190 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17191 (clobber (reg:CC FLAGS_REG))])]
17192 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17195 [(set (match_operand 0 "register_operand" "")
17196 (match_operand 1 "register_operand" ""))
17198 (match_operator 3 "commutative_operator"
17200 (match_operand 2 "memory_operand" "")]))]
17201 "REGNO (operands[0]) != REGNO (operands[1])
17202 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17203 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17204 [(set (match_dup 0) (match_dup 2))
17206 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17208 ; Don't do logical operations with memory outputs
17210 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17211 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17212 ; the same decoder scheduling characteristics as the original.
17215 [(match_scratch:SI 2 "r")
17216 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17217 (match_operator:SI 3 "arith_or_logical_operator"
17219 (match_operand:SI 1 "nonmemory_operand" "")]))
17220 (clobber (reg:CC FLAGS_REG))])]
17221 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17222 /* Do not split stack checking probes. */
17223 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17224 [(set (match_dup 2) (match_dup 0))
17225 (parallel [(set (match_dup 2)
17226 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17227 (clobber (reg:CC FLAGS_REG))])
17228 (set (match_dup 0) (match_dup 2))])
17231 [(match_scratch:SI 2 "r")
17232 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17233 (match_operator:SI 3 "arith_or_logical_operator"
17234 [(match_operand:SI 1 "nonmemory_operand" "")
17236 (clobber (reg:CC FLAGS_REG))])]
17237 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17238 /* Do not split stack checking probes. */
17239 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17240 [(set (match_dup 2) (match_dup 0))
17241 (parallel [(set (match_dup 2)
17242 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17243 (clobber (reg:CC FLAGS_REG))])
17244 (set (match_dup 0) (match_dup 2))])
17246 ;; Attempt to use arith or logical operations with memory outputs with
17247 ;; setting of flags.
17249 [(set (match_operand:SWI 0 "register_operand" "")
17250 (match_operand:SWI 1 "memory_operand" ""))
17251 (parallel [(set (match_dup 0)
17252 (match_operator:SWI 3 "plusminuslogic_operator"
17254 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17255 (clobber (reg:CC FLAGS_REG))])
17256 (set (match_dup 1) (match_dup 0))
17257 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17258 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17259 && peep2_reg_dead_p (4, operands[0])
17260 && !reg_overlap_mentioned_p (operands[0], operands[1])
17261 && ix86_match_ccmode (peep2_next_insn (3),
17262 (GET_CODE (operands[3]) == PLUS
17263 || GET_CODE (operands[3]) == MINUS)
17264 ? CCGOCmode : CCNOmode)"
17265 [(parallel [(set (match_dup 4) (match_dup 5))
17266 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17267 (match_dup 2)]))])]
17269 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17270 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17271 copy_rtx (operands[1]),
17272 copy_rtx (operands[2]));
17273 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17274 operands[5], const0_rtx);
17278 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17279 (match_operator:SWI 2 "plusminuslogic_operator"
17281 (match_operand:SWI 1 "memory_operand" "")]))
17282 (clobber (reg:CC FLAGS_REG))])
17283 (set (match_dup 1) (match_dup 0))
17284 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17285 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17286 && GET_CODE (operands[2]) != MINUS
17287 && peep2_reg_dead_p (3, operands[0])
17288 && !reg_overlap_mentioned_p (operands[0], operands[1])
17289 && ix86_match_ccmode (peep2_next_insn (2),
17290 GET_CODE (operands[2]) == PLUS
17291 ? CCGOCmode : CCNOmode)"
17292 [(parallel [(set (match_dup 3) (match_dup 4))
17293 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17294 (match_dup 0)]))])]
17296 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17297 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17298 copy_rtx (operands[1]),
17299 copy_rtx (operands[0]));
17300 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17301 operands[4], const0_rtx);
17305 [(set (match_operand:SWI12 0 "register_operand" "")
17306 (match_operand:SWI12 1 "memory_operand" ""))
17307 (parallel [(set (match_operand:SI 4 "register_operand" "")
17308 (match_operator:SI 3 "plusminuslogic_operator"
17310 (match_operand:SI 2 "nonmemory_operand" "")]))
17311 (clobber (reg:CC FLAGS_REG))])
17312 (set (match_dup 1) (match_dup 0))
17313 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17314 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17315 && REG_P (operands[0]) && REG_P (operands[4])
17316 && REGNO (operands[0]) == REGNO (operands[4])
17317 && peep2_reg_dead_p (4, operands[0])
17318 && !reg_overlap_mentioned_p (operands[0], operands[1])
17319 && ix86_match_ccmode (peep2_next_insn (3),
17320 (GET_CODE (operands[3]) == PLUS
17321 || GET_CODE (operands[3]) == MINUS)
17322 ? CCGOCmode : CCNOmode)"
17323 [(parallel [(set (match_dup 4) (match_dup 5))
17324 (set (match_dup 1) (match_dup 6))])]
17326 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17327 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17328 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17329 copy_rtx (operands[1]), operands[2]);
17330 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17331 operands[5], const0_rtx);
17332 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17333 copy_rtx (operands[1]),
17334 copy_rtx (operands[2]));
17337 ;; Attempt to always use XOR for zeroing registers.
17339 [(set (match_operand 0 "register_operand" "")
17340 (match_operand 1 "const0_operand" ""))]
17341 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17342 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17343 && GENERAL_REG_P (operands[0])
17344 && peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (const_int 0))
17346 (clobber (reg:CC FLAGS_REG))])]
17347 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17350 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17352 "(GET_MODE (operands[0]) == QImode
17353 || GET_MODE (operands[0]) == HImode)
17354 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17355 && peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17357 (clobber (reg:CC FLAGS_REG))])])
17359 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17361 [(set (match_operand:SWI248 0 "register_operand" "")
17363 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17364 && peep2_regno_dead_p (0, FLAGS_REG)"
17365 [(parallel [(set (match_dup 0) (const_int -1))
17366 (clobber (reg:CC FLAGS_REG))])]
17368 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17369 operands[0] = gen_lowpart (SImode, operands[0]);
17372 ;; Attempt to convert simple lea to add/shift.
17373 ;; These can be created by move expanders.
17376 [(set (match_operand:SWI48 0 "register_operand" "")
17377 (plus:SWI48 (match_dup 0)
17378 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17379 "peep2_regno_dead_p (0, FLAGS_REG)"
17380 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17381 (clobber (reg:CC FLAGS_REG))])])
17384 [(set (match_operand:SI 0 "register_operand" "")
17385 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17386 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17388 && peep2_regno_dead_p (0, FLAGS_REG)
17389 && REGNO (operands[0]) == REGNO (operands[1])"
17390 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17391 (clobber (reg:CC FLAGS_REG))])]
17392 "operands[2] = gen_lowpart (SImode, operands[2]);")
17395 [(set (match_operand:SWI48 0 "register_operand" "")
17396 (mult:SWI48 (match_dup 0)
17397 (match_operand:SWI48 1 "const_int_operand" "")))]
17398 "exact_log2 (INTVAL (operands[1])) >= 0
17399 && peep2_regno_dead_p (0, FLAGS_REG)"
17400 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17401 (clobber (reg:CC FLAGS_REG))])]
17402 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17405 [(set (match_operand:SI 0 "register_operand" "")
17406 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17407 (match_operand:DI 2 "const_int_operand" "")) 0))]
17409 && exact_log2 (INTVAL (operands[2])) >= 0
17410 && REGNO (operands[0]) == REGNO (operands[1])
17411 && peep2_regno_dead_p (0, FLAGS_REG)"
17412 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17413 (clobber (reg:CC FLAGS_REG))])]
17414 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17416 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17417 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17418 ;; On many CPUs it is also faster, since special hardware to avoid esp
17419 ;; dependencies is present.
17421 ;; While some of these conversions may be done using splitters, we use
17422 ;; peepholes in order to allow combine_stack_adjustments pass to see
17423 ;; nonobfuscated RTL.
17425 ;; Convert prologue esp subtractions to push.
17426 ;; We need register to push. In order to keep verify_flow_info happy we have
17428 ;; - use scratch and clobber it in order to avoid dependencies
17429 ;; - use already live register
17430 ;; We can't use the second way right now, since there is no reliable way how to
17431 ;; verify that given register is live. First choice will also most likely in
17432 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17433 ;; call clobbered registers are dead. We may want to use base pointer as an
17434 ;; alternative when no register is available later.
17437 [(match_scratch:P 1 "r")
17438 (parallel [(set (reg:P SP_REG)
17439 (plus:P (reg:P SP_REG)
17440 (match_operand:P 0 "const_int_operand" "")))
17441 (clobber (reg:CC FLAGS_REG))
17442 (clobber (mem:BLK (scratch)))])]
17443 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17444 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17445 [(clobber (match_dup 1))
17446 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17447 (clobber (mem:BLK (scratch)))])])
17450 [(match_scratch:P 1 "r")
17451 (parallel [(set (reg:P SP_REG)
17452 (plus:P (reg:P SP_REG)
17453 (match_operand:P 0 "const_int_operand" "")))
17454 (clobber (reg:CC FLAGS_REG))
17455 (clobber (mem:BLK (scratch)))])]
17456 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17457 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17458 [(clobber (match_dup 1))
17459 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17460 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17461 (clobber (mem:BLK (scratch)))])])
17463 ;; Convert esp subtractions to push.
17465 [(match_scratch:P 1 "r")
17466 (parallel [(set (reg:P SP_REG)
17467 (plus:P (reg:P SP_REG)
17468 (match_operand:P 0 "const_int_operand" "")))
17469 (clobber (reg:CC FLAGS_REG))])]
17470 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17471 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17472 [(clobber (match_dup 1))
17473 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17476 [(match_scratch:P 1 "r")
17477 (parallel [(set (reg:P SP_REG)
17478 (plus:P (reg:P SP_REG)
17479 (match_operand:P 0 "const_int_operand" "")))
17480 (clobber (reg:CC FLAGS_REG))])]
17481 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17482 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17483 [(clobber (match_dup 1))
17484 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17485 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17487 ;; Convert epilogue deallocator to pop.
17489 [(match_scratch:P 1 "r")
17490 (parallel [(set (reg:P SP_REG)
17491 (plus:P (reg:P SP_REG)
17492 (match_operand:P 0 "const_int_operand" "")))
17493 (clobber (reg:CC FLAGS_REG))
17494 (clobber (mem:BLK (scratch)))])]
17495 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17496 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17497 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17498 (clobber (mem:BLK (scratch)))])])
17500 ;; Two pops case is tricky, since pop causes dependency
17501 ;; on destination register. We use two registers if available.
17503 [(match_scratch:P 1 "r")
17504 (match_scratch:P 2 "r")
17505 (parallel [(set (reg:P SP_REG)
17506 (plus:P (reg:P SP_REG)
17507 (match_operand:P 0 "const_int_operand" "")))
17508 (clobber (reg:CC FLAGS_REG))
17509 (clobber (mem:BLK (scratch)))])]
17510 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17511 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17512 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17513 (clobber (mem:BLK (scratch)))])
17514 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17517 [(match_scratch:P 1 "r")
17518 (parallel [(set (reg:P SP_REG)
17519 (plus:P (reg:P SP_REG)
17520 (match_operand:P 0 "const_int_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))
17522 (clobber (mem:BLK (scratch)))])]
17523 "optimize_insn_for_size_p ()
17524 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17525 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17526 (clobber (mem:BLK (scratch)))])
17527 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17529 ;; Convert esp additions to pop.
17531 [(match_scratch:P 1 "r")
17532 (parallel [(set (reg:P SP_REG)
17533 (plus:P (reg:P SP_REG)
17534 (match_operand:P 0 "const_int_operand" "")))
17535 (clobber (reg:CC FLAGS_REG))])]
17536 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17537 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17539 ;; Two pops case is tricky, since pop causes dependency
17540 ;; on destination register. We use two registers if available.
17542 [(match_scratch:P 1 "r")
17543 (match_scratch:P 2 "r")
17544 (parallel [(set (reg:P SP_REG)
17545 (plus:P (reg:P SP_REG)
17546 (match_operand:P 0 "const_int_operand" "")))
17547 (clobber (reg:CC FLAGS_REG))])]
17548 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17549 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17550 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17553 [(match_scratch:P 1 "r")
17554 (parallel [(set (reg:P SP_REG)
17555 (plus:P (reg:P SP_REG)
17556 (match_operand:P 0 "const_int_operand" "")))
17557 (clobber (reg:CC FLAGS_REG))])]
17558 "optimize_insn_for_size_p ()
17559 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17560 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17561 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17563 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17564 ;; required and register dies. Similarly for 128 to -128.
17566 [(set (match_operand 0 "flags_reg_operand" "")
17567 (match_operator 1 "compare_operator"
17568 [(match_operand 2 "register_operand" "")
17569 (match_operand 3 "const_int_operand" "")]))]
17570 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17571 && incdec_operand (operands[3], GET_MODE (operands[3])))
17572 || (!TARGET_FUSE_CMP_AND_BRANCH
17573 && INTVAL (operands[3]) == 128))
17574 && ix86_match_ccmode (insn, CCGCmode)
17575 && peep2_reg_dead_p (1, operands[2])"
17576 [(parallel [(set (match_dup 0)
17577 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17578 (clobber (match_dup 2))])])
17580 ;; Convert imul by three, five and nine into lea
17583 [(set (match_operand:SWI48 0 "register_operand" "")
17584 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17585 (match_operand:SWI48 2 "const359_operand" "")))
17586 (clobber (reg:CC FLAGS_REG))])]
17587 "!TARGET_PARTIAL_REG_STALL
17588 || <MODE>mode == SImode
17589 || optimize_function_for_size_p (cfun)"
17590 [(set (match_dup 0)
17591 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17593 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17597 [(set (match_operand:SWI48 0 "register_operand" "")
17598 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17599 (match_operand:SWI48 2 "const359_operand" "")))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "optimize_insn_for_speed_p ()
17602 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17603 [(set (match_dup 0) (match_dup 1))
17605 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17607 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17609 ;; imul $32bit_imm, mem, reg is vector decoded, while
17610 ;; imul $32bit_imm, reg, reg is direct decoded.
17612 [(match_scratch:SWI48 3 "r")
17613 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17614 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17615 (match_operand:SWI48 2 "immediate_operand" "")))
17616 (clobber (reg:CC FLAGS_REG))])]
17617 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17618 && !satisfies_constraint_K (operands[2])"
17619 [(set (match_dup 3) (match_dup 1))
17620 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17621 (clobber (reg:CC FLAGS_REG))])])
17624 [(match_scratch:SI 3 "r")
17625 (parallel [(set (match_operand:DI 0 "register_operand" "")
17627 (mult:SI (match_operand:SI 1 "memory_operand" "")
17628 (match_operand:SI 2 "immediate_operand" ""))))
17629 (clobber (reg:CC FLAGS_REG))])]
17631 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17632 && !satisfies_constraint_K (operands[2])"
17633 [(set (match_dup 3) (match_dup 1))
17634 (parallel [(set (match_dup 0)
17635 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17636 (clobber (reg:CC FLAGS_REG))])])
17638 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17639 ;; Convert it into imul reg, reg
17640 ;; It would be better to force assembler to encode instruction using long
17641 ;; immediate, but there is apparently no way to do so.
17643 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17645 (match_operand:SWI248 1 "nonimmediate_operand" "")
17646 (match_operand:SWI248 2 "const_int_operand" "")))
17647 (clobber (reg:CC FLAGS_REG))])
17648 (match_scratch:SWI248 3 "r")]
17649 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17650 && satisfies_constraint_K (operands[2])"
17651 [(set (match_dup 3) (match_dup 2))
17652 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17653 (clobber (reg:CC FLAGS_REG))])]
17655 if (!rtx_equal_p (operands[0], operands[1]))
17656 emit_move_insn (operands[0], operands[1]);
17659 ;; After splitting up read-modify operations, array accesses with memory
17660 ;; operands might end up in form:
17662 ;; movl 4(%esp), %edx
17664 ;; instead of pre-splitting:
17666 ;; addl 4(%esp), %eax
17668 ;; movl 4(%esp), %edx
17669 ;; leal (%edx,%eax,4), %eax
17672 [(match_scratch:P 5 "r")
17673 (parallel [(set (match_operand 0 "register_operand" "")
17674 (ashift (match_operand 1 "register_operand" "")
17675 (match_operand 2 "const_int_operand" "")))
17676 (clobber (reg:CC FLAGS_REG))])
17677 (parallel [(set (match_operand 3 "register_operand" "")
17678 (plus (match_dup 0)
17679 (match_operand 4 "x86_64_general_operand" "")))
17680 (clobber (reg:CC FLAGS_REG))])]
17681 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17682 /* Validate MODE for lea. */
17683 && ((!TARGET_PARTIAL_REG_STALL
17684 && (GET_MODE (operands[0]) == QImode
17685 || GET_MODE (operands[0]) == HImode))
17686 || GET_MODE (operands[0]) == SImode
17687 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17688 && (rtx_equal_p (operands[0], operands[3])
17689 || peep2_reg_dead_p (2, operands[0]))
17690 /* We reorder load and the shift. */
17691 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17692 [(set (match_dup 5) (match_dup 4))
17693 (set (match_dup 0) (match_dup 1))]
17695 enum machine_mode op1mode = GET_MODE (operands[1]);
17696 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17697 int scale = 1 << INTVAL (operands[2]);
17698 rtx index = gen_lowpart (Pmode, operands[1]);
17699 rtx base = gen_lowpart (Pmode, operands[5]);
17700 rtx dest = gen_lowpart (mode, operands[3]);
17702 operands[1] = gen_rtx_PLUS (Pmode, base,
17703 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17704 operands[5] = base;
17706 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17707 if (op1mode != Pmode)
17708 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17709 operands[0] = dest;
17712 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17713 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17714 ;; caught for use by garbage collectors and the like. Using an insn that
17715 ;; maps to SIGILL makes it more likely the program will rightfully die.
17716 ;; Keeping with tradition, "6" is in honor of #UD.
17717 (define_insn "trap"
17718 [(trap_if (const_int 1) (const_int 6))]
17720 { return ASM_SHORT "0x0b0f"; }
17721 [(set_attr "length" "2")])
17723 (define_expand "prefetch"
17724 [(prefetch (match_operand 0 "address_operand" "")
17725 (match_operand:SI 1 "const_int_operand" "")
17726 (match_operand:SI 2 "const_int_operand" ""))]
17727 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17729 int rw = INTVAL (operands[1]);
17730 int locality = INTVAL (operands[2]);
17732 gcc_assert (rw == 0 || rw == 1);
17733 gcc_assert (locality >= 0 && locality <= 3);
17734 gcc_assert (GET_MODE (operands[0]) == Pmode
17735 || GET_MODE (operands[0]) == VOIDmode);
17737 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17738 supported by SSE counterpart or the SSE prefetch is not available
17739 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17741 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17742 operands[2] = GEN_INT (3);
17744 operands[1] = const0_rtx;
17747 (define_insn "*prefetch_sse_<mode>"
17748 [(prefetch (match_operand:P 0 "address_operand" "p")
17750 (match_operand:SI 1 "const_int_operand" ""))]
17751 "TARGET_PREFETCH_SSE"
17753 static const char * const patterns[4] = {
17754 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17757 int locality = INTVAL (operands[1]);
17758 gcc_assert (locality >= 0 && locality <= 3);
17760 return patterns[locality];
17762 [(set_attr "type" "sse")
17763 (set_attr "atom_sse_attr" "prefetch")
17764 (set (attr "length_address")
17765 (symbol_ref "memory_address_length (operands[0])"))
17766 (set_attr "memory" "none")])
17768 (define_insn "*prefetch_3dnow_<mode>"
17769 [(prefetch (match_operand:P 0 "address_operand" "p")
17770 (match_operand:SI 1 "const_int_operand" "n")
17774 if (INTVAL (operands[1]) == 0)
17775 return "prefetch\t%a0";
17777 return "prefetchw\t%a0";
17779 [(set_attr "type" "mmx")
17780 (set (attr "length_address")
17781 (symbol_ref "memory_address_length (operands[0])"))
17782 (set_attr "memory" "none")])
17784 (define_expand "stack_protect_set"
17785 [(match_operand 0 "memory_operand" "")
17786 (match_operand 1 "memory_operand" "")]
17789 rtx (*insn)(rtx, rtx);
17791 #ifdef TARGET_THREAD_SSP_OFFSET
17792 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17793 insn = (TARGET_LP64
17794 ? gen_stack_tls_protect_set_di
17795 : gen_stack_tls_protect_set_si);
17797 insn = (TARGET_LP64
17798 ? gen_stack_protect_set_di
17799 : gen_stack_protect_set_si);
17802 emit_insn (insn (operands[0], operands[1]));
17806 (define_insn "stack_protect_set_<mode>"
17807 [(set (match_operand:PTR 0 "memory_operand" "=m")
17808 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17810 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17811 (clobber (reg:CC FLAGS_REG))]
17813 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17814 [(set_attr "type" "multi")])
17816 (define_insn "stack_tls_protect_set_<mode>"
17817 [(set (match_operand:PTR 0 "memory_operand" "=m")
17818 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17819 UNSPEC_SP_TLS_SET))
17820 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17821 (clobber (reg:CC FLAGS_REG))]
17823 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17824 [(set_attr "type" "multi")])
17826 (define_expand "stack_protect_test"
17827 [(match_operand 0 "memory_operand" "")
17828 (match_operand 1 "memory_operand" "")
17829 (match_operand 2 "" "")]
17832 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17834 rtx (*insn)(rtx, rtx, rtx);
17836 #ifdef TARGET_THREAD_SSP_OFFSET
17837 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17838 insn = (TARGET_LP64
17839 ? gen_stack_tls_protect_test_di
17840 : gen_stack_tls_protect_test_si);
17842 insn = (TARGET_LP64
17843 ? gen_stack_protect_test_di
17844 : gen_stack_protect_test_si);
17847 emit_insn (insn (flags, operands[0], operands[1]));
17849 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17850 flags, const0_rtx, operands[2]));
17854 (define_insn "stack_protect_test_<mode>"
17855 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17856 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17857 (match_operand:PTR 2 "memory_operand" "m")]
17859 (clobber (match_scratch:PTR 3 "=&r"))]
17861 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17862 [(set_attr "type" "multi")])
17864 (define_insn "stack_tls_protect_test_<mode>"
17865 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17866 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17867 (match_operand:PTR 2 "const_int_operand" "i")]
17868 UNSPEC_SP_TLS_TEST))
17869 (clobber (match_scratch:PTR 3 "=r"))]
17871 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17872 [(set_attr "type" "multi")])
17874 (define_insn "sse4_2_crc32<mode>"
17875 [(set (match_operand:SI 0 "register_operand" "=r")
17877 [(match_operand:SI 1 "register_operand" "0")
17878 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17880 "TARGET_SSE4_2 || TARGET_CRC32"
17881 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17882 [(set_attr "type" "sselog1")
17883 (set_attr "prefix_rep" "1")
17884 (set_attr "prefix_extra" "1")
17885 (set (attr "prefix_data16")
17886 (if_then_else (match_operand:HI 2 "" "")
17888 (const_string "*")))
17889 (set (attr "prefix_rex")
17890 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17892 (const_string "*")))
17893 (set_attr "mode" "SI")])
17895 (define_insn "sse4_2_crc32di"
17896 [(set (match_operand:DI 0 "register_operand" "=r")
17898 [(match_operand:DI 1 "register_operand" "0")
17899 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17901 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17902 "crc32{q}\t{%2, %0|%0, %2}"
17903 [(set_attr "type" "sselog1")
17904 (set_attr "prefix_rep" "1")
17905 (set_attr "prefix_extra" "1")
17906 (set_attr "mode" "DI")])
17908 (define_expand "rdpmc"
17909 [(match_operand:DI 0 "register_operand" "")
17910 (match_operand:SI 1 "register_operand" "")]
17913 rtx reg = gen_reg_rtx (DImode);
17916 /* Force operand 1 into ECX. */
17917 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17918 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17919 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17924 rtvec vec = rtvec_alloc (2);
17925 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17926 rtx upper = gen_reg_rtx (DImode);
17927 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17928 gen_rtvec (1, const0_rtx),
17930 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17931 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17933 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17934 NULL, 1, OPTAB_DIRECT);
17935 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17939 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17940 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17944 (define_insn "*rdpmc"
17945 [(set (match_operand:DI 0 "register_operand" "=A")
17946 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17950 [(set_attr "type" "other")
17951 (set_attr "length" "2")])
17953 (define_insn "*rdpmc_rex64"
17954 [(set (match_operand:DI 0 "register_operand" "=a")
17955 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17957 (set (match_operand:DI 1 "register_operand" "=d")
17958 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17961 [(set_attr "type" "other")
17962 (set_attr "length" "2")])
17964 (define_expand "rdtsc"
17965 [(set (match_operand:DI 0 "register_operand" "")
17966 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17971 rtvec vec = rtvec_alloc (2);
17972 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17973 rtx upper = gen_reg_rtx (DImode);
17974 rtx lower = gen_reg_rtx (DImode);
17975 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17976 gen_rtvec (1, const0_rtx),
17978 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17979 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17981 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17982 NULL, 1, OPTAB_DIRECT);
17983 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17985 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17990 (define_insn "*rdtsc"
17991 [(set (match_operand:DI 0 "register_operand" "=A")
17992 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17995 [(set_attr "type" "other")
17996 (set_attr "length" "2")])
17998 (define_insn "*rdtsc_rex64"
17999 [(set (match_operand:DI 0 "register_operand" "=a")
18000 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18001 (set (match_operand:DI 1 "register_operand" "=d")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18005 [(set_attr "type" "other")
18006 (set_attr "length" "2")])
18008 (define_expand "rdtscp"
18009 [(match_operand:DI 0 "register_operand" "")
18010 (match_operand:SI 1 "memory_operand" "")]
18013 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18014 gen_rtvec (1, const0_rtx),
18016 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18017 gen_rtvec (1, const0_rtx),
18019 rtx reg = gen_reg_rtx (DImode);
18020 rtx tmp = gen_reg_rtx (SImode);
18024 rtvec vec = rtvec_alloc (3);
18025 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18026 rtx upper = gen_reg_rtx (DImode);
18027 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18028 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18029 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18031 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18032 NULL, 1, OPTAB_DIRECT);
18033 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18038 rtvec vec = rtvec_alloc (2);
18039 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18040 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18041 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18044 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18045 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18049 (define_insn "*rdtscp"
18050 [(set (match_operand:DI 0 "register_operand" "=A")
18051 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18052 (set (match_operand:SI 1 "register_operand" "=c")
18053 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18056 [(set_attr "type" "other")
18057 (set_attr "length" "3")])
18059 (define_insn "*rdtscp_rex64"
18060 [(set (match_operand:DI 0 "register_operand" "=a")
18061 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18062 (set (match_operand:DI 1 "register_operand" "=d")
18063 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18064 (set (match_operand:SI 2 "register_operand" "=c")
18065 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18068 [(set_attr "type" "other")
18069 (set_attr "length" "3")])
18071 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18073 ;; LWP instructions
18075 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18077 (define_expand "lwp_llwpcb"
18078 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18079 UNSPECV_LLWP_INTRINSIC)]
18082 (define_insn "*lwp_llwpcb<mode>1"
18083 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18084 UNSPECV_LLWP_INTRINSIC)]
18087 [(set_attr "type" "lwp")
18088 (set_attr "mode" "<MODE>")
18089 (set_attr "length" "5")])
18091 (define_expand "lwp_slwpcb"
18092 [(set (match_operand 0 "register_operand" "=r")
18093 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18098 insn = (TARGET_64BIT
18100 : gen_lwp_slwpcbsi);
18102 emit_insn (insn (operands[0]));
18106 (define_insn "lwp_slwpcb<mode>"
18107 [(set (match_operand:P 0 "register_operand" "=r")
18108 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18111 [(set_attr "type" "lwp")
18112 (set_attr "mode" "<MODE>")
18113 (set_attr "length" "5")])
18115 (define_expand "lwp_lwpval<mode>3"
18116 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18117 (match_operand:SI 2 "nonimmediate_operand" "rm")
18118 (match_operand:SI 3 "const_int_operand" "i")]
18119 UNSPECV_LWPVAL_INTRINSIC)]
18121 ;; Avoid unused variable warning.
18122 "(void) operands[0];")
18124 (define_insn "*lwp_lwpval<mode>3_1"
18125 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18126 (match_operand:SI 1 "nonimmediate_operand" "rm")
18127 (match_operand:SI 2 "const_int_operand" "i")]
18128 UNSPECV_LWPVAL_INTRINSIC)]
18130 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18131 [(set_attr "type" "lwp")
18132 (set_attr "mode" "<MODE>")
18133 (set (attr "length")
18134 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18136 (define_expand "lwp_lwpins<mode>3"
18137 [(set (reg:CCC FLAGS_REG)
18138 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18139 (match_operand:SI 2 "nonimmediate_operand" "rm")
18140 (match_operand:SI 3 "const_int_operand" "i")]
18141 UNSPECV_LWPINS_INTRINSIC))
18142 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18143 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18146 (define_insn "*lwp_lwpins<mode>3_1"
18147 [(set (reg:CCC FLAGS_REG)
18148 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18149 (match_operand:SI 1 "nonimmediate_operand" "rm")
18150 (match_operand:SI 2 "const_int_operand" "i")]
18151 UNSPECV_LWPINS_INTRINSIC))]
18153 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18154 [(set_attr "type" "lwp")
18155 (set_attr "mode" "<MODE>")
18156 (set (attr "length")
18157 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18159 (define_insn "rdfsbase<mode>"
18160 [(set (match_operand:SWI48 0 "register_operand" "=r")
18161 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18162 "TARGET_64BIT && TARGET_FSGSBASE"
18164 [(set_attr "type" "other")
18165 (set_attr "prefix_extra" "2")])
18167 (define_insn "rdgsbase<mode>"
18168 [(set (match_operand:SWI48 0 "register_operand" "=r")
18169 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18170 "TARGET_64BIT && TARGET_FSGSBASE"
18172 [(set_attr "type" "other")
18173 (set_attr "prefix_extra" "2")])
18175 (define_insn "wrfsbase<mode>"
18176 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18178 "TARGET_64BIT && TARGET_FSGSBASE"
18180 [(set_attr "type" "other")
18181 (set_attr "prefix_extra" "2")])
18183 (define_insn "wrgsbase<mode>"
18184 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18186 "TARGET_64BIT && TARGET_FSGSBASE"
18188 [(set_attr "type" "other")
18189 (set_attr "prefix_extra" "2")])
18191 (define_insn "rdrand<mode>_1"
18192 [(set (match_operand:SWI248 0 "register_operand" "=r")
18193 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18194 (set (reg:CCC FLAGS_REG)
18195 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18198 [(set_attr "type" "other")
18199 (set_attr "prefix_extra" "1")])
18201 (define_expand "pause"
18202 [(set (match_dup 0)
18203 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18206 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18207 MEM_VOLATILE_P (operands[0]) = 1;
18210 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18211 ;; They have the same encoding.
18212 (define_insn "*pause"
18213 [(set (match_operand:BLK 0 "" "")
18214 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18217 [(set_attr "length" "2")
18218 (set_attr "memory" "unknown")])
18222 (include "sync.md")