1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2020 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
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 "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
144 UNSPEC_FRNDINT_ROUNDEVEN
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
188 UNSPEC_INTERRUPT_RETURN
191 (define_c_enum "unspecv" [
195 UNSPECV_PROBE_STACK_RANGE
198 UNSPECV_SPLIT_STACK_RETURN
204 UNSPECV_LLWP_INTRINSIC
205 UNSPECV_SLWP_INTRINSIC
206 UNSPECV_LWPVAL_INTRINSIC
207 UNSPECV_LWPINS_INTRINSIC
233 ;; For atomic compound assignments.
239 ;; For RDRAND support
242 ;; For RDSEED support
256 ;; For CLFLUSHOPT support
259 ;; For MONITORX and MWAITX support
263 ;; For CLZERO support
266 ;; For RDPKRU and WRPKRU support
283 ;; For MOVDIRI and MOVDIR64B support
287 ;; For WAITPKG support
292 ;; For CLDEMOTE support
295 ;; For Speculation Barrier support
296 UNSPECV_SPECULATION_BARRIER
300 ;; For ENQCMD and ENQCMDS support
305 ;; Constants to represent rounding modes in the ROUND instruction
307 [(ROUND_ROUNDEVEN 0x0)
315 ;; Constants to represent AVX512F embeded rounding
317 [(ROUND_NEAREST_INT 0)
325 ;; Constants to represent pcomtrue/pcomfalse variants
335 ;; Constants used in the XOP pperm instruction
337 [(PPERM_SRC 0x00) /* copy source */
338 (PPERM_INVERT 0x20) /* invert source */
339 (PPERM_REVERSE 0x40) /* bit reverse source */
340 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
341 (PPERM_ZERO 0x80) /* all 0's */
342 (PPERM_ONES 0xa0) /* all 1's */
343 (PPERM_SIGN 0xc0) /* propagate sign bit */
344 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
345 (PPERM_SRC1 0x00) /* use first source byte */
346 (PPERM_SRC2 0x10) /* use second source byte */
349 ;; Registers by name.
427 (FIRST_PSEUDO_REG 76)
430 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
433 ;; In C guard expressions, put expressions which may be compile-time
434 ;; constants first. This allows for better optimization. For
435 ;; example, write "TARGET_64BIT && reload_completed", not
436 ;; "reload_completed && TARGET_64BIT".
440 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
441 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
442 bdver4,btver2,znver1,znver2"
443 (const (symbol_ref "ix86_schedule")))
445 ;; A basic instruction type. Refinements due to arguments to be
446 ;; provided in other attributes.
449 alu,alu1,negnot,imov,imovx,lea,
450 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
451 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
452 push,pop,call,callv,leave,
454 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
455 fxch,fistp,fisttp,frndint,
456 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
457 ssemul,sseimul,ssediv,sselog,sselog1,
458 sseishft,sseishft1,ssecmp,ssecomi,
459 ssecvt,ssecvt1,sseicvt,sseins,
460 sseshuf,sseshuf1,ssemuladd,sse4arg,
462 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
463 (const_string "other"))
465 ;; Main data type used by the insn
467 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
469 (const_string "unknown"))
471 ;; The CPU unit operations uses.
472 (define_attr "unit" "integer,i387,sse,mmx,unknown"
473 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
474 fxch,fistp,fisttp,frndint")
475 (const_string "i387")
476 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
477 ssemul,sseimul,ssediv,sselog,sselog1,
478 sseishft,sseishft1,ssecmp,ssecomi,
479 ssecvt,ssecvt1,sseicvt,sseins,
480 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
482 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
484 (eq_attr "type" "other")
485 (const_string "unknown")]
486 (const_string "integer")))
488 ;; The (bounding maximum) length of an instruction immediate.
489 (define_attr "length_immediate" ""
490 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
491 bitmanip,imulx,msklog,mskmov")
493 (eq_attr "unit" "i387,sse,mmx")
495 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
496 rotate,rotatex,rotate1,imul,icmp,push,pop")
497 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
498 (eq_attr "type" "imov,test")
499 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
500 (eq_attr "type" "call")
501 (if_then_else (match_operand 0 "constant_call_address_operand")
504 (eq_attr "type" "callv")
505 (if_then_else (match_operand 1 "constant_call_address_operand")
508 ;; We don't know the size before shorten_branches. Expect
509 ;; the instruction to fit for better scheduling.
510 (eq_attr "type" "ibr")
513 (symbol_ref "/* Update immediate_length and other attributes! */
514 gcc_unreachable (),1")))
516 ;; The (bounding maximum) length of an instruction address.
517 (define_attr "length_address" ""
518 (cond [(eq_attr "type" "str,other,multi,fxch")
520 (and (eq_attr "type" "call")
521 (match_operand 0 "constant_call_address_operand"))
523 (and (eq_attr "type" "callv")
524 (match_operand 1 "constant_call_address_operand"))
527 (symbol_ref "ix86_attr_length_address_default (insn)")))
529 ;; Set when length prefix is used.
530 (define_attr "prefix_data16" ""
531 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
533 (eq_attr "mode" "HI")
535 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
540 ;; Set when string REP prefix is used.
541 (define_attr "prefix_rep" ""
542 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
544 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
553 (eq_attr "unit" "sse,mmx"))
557 ;; Set when REX opcode prefix is used.
558 (define_attr "prefix_rex" ""
559 (cond [(not (match_test "TARGET_64BIT"))
561 (and (eq_attr "mode" "DI")
562 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
563 (eq_attr "unit" "!mmx")))
565 (and (eq_attr "mode" "QI")
566 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
568 (match_test "x86_extended_reg_mentioned_p (insn)")
570 (and (eq_attr "type" "imovx")
571 (match_operand:QI 1 "ext_QIreg_operand"))
576 ;; There are also additional prefixes in 3DNOW, SSSE3.
577 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
578 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
579 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
580 (define_attr "prefix_extra" ""
581 (cond [(eq_attr "type" "ssemuladd,sse4arg")
583 (eq_attr "type" "sseiadd1,ssecvt1")
588 ;; Prefix used: original, VEX or maybe VEX.
589 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
590 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
592 (eq_attr "mode" "XI,V16SF,V8DF")
593 (const_string "evex")
595 (const_string "orig")))
597 ;; VEX W bit is used.
598 (define_attr "prefix_vex_w" "" (const_int 0))
600 ;; The length of VEX prefix
601 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
602 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
603 ;; still prefix_0f 1, with prefix_extra 1.
604 (define_attr "length_vex" ""
605 (if_then_else (and (eq_attr "prefix_0f" "1")
606 (eq_attr "prefix_extra" "0"))
607 (if_then_else (eq_attr "prefix_vex_w" "1")
608 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
609 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
610 (if_then_else (eq_attr "prefix_vex_w" "1")
611 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
612 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
614 ;; 4-bytes evex prefix and 1 byte opcode.
615 (define_attr "length_evex" "" (const_int 5))
617 ;; Set when modrm byte is used.
618 (define_attr "modrm" ""
619 (cond [(eq_attr "type" "str,leave")
621 (eq_attr "unit" "i387")
623 (and (eq_attr "type" "incdec")
624 (and (not (match_test "TARGET_64BIT"))
625 (ior (match_operand:SI 1 "register_operand")
626 (match_operand:HI 1 "register_operand"))))
628 (and (eq_attr "type" "push")
629 (not (match_operand 1 "memory_operand")))
631 (and (eq_attr "type" "pop")
632 (not (match_operand 0 "memory_operand")))
634 (and (eq_attr "type" "imov")
635 (and (not (eq_attr "mode" "DI"))
636 (ior (and (match_operand 0 "register_operand")
637 (match_operand 1 "immediate_operand"))
638 (ior (and (match_operand 0 "ax_reg_operand")
639 (match_operand 1 "memory_displacement_only_operand"))
640 (and (match_operand 0 "memory_displacement_only_operand")
641 (match_operand 1 "ax_reg_operand"))))))
643 (and (eq_attr "type" "call")
644 (match_operand 0 "constant_call_address_operand"))
646 (and (eq_attr "type" "callv")
647 (match_operand 1 "constant_call_address_operand"))
649 (and (eq_attr "type" "alu,alu1,icmp,test")
650 (match_operand 0 "ax_reg_operand"))
651 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
655 ;; The (bounding maximum) length of an instruction in bytes.
656 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
657 ;; Later we may want to split them and compute proper length as for
659 (define_attr "length" ""
660 (cond [(eq_attr "type" "other,multi,fistp,frndint")
662 (eq_attr "type" "fcmp")
664 (eq_attr "unit" "i387")
666 (plus (attr "prefix_data16")
667 (attr "length_address")))
668 (ior (eq_attr "prefix" "evex")
669 (and (ior (eq_attr "prefix" "maybe_evex")
670 (eq_attr "prefix" "maybe_vex"))
671 (match_test "TARGET_AVX512F")))
672 (plus (attr "length_evex")
673 (plus (attr "length_immediate")
675 (attr "length_address"))))
676 (ior (eq_attr "prefix" "vex")
677 (and (ior (eq_attr "prefix" "maybe_vex")
678 (eq_attr "prefix" "maybe_evex"))
679 (match_test "TARGET_AVX")))
680 (plus (attr "length_vex")
681 (plus (attr "length_immediate")
683 (attr "length_address"))))]
684 (plus (plus (attr "modrm")
685 (plus (attr "prefix_0f")
686 (plus (attr "prefix_rex")
687 (plus (attr "prefix_extra")
689 (plus (attr "prefix_rep")
690 (plus (attr "prefix_data16")
691 (plus (attr "length_immediate")
692 (attr "length_address")))))))
694 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
695 ;; `store' if there is a simple memory reference therein, or `unknown'
696 ;; if the instruction is complex.
698 (define_attr "memory" "none,load,store,both,unknown"
699 (cond [(eq_attr "type" "other,multi,str,lwp")
700 (const_string "unknown")
701 (eq_attr "type" "lea,fcmov,fpspc")
702 (const_string "none")
703 (eq_attr "type" "fistp,leave")
704 (const_string "both")
705 (eq_attr "type" "frndint")
706 (const_string "load")
707 (eq_attr "type" "push")
708 (if_then_else (match_operand 1 "memory_operand")
709 (const_string "both")
710 (const_string "store"))
711 (eq_attr "type" "pop")
712 (if_then_else (match_operand 0 "memory_operand")
713 (const_string "both")
714 (const_string "load"))
715 (eq_attr "type" "setcc")
716 (if_then_else (match_operand 0 "memory_operand")
717 (const_string "store")
718 (const_string "none"))
719 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
720 (if_then_else (ior (match_operand 0 "memory_operand")
721 (match_operand 1 "memory_operand"))
722 (const_string "load")
723 (const_string "none"))
724 (eq_attr "type" "ibr")
725 (if_then_else (match_operand 0 "memory_operand")
726 (const_string "load")
727 (const_string "none"))
728 (eq_attr "type" "call")
729 (if_then_else (match_operand 0 "constant_call_address_operand")
730 (const_string "none")
731 (const_string "load"))
732 (eq_attr "type" "callv")
733 (if_then_else (match_operand 1 "constant_call_address_operand")
734 (const_string "none")
735 (const_string "load"))
736 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
737 (match_operand 1 "memory_operand"))
738 (const_string "both")
739 (and (match_operand 0 "memory_operand")
740 (match_operand 1 "memory_operand"))
741 (const_string "both")
742 (match_operand 0 "memory_operand")
743 (const_string "store")
744 (match_operand 1 "memory_operand")
745 (const_string "load")
747 "!alu1,negnot,ishift1,rotate1,
748 imov,imovx,icmp,test,bitmanip,
750 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
751 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
752 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
753 (match_operand 2 "memory_operand"))
754 (const_string "load")
755 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
756 (match_operand 3 "memory_operand"))
757 (const_string "load")
759 (const_string "none")))
761 ;; Indicates if an instruction has both an immediate and a displacement.
763 (define_attr "imm_disp" "false,true,unknown"
764 (cond [(eq_attr "type" "other,multi")
765 (const_string "unknown")
766 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
767 (and (match_operand 0 "memory_displacement_operand")
768 (match_operand 1 "immediate_operand")))
769 (const_string "true")
770 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
771 (and (match_operand 0 "memory_displacement_operand")
772 (match_operand 2 "immediate_operand")))
773 (const_string "true")
775 (const_string "false")))
777 ;; Indicates if an FP operation has an integer source.
779 (define_attr "fp_int_src" "false,true"
780 (const_string "false"))
782 ;; Defines rounding mode of an FP operation.
784 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
785 (const_string "any"))
787 ;; Define attribute to indicate AVX insns with partial XMM register update.
788 (define_attr "avx_partial_xmm_update" "false,true"
789 (const_string "false"))
791 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
792 (define_attr "use_carry" "0,1" (const_string "0"))
794 ;; Define attribute to indicate unaligned ssemov insns
795 (define_attr "movu" "0,1" (const_string "0"))
797 ;; Used to control the "enabled" attribute on a per-instruction basis.
798 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
799 sse_noavx,sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
800 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
801 avx512bw,noavx512bw,avx512dq,noavx512dq,
802 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
803 (const_string "base"))
805 ;; Define instruction set of MMX instructions
806 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
807 (const_string "base"))
809 (define_attr "enabled" ""
810 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
811 (eq_attr "isa" "x64_sse2")
812 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
813 (eq_attr "isa" "x64_sse4")
814 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
815 (eq_attr "isa" "x64_sse4_noavx")
816 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
817 (eq_attr "isa" "x64_avx")
818 (symbol_ref "TARGET_64BIT && TARGET_AVX")
819 (eq_attr "isa" "x64_avx512dq")
820 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
821 (eq_attr "isa" "x64_avx512bw")
822 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
823 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
824 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
825 (eq_attr "isa" "sse_noavx")
826 (symbol_ref "TARGET_SSE && !TARGET_AVX")
827 (eq_attr "isa" "sse2_noavx")
828 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
829 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
830 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
831 (eq_attr "isa" "sse4_noavx")
832 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
833 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
834 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
835 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
836 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
837 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
838 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
839 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
840 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
841 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
842 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
843 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
844 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
845 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
846 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
847 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
848 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
850 (eq_attr "mmx_isa" "native")
851 (symbol_ref "!TARGET_MMX_WITH_SSE")
852 (eq_attr "mmx_isa" "sse")
853 (symbol_ref "TARGET_MMX_WITH_SSE")
854 (eq_attr "mmx_isa" "sse_noavx")
855 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
856 (eq_attr "mmx_isa" "avx")
857 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
861 (define_attr "preferred_for_size" "" (const_int 1))
862 (define_attr "preferred_for_speed" "" (const_int 1))
864 ;; Describe a user's asm statement.
865 (define_asm_attributes
866 [(set_attr "length" "128")
867 (set_attr "type" "multi")])
869 (define_code_iterator plusminus [plus minus])
871 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
873 (define_code_iterator multdiv [mult div])
875 ;; Base name for define_insn
876 (define_code_attr plusminus_insn
877 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
878 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
880 ;; Base name for insn mnemonic.
881 (define_code_attr plusminus_mnemonic
882 [(plus "add") (ss_plus "adds") (us_plus "addus")
883 (minus "sub") (ss_minus "subs") (us_minus "subus")])
884 (define_code_attr multdiv_mnemonic
885 [(mult "mul") (div "div")])
887 ;; Mark commutative operators as such in constraints.
888 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
889 (minus "") (ss_minus "") (us_minus "")])
891 ;; Mapping of max and min
892 (define_code_iterator maxmin [smax smin umax umin])
894 ;; Mapping of signed max and min
895 (define_code_iterator smaxmin [smax smin])
897 ;; Mapping of unsigned max and min
898 (define_code_iterator umaxmin [umax umin])
900 ;; Base name for integer and FP insn mnemonic
901 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
902 (umax "maxu") (umin "minu")])
903 (define_code_attr maxmin_float [(smax "max") (smin "min")])
905 (define_int_iterator IEEE_MAXMIN
909 (define_int_attr ieee_maxmin
910 [(UNSPEC_IEEE_MAX "max")
911 (UNSPEC_IEEE_MIN "min")])
913 ;; Mapping of logic operators
914 (define_code_iterator any_logic [and ior xor])
915 (define_code_iterator any_or [ior xor])
916 (define_code_iterator fpint_logic [and xor])
918 ;; Base name for insn mnemonic.
919 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
921 ;; Mapping of logic-shift operators
922 (define_code_iterator any_lshift [ashift lshiftrt])
924 ;; Mapping of shift-right operators
925 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
927 ;; Mapping of all shift operators
928 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
930 ;; Base name for define_insn
931 (define_code_attr shift_insn
932 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
934 ;; Base name for insn mnemonic.
935 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
936 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
938 ;; Mapping of rotate operators
939 (define_code_iterator any_rotate [rotate rotatert])
941 ;; Base name for define_insn
942 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
944 ;; Base name for insn mnemonic.
945 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
947 ;; Mapping of abs neg operators
948 (define_code_iterator absneg [abs neg])
950 ;; Base name for x87 insn mnemonic.
951 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
953 ;; Used in signed and unsigned widening multiplications.
954 (define_code_iterator any_extend [sign_extend zero_extend])
956 ;; Prefix for insn menmonic.
957 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
958 (div "i") (udiv "")])
959 ;; Prefix for define_insn
960 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
961 (define_code_attr u [(sign_extend "") (zero_extend "u")
962 (div "") (udiv "u")])
963 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
964 (div "false") (udiv "true")])
966 ;; Used in signed and unsigned truncations.
967 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
968 ;; Instruction suffix for truncations.
969 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
971 ;; Used in signed and unsigned fix.
972 (define_code_iterator any_fix [fix unsigned_fix])
973 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
974 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
975 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
977 ;; Used in signed and unsigned float.
978 (define_code_iterator any_float [float unsigned_float])
979 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
980 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
981 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
983 ;; All integer modes.
984 (define_mode_iterator SWI1248x [QI HI SI DI])
986 ;; All integer modes without QImode.
987 (define_mode_iterator SWI248x [HI SI DI])
989 ;; All integer modes without QImode and HImode.
990 (define_mode_iterator SWI48x [SI DI])
992 ;; All integer modes without SImode and DImode.
993 (define_mode_iterator SWI12 [QI HI])
995 ;; All integer modes without DImode.
996 (define_mode_iterator SWI124 [QI HI SI])
998 ;; All integer modes without QImode and DImode.
999 (define_mode_iterator SWI24 [HI SI])
1001 ;; Single word integer modes.
1002 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1004 ;; Single word integer modes without QImode.
1005 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1007 ;; Single word integer modes without QImode and HImode.
1008 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1010 ;; All math-dependant single and double word integer modes.
1011 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1012 (HI "TARGET_HIMODE_MATH")
1013 SI DI (TI "TARGET_64BIT")])
1015 ;; Math-dependant single word integer modes.
1016 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1017 (HI "TARGET_HIMODE_MATH")
1018 SI (DI "TARGET_64BIT")])
1020 ;; Math-dependant integer modes without DImode.
1021 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1022 (HI "TARGET_HIMODE_MATH")
1025 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1026 (define_mode_iterator SWIM1248s
1027 [(QI "TARGET_QIMODE_MATH")
1028 (HI "TARGET_HIMODE_MATH")
1029 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1031 ;; Math-dependant single word integer modes without QImode.
1032 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1033 SI (DI "TARGET_64BIT")])
1035 ;; Double word integer modes.
1036 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1037 (TI "TARGET_64BIT")])
1039 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1040 ;; compile time constant, it is faster to use <MODE_SIZE> than
1041 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1042 ;; command line options just use GET_MODE_SIZE macro.
1043 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1044 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1045 (V16QI "16") (V32QI "32") (V64QI "64")
1046 (V8HI "16") (V16HI "32") (V32HI "64")
1047 (V4SI "16") (V8SI "32") (V16SI "64")
1048 (V2DI "16") (V4DI "32") (V8DI "64")
1049 (V1TI "16") (V2TI "32") (V4TI "64")
1050 (V2DF "16") (V4DF "32") (V8DF "64")
1051 (V4SF "16") (V8SF "32") (V16SF "64")])
1053 ;; Double word integer modes as mode attribute.
1054 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1055 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1057 ;; LEA mode corresponding to an integer mode
1058 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1060 ;; Half mode for double word integer modes.
1061 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1062 (DI "TARGET_64BIT")])
1064 ;; Instruction suffix for integer modes.
1065 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1067 ;; Instruction suffix for masks.
1068 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1070 ;; Pointer size prefix for integer modes (Intel asm dialect)
1071 (define_mode_attr iptrsize [(QI "BYTE")
1076 ;; Register class for integer modes.
1077 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1079 ;; Immediate operand constraint for integer modes.
1080 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1082 ;; General operand constraint for word modes.
1083 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1085 ;; Immediate operand constraint for double integer modes.
1086 (define_mode_attr di [(SI "nF") (DI "Wd")])
1088 ;; Immediate operand constraint for shifts.
1089 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1091 ;; Print register name in the specified mode.
1092 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1094 ;; General operand predicate for integer modes.
1095 (define_mode_attr general_operand
1096 [(QI "general_operand")
1097 (HI "general_operand")
1098 (SI "x86_64_general_operand")
1099 (DI "x86_64_general_operand")
1100 (TI "x86_64_general_operand")])
1102 ;; General operand predicate for integer modes, where for TImode
1103 ;; we need both words of the operand to be general operands.
1104 (define_mode_attr general_hilo_operand
1105 [(QI "general_operand")
1106 (HI "general_operand")
1107 (SI "x86_64_general_operand")
1108 (DI "x86_64_general_operand")
1109 (TI "x86_64_hilo_general_operand")])
1111 ;; General sign extend operand predicate for integer modes,
1112 ;; which disallows VOIDmode operands and thus it is suitable
1113 ;; for use inside sign_extend.
1114 (define_mode_attr general_sext_operand
1115 [(QI "sext_operand")
1117 (SI "x86_64_sext_operand")
1118 (DI "x86_64_sext_operand")])
1120 ;; General sign/zero extend operand predicate for integer modes.
1121 (define_mode_attr general_szext_operand
1122 [(QI "general_operand")
1123 (HI "general_operand")
1124 (SI "x86_64_szext_general_operand")
1125 (DI "x86_64_szext_general_operand")])
1127 (define_mode_attr nonmemory_szext_operand
1128 [(QI "nonmemory_operand")
1129 (HI "nonmemory_operand")
1130 (SI "x86_64_szext_nonmemory_operand")
1131 (DI "x86_64_szext_nonmemory_operand")])
1133 ;; Immediate operand predicate for integer modes.
1134 (define_mode_attr immediate_operand
1135 [(QI "immediate_operand")
1136 (HI "immediate_operand")
1137 (SI "x86_64_immediate_operand")
1138 (DI "x86_64_immediate_operand")])
1140 ;; Nonmemory operand predicate for integer modes.
1141 (define_mode_attr nonmemory_operand
1142 [(QI "nonmemory_operand")
1143 (HI "nonmemory_operand")
1144 (SI "x86_64_nonmemory_operand")
1145 (DI "x86_64_nonmemory_operand")])
1147 ;; Operand predicate for shifts.
1148 (define_mode_attr shift_operand
1149 [(QI "nonimmediate_operand")
1150 (HI "nonimmediate_operand")
1151 (SI "nonimmediate_operand")
1152 (DI "shiftdi_operand")
1153 (TI "register_operand")])
1155 ;; Operand predicate for shift argument.
1156 (define_mode_attr shift_immediate_operand
1157 [(QI "const_1_to_31_operand")
1158 (HI "const_1_to_31_operand")
1159 (SI "const_1_to_31_operand")
1160 (DI "const_1_to_63_operand")])
1162 ;; Input operand predicate for arithmetic left shifts.
1163 (define_mode_attr ashl_input_operand
1164 [(QI "nonimmediate_operand")
1165 (HI "nonimmediate_operand")
1166 (SI "nonimmediate_operand")
1167 (DI "ashldi_input_operand")
1168 (TI "reg_or_pm1_operand")])
1170 ;; SSE and x87 SFmode and DFmode floating point modes
1171 (define_mode_iterator MODEF [SF DF])
1173 ;; All x87 floating point modes
1174 (define_mode_iterator X87MODEF [SF DF XF])
1176 ;; All SSE floating point modes
1177 (define_mode_iterator SSEMODEF [SF DF TF])
1178 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182 [(SF "ss") (DF "sd")
1183 (V16SF "ps") (V8DF "pd")
1184 (V8SF "ps") (V4DF "pd")
1185 (V4SF "ps") (V2DF "pd")
1186 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1205 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1207 ;; This mode iterator allows :P to be used for patterns that operate on
1208 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1209 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1211 ;; This mode iterator allows :W to be used for patterns that operate on
1212 ;; word_mode sized quantities.
1213 (define_mode_iterator W
1214 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1216 ;; This mode iterator allows :PTR to be used for patterns that operate on
1217 ;; ptr_mode sized quantities.
1218 (define_mode_iterator PTR
1219 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1221 ;; Scheduling descriptions
1223 (include "pentium.md")
1226 (include "athlon.md")
1227 (include "bdver1.md")
1228 (include "bdver3.md")
1229 (include "btver2.md")
1230 (include "znver1.md")
1231 (include "geode.md")
1235 (include "core2.md")
1236 (include "haswell.md")
1239 ;; Operand and operator predicates and constraints
1241 (include "predicates.md")
1242 (include "constraints.md")
1245 ;; Compare and branch/compare and store instructions.
1247 (define_expand "cbranch<mode>4"
1248 [(set (reg:CC FLAGS_REG)
1249 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1250 (match_operand:SDWIM 2 "<general_operand>")))
1251 (set (pc) (if_then_else
1252 (match_operator 0 "ordered_comparison_operator"
1253 [(reg:CC FLAGS_REG) (const_int 0)])
1254 (label_ref (match_operand 3))
1258 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1259 operands[1] = force_reg (<MODE>mode, operands[1]);
1260 ix86_expand_branch (GET_CODE (operands[0]),
1261 operands[1], operands[2], operands[3]);
1265 (define_expand "cstore<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1268 (match_operand:SWIM 3 "<general_operand>")))
1269 (set (match_operand:QI 0 "register_operand")
1270 (match_operator 1 "ordered_comparison_operator"
1271 [(reg:CC FLAGS_REG) (const_int 0)]))]
1274 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1275 operands[2] = force_reg (<MODE>mode, operands[2]);
1276 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1277 operands[2], operands[3]);
1281 (define_expand "@cmp<mode>_1"
1282 [(set (reg:CC FLAGS_REG)
1283 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1284 (match_operand:SWI48 1 "<general_operand>")))])
1286 (define_mode_iterator SWI1248_AVX512BWDQ_64
1287 [(QI "TARGET_AVX512DQ") HI
1288 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1290 (define_insn "*cmp<mode>_ccz_1"
1291 [(set (reg FLAGS_REG)
1292 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1293 "nonimmediate_operand" "<r>,?m<r>,$k")
1294 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1295 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1297 test{<imodesuffix>}\t%0, %0
1298 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1299 kortest<mskmodesuffix>\t%0, %0"
1300 [(set_attr "type" "test,icmp,msklog")
1301 (set_attr "length_immediate" "0,1,*")
1302 (set_attr "prefix" "*,*,vex")
1303 (set_attr "mode" "<MODE>")])
1305 (define_insn "*cmp<mode>_ccno_1"
1306 [(set (reg FLAGS_REG)
1307 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1308 (match_operand:SWI 1 "const0_operand")))]
1309 "ix86_match_ccmode (insn, CCNOmode)"
1311 test{<imodesuffix>}\t%0, %0
1312 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "test,icmp")
1314 (set_attr "length_immediate" "0,1")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmp<mode>_1"
1318 [(set (reg FLAGS_REG)
1319 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1320 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1321 "ix86_match_ccmode (insn, CCmode)"
1322 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1323 [(set_attr "type" "icmp")
1324 (set_attr "mode" "<MODE>")])
1326 (define_insn "*cmp<mode>_minus_1"
1327 [(set (reg FLAGS_REG)
1329 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1330 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1332 "ix86_match_ccmode (insn, CCGOCmode)"
1333 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1334 [(set_attr "type" "icmp")
1335 (set_attr "mode" "<MODE>")])
1337 (define_insn "*cmpqi_ext_1"
1338 [(set (reg FLAGS_REG)
1340 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1343 (match_operand 1 "ext_register_operand" "Q,Q")
1345 (const_int 8)) 0)))]
1346 "ix86_match_ccmode (insn, CCmode)"
1347 "cmp{b}\t{%h1, %0|%0, %h1}"
1348 [(set_attr "isa" "*,nox64")
1349 (set_attr "type" "icmp")
1350 (set_attr "mode" "QI")])
1352 (define_insn "*cmpqi_ext_2"
1353 [(set (reg FLAGS_REG)
1357 (match_operand 0 "ext_register_operand" "Q")
1360 (match_operand:QI 1 "const0_operand")))]
1361 "ix86_match_ccmode (insn, CCNOmode)"
1363 [(set_attr "type" "test")
1364 (set_attr "length_immediate" "0")
1365 (set_attr "mode" "QI")])
1367 (define_expand "cmpqi_ext_3"
1368 [(set (reg:CC FLAGS_REG)
1372 (match_operand 0 "ext_register_operand")
1375 (match_operand:QI 1 "const_int_operand")))])
1377 (define_insn "*cmpqi_ext_3"
1378 [(set (reg FLAGS_REG)
1382 (match_operand 0 "ext_register_operand" "Q,Q")
1385 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1386 "ix86_match_ccmode (insn, CCmode)"
1387 "cmp{b}\t{%1, %h0|%h0, %1}"
1388 [(set_attr "isa" "*,nox64")
1389 (set_attr "type" "icmp")
1390 (set_attr "mode" "QI")])
1392 (define_insn "*cmpqi_ext_4"
1393 [(set (reg FLAGS_REG)
1397 (match_operand 0 "ext_register_operand" "Q")
1402 (match_operand 1 "ext_register_operand" "Q")
1404 (const_int 8)) 0)))]
1405 "ix86_match_ccmode (insn, CCmode)"
1406 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1407 [(set_attr "type" "icmp")
1408 (set_attr "mode" "QI")])
1410 ;; These implement float point compares.
1411 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1412 ;; which would allow mix and match FP modes on the compares. Which is what
1413 ;; the old patterns did, but with many more of them.
1415 (define_expand "cbranchxf4"
1416 [(set (reg:CC FLAGS_REG)
1417 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1418 (match_operand:XF 2 "nonmemory_operand")))
1419 (set (pc) (if_then_else
1420 (match_operator 0 "ix86_fp_comparison_operator"
1423 (label_ref (match_operand 3))
1427 ix86_expand_branch (GET_CODE (operands[0]),
1428 operands[1], operands[2], operands[3]);
1432 (define_expand "cstorexf4"
1433 [(set (reg:CC FLAGS_REG)
1434 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1435 (match_operand:XF 3 "nonmemory_operand")))
1436 (set (match_operand:QI 0 "register_operand")
1437 (match_operator 1 "ix86_fp_comparison_operator"
1442 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1443 operands[2], operands[3]);
1447 (define_expand "cbranch<mode>4"
1448 [(set (reg:CC FLAGS_REG)
1449 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1450 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1451 (set (pc) (if_then_else
1452 (match_operator 0 "ix86_fp_comparison_operator"
1455 (label_ref (match_operand 3))
1457 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1459 ix86_expand_branch (GET_CODE (operands[0]),
1460 operands[1], operands[2], operands[3]);
1464 (define_expand "cstore<mode>4"
1465 [(set (reg:CC FLAGS_REG)
1466 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1467 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1468 (set (match_operand:QI 0 "register_operand")
1469 (match_operator 1 "ix86_fp_comparison_operator"
1472 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1474 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1475 operands[2], operands[3]);
1479 (define_expand "cbranchcc4"
1480 [(set (pc) (if_then_else
1481 (match_operator 0 "comparison_operator"
1482 [(match_operand 1 "flags_reg_operand")
1483 (match_operand 2 "const0_operand")])
1484 (label_ref (match_operand 3))
1488 ix86_expand_branch (GET_CODE (operands[0]),
1489 operands[1], operands[2], operands[3]);
1493 (define_expand "cstorecc4"
1494 [(set (match_operand:QI 0 "register_operand")
1495 (match_operator 1 "comparison_operator"
1496 [(match_operand 2 "flags_reg_operand")
1497 (match_operand 3 "const0_operand")]))]
1500 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1501 operands[2], operands[3]);
1505 ;; FP compares, step 1:
1506 ;; Set the FP condition codes and move fpsr to ax.
1508 ;; We may not use "#" to split and emit these
1509 ;; due to reg-stack pops killing fpsr.
1511 (define_insn "*cmpxf_i387"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1515 (match_operand:XF 1 "register_operand" "f")
1516 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1519 "* return output_fp_compare (insn, operands, false, false);"
1520 [(set_attr "type" "multi")
1521 (set_attr "unit" "i387")
1522 (set_attr "mode" "XF")])
1524 (define_insn "*cmp<mode>_i387"
1525 [(set (match_operand:HI 0 "register_operand" "=a")
1528 (match_operand:MODEF 1 "register_operand" "f")
1529 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1532 "* return output_fp_compare (insn, operands, false, false);"
1533 [(set_attr "type" "multi")
1534 (set_attr "unit" "i387")
1535 (set_attr "mode" "<MODE>")])
1537 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1538 [(set (match_operand:HI 0 "register_operand" "=a")
1541 (match_operand:X87MODEF 1 "register_operand" "f")
1543 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1546 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1547 || optimize_function_for_size_p (cfun))"
1548 "* return output_fp_compare (insn, operands, false, false);"
1549 [(set_attr "type" "multi")
1550 (set_attr "unit" "i387")
1551 (set_attr "fp_int_src" "true")
1552 (set_attr "mode" "<SWI24:MODE>")])
1554 (define_insn "*cmpu<mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1559 (match_operand:X87MODEF 1 "register_operand" "f")
1560 (match_operand:X87MODEF 2 "register_operand" "f"))]
1564 "* return output_fp_compare (insn, operands, false, true);"
1565 [(set_attr "type" "multi")
1566 (set_attr "unit" "i387")
1567 (set_attr "mode" "<MODE>")])
1569 ;; FP compares, step 2:
1570 ;; Get ax into flags, general case.
1572 (define_insn "x86_sahf_1"
1573 [(set (reg:CC FLAGS_REG)
1574 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1578 #ifndef HAVE_AS_IX86_SAHF
1580 return ASM_BYTE "0x9e";
1585 [(set_attr "length" "1")
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")
1588 (set_attr "bdver1_decode" "direct")
1589 (set_attr "mode" "SI")])
1591 ;; Pentium Pro can do both steps in one go.
1592 ;; (these instructions set flags directly)
1594 (define_subst_attr "unord" "unord_subst" "" "u")
1595 (define_subst_attr "unordered" "unord_subst" "false" "true")
1597 (define_subst "unord_subst"
1598 [(set (match_operand:CCFP 0)
1599 (match_operand:CCFP 1))]
1606 (define_insn "*cmpi<unord>xf_i387"
1607 [(set (reg:CCFP FLAGS_REG)
1609 (match_operand:XF 0 "register_operand" "f")
1610 (match_operand:XF 1 "register_operand" "f")))]
1611 "TARGET_80387 && TARGET_CMOVE"
1612 "* return output_fp_compare (insn, operands, true, <unordered>);"
1613 [(set_attr "type" "fcmp")
1614 (set_attr "mode" "XF")
1615 (set_attr "athlon_decode" "vector")
1616 (set_attr "amdfam10_decode" "direct")
1617 (set_attr "bdver1_decode" "double")
1618 (set_attr "znver1_decode" "double")])
1620 (define_insn "*cmpi<unord><MODEF:mode>"
1621 [(set (reg:CCFP FLAGS_REG)
1623 (match_operand:MODEF 0 "register_operand" "f,v")
1624 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1625 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1626 || (TARGET_80387 && TARGET_CMOVE)"
1628 * return output_fp_compare (insn, operands, true, <unordered>);
1629 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1630 [(set_attr "type" "fcmp,ssecomi")
1631 (set_attr "prefix" "orig,maybe_vex")
1632 (set_attr "mode" "<MODEF:MODE>")
1633 (set_attr "prefix_rep" "*,0")
1634 (set (attr "prefix_data16")
1635 (cond [(eq_attr "alternative" "0")
1637 (eq_attr "mode" "DF")
1640 (const_string "0")))
1641 (set_attr "athlon_decode" "vector")
1642 (set_attr "amdfam10_decode" "direct")
1643 (set_attr "bdver1_decode" "double")
1644 (set_attr "znver1_decode" "double")
1645 (set (attr "enabled")
1647 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1649 (eq_attr "alternative" "0")
1650 (symbol_ref "TARGET_MIX_SSE_I387")
1651 (symbol_ref "true"))
1653 (eq_attr "alternative" "0")
1655 (symbol_ref "false"))))])
1657 ;; Push/pop instructions.
1659 (define_insn "*push<mode>2"
1660 [(set (match_operand:DWI 0 "push_operand" "=<")
1661 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1664 [(set_attr "type" "multi")
1665 (set_attr "mode" "<MODE>")])
1668 [(set (match_operand:DWI 0 "push_operand")
1669 (match_operand:DWI 1 "general_gr_operand"))]
1672 "ix86_split_long_move (operands); DONE;")
1674 (define_insn "*pushdi2_rex64"
1675 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1676 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1681 [(set_attr "type" "push,multi")
1682 (set_attr "mode" "DI")])
1684 ;; Convert impossible pushes of immediate to existing instructions.
1685 ;; First try to get scratch register and go through it. In case this
1686 ;; fails, push sign extended lower part first and then overwrite
1687 ;; upper part by 32bit move.
1689 [(match_scratch:DI 2 "r")
1690 (set (match_operand:DI 0 "push_operand")
1691 (match_operand:DI 1 "immediate_operand"))]
1692 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1693 && !x86_64_immediate_operand (operands[1], DImode)"
1694 [(set (match_dup 2) (match_dup 1))
1695 (set (match_dup 0) (match_dup 2))])
1697 ;; We need to define this as both peepholer and splitter for case
1698 ;; peephole2 pass is not run.
1699 ;; "&& 1" is needed to keep it from matching the previous pattern.
1701 [(set (match_operand:DI 0 "push_operand")
1702 (match_operand:DI 1 "immediate_operand"))]
1703 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1704 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1705 [(set (match_dup 0) (match_dup 1))
1706 (set (match_dup 2) (match_dup 3))]
1708 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710 operands[1] = gen_lowpart (DImode, operands[2]);
1711 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1716 [(set (match_operand:DI 0 "push_operand")
1717 (match_operand:DI 1 "immediate_operand"))]
1718 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1719 ? epilogue_completed : reload_completed)
1720 && !symbolic_operand (operands[1], DImode)
1721 && !x86_64_immediate_operand (operands[1], DImode)"
1722 [(set (match_dup 0) (match_dup 1))
1723 (set (match_dup 2) (match_dup 3))]
1725 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1727 operands[1] = gen_lowpart (DImode, operands[2]);
1728 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1732 (define_insn "*pushsi2"
1733 [(set (match_operand:SI 0 "push_operand" "=<")
1734 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1737 [(set_attr "type" "push")
1738 (set_attr "mode" "SI")])
1740 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1741 ;; "push a byte/word". But actually we use pushl, which has the effect
1742 ;; of rounding the amount pushed up to a word.
1744 ;; For TARGET_64BIT we always round up to 8 bytes.
1745 (define_insn "*push<mode>2_rex64"
1746 [(set (match_operand:SWI124 0 "push_operand" "=X")
1747 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "DI")])
1753 (define_insn "*push<mode>2"
1754 [(set (match_operand:SWI12 0 "push_operand" "=X")
1755 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1758 [(set_attr "type" "push")
1759 (set_attr "mode" "SI")])
1761 (define_insn "*push<mode>2_prologue"
1762 [(set (match_operand:W 0 "push_operand" "=<")
1763 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1764 (clobber (mem:BLK (scratch)))]
1766 "push{<imodesuffix>}\t%1"
1767 [(set_attr "type" "push")
1768 (set_attr "mode" "<MODE>")])
1770 (define_insn "*pop<mode>1"
1771 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:W 1 "pop_operand" ">"))]
1774 "pop{<imodesuffix>}\t%0"
1775 [(set_attr "type" "pop")
1776 (set_attr "mode" "<MODE>")])
1778 (define_insn "*pop<mode>1_epilogue"
1779 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1780 (match_operand:W 1 "pop_operand" ">"))
1781 (clobber (mem:BLK (scratch)))]
1783 "pop{<imodesuffix>}\t%0"
1784 [(set_attr "type" "pop")
1785 (set_attr "mode" "<MODE>")])
1787 (define_insn "*pushfl<mode>2"
1788 [(set (match_operand:W 0 "push_operand" "=<")
1789 (match_operand:W 1 "flags_reg_operand"))]
1791 "pushf{<imodesuffix>}"
1792 [(set_attr "type" "push")
1793 (set_attr "mode" "<MODE>")])
1795 (define_insn "*popfl<mode>1"
1796 [(set (match_operand:W 0 "flags_reg_operand")
1797 (match_operand:W 1 "pop_operand" ">"))]
1799 "popf{<imodesuffix>}"
1800 [(set_attr "type" "pop")
1801 (set_attr "mode" "<MODE>")])
1804 ;; Reload patterns to support multi-word load/store
1805 ;; with non-offsetable address.
1806 (define_expand "reload_noff_store"
1807 [(parallel [(match_operand 0 "memory_operand" "=m")
1808 (match_operand 1 "register_operand" "r")
1809 (match_operand:DI 2 "register_operand" "=&r")])]
1812 rtx mem = operands[0];
1813 rtx addr = XEXP (mem, 0);
1815 emit_move_insn (operands[2], addr);
1816 mem = replace_equiv_address_nv (mem, operands[2]);
1818 emit_insn (gen_rtx_SET (mem, operands[1]));
1822 (define_expand "reload_noff_load"
1823 [(parallel [(match_operand 0 "register_operand" "=r")
1824 (match_operand 1 "memory_operand" "m")
1825 (match_operand:DI 2 "register_operand" "=r")])]
1828 rtx mem = operands[1];
1829 rtx addr = XEXP (mem, 0);
1831 emit_move_insn (operands[2], addr);
1832 mem = replace_equiv_address_nv (mem, operands[2]);
1834 emit_insn (gen_rtx_SET (operands[0], mem));
1838 ;; Move instructions.
1840 (define_expand "movxi"
1841 [(set (match_operand:XI 0 "nonimmediate_operand")
1842 (match_operand:XI 1 "general_operand"))]
1844 "ix86_expand_vector_move (XImode, operands); DONE;")
1846 (define_expand "movoi"
1847 [(set (match_operand:OI 0 "nonimmediate_operand")
1848 (match_operand:OI 1 "general_operand"))]
1850 "ix86_expand_vector_move (OImode, operands); DONE;")
1852 (define_expand "movti"
1853 [(set (match_operand:TI 0 "nonimmediate_operand")
1854 (match_operand:TI 1 "general_operand"))]
1855 "TARGET_64BIT || TARGET_SSE"
1858 ix86_expand_move (TImode, operands);
1860 ix86_expand_vector_move (TImode, operands);
1864 ;; This expands to what emit_move_complex would generate if we didn't
1865 ;; have a movti pattern. Having this avoids problems with reload on
1866 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1867 ;; to have around all the time.
1868 (define_expand "movcdi"
1869 [(set (match_operand:CDI 0 "nonimmediate_operand")
1870 (match_operand:CDI 1 "general_operand"))]
1873 if (push_operand (operands[0], CDImode))
1874 emit_move_complex_push (CDImode, operands[0], operands[1]);
1876 emit_move_complex_parts (operands[0], operands[1]);
1880 (define_expand "mov<mode>"
1881 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1882 (match_operand:SWI1248x 1 "general_operand"))]
1884 "ix86_expand_move (<MODE>mode, operands); DONE;")
1886 (define_insn "*mov<mode>_xor"
1887 [(set (match_operand:SWI48 0 "register_operand" "=r")
1888 (match_operand:SWI48 1 "const0_operand"))
1889 (clobber (reg:CC FLAGS_REG))]
1892 [(set_attr "type" "alu1")
1893 (set_attr "mode" "SI")
1894 (set_attr "length_immediate" "0")])
1896 (define_insn "*mov<mode>_or"
1897 [(set (match_operand:SWI48 0 "register_operand" "=r")
1898 (match_operand:SWI48 1 "constm1_operand"))
1899 (clobber (reg:CC FLAGS_REG))]
1901 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "<MODE>")
1904 (set_attr "length_immediate" "1")])
1906 (define_insn "*movxi_internal_avx512f"
1907 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1908 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1910 && (register_operand (operands[0], XImode)
1911 || register_operand (operands[1], XImode))"
1913 switch (get_attr_type (insn))
1916 return standard_sse_constant_opcode (insn, operands);
1919 if (misaligned_operand (operands[0], XImode)
1920 || misaligned_operand (operands[1], XImode))
1921 return "vmovdqu32\t{%1, %0|%0, %1}";
1923 return "vmovdqa32\t{%1, %0|%0, %1}";
1929 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1930 (set_attr "prefix" "evex")
1931 (set_attr "mode" "XI")])
1933 (define_insn "*movoi_internal_avx"
1934 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1935 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1937 && (register_operand (operands[0], OImode)
1938 || register_operand (operands[1], OImode))"
1940 switch (get_attr_type (insn))
1943 return standard_sse_constant_opcode (insn, operands);
1946 if (misaligned_operand (operands[0], OImode)
1947 || misaligned_operand (operands[1], OImode))
1949 if (get_attr_mode (insn) == MODE_V8SF)
1950 return "vmovups\t{%1, %0|%0, %1}";
1951 else if (get_attr_mode (insn) == MODE_XI)
1952 return "vmovdqu32\t{%1, %0|%0, %1}";
1954 return "vmovdqu\t{%1, %0|%0, %1}";
1958 if (get_attr_mode (insn) == MODE_V8SF)
1959 return "vmovaps\t{%1, %0|%0, %1}";
1960 else if (get_attr_mode (insn) == MODE_XI)
1961 return "vmovdqa32\t{%1, %0|%0, %1}";
1963 return "vmovdqa\t{%1, %0|%0, %1}";
1970 [(set_attr "isa" "*,avx2,*,*")
1971 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1972 (set_attr "prefix" "vex")
1974 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1975 (match_operand 1 "ext_sse_reg_operand"))
1977 (and (eq_attr "alternative" "1")
1978 (match_test "TARGET_AVX512VL"))
1980 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1981 (and (eq_attr "alternative" "3")
1982 (match_test "TARGET_SSE_TYPELESS_STORES")))
1983 (const_string "V8SF")
1985 (const_string "OI")))])
1987 (define_insn "*movti_internal"
1988 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1989 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1991 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1993 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1994 && (register_operand (operands[0], TImode)
1995 || register_operand (operands[1], TImode)))"
1997 switch (get_attr_type (insn))
2003 return standard_sse_constant_opcode (insn, operands);
2006 /* TDmode values are passed as TImode on the stack. Moving them
2007 to stack may result in unaligned memory access. */
2008 if (misaligned_operand (operands[0], TImode)
2009 || misaligned_operand (operands[1], TImode))
2011 if (get_attr_mode (insn) == MODE_V4SF)
2012 return "%vmovups\t{%1, %0|%0, %1}";
2013 else if (get_attr_mode (insn) == MODE_XI)
2014 return "vmovdqu32\t{%1, %0|%0, %1}";
2016 return "%vmovdqu\t{%1, %0|%0, %1}";
2020 if (get_attr_mode (insn) == MODE_V4SF)
2021 return "%vmovaps\t{%1, %0|%0, %1}";
2022 else if (get_attr_mode (insn) == MODE_XI)
2023 return "vmovdqa32\t{%1, %0|%0, %1}";
2025 return "%vmovdqa\t{%1, %0|%0, %1}";
2033 (cond [(eq_attr "alternative" "0,1,6,7")
2034 (const_string "x64")
2035 (eq_attr "alternative" "3")
2036 (const_string "sse2")
2038 (const_string "*")))
2040 (cond [(eq_attr "alternative" "0,1,6,7")
2041 (const_string "multi")
2042 (eq_attr "alternative" "2,3")
2043 (const_string "sselog1")
2045 (const_string "ssemov")))
2046 (set (attr "prefix")
2047 (if_then_else (eq_attr "type" "sselog1,ssemov")
2048 (const_string "maybe_vex")
2049 (const_string "orig")))
2051 (cond [(eq_attr "alternative" "0,1")
2053 (ior (match_operand 0 "ext_sse_reg_operand")
2054 (match_operand 1 "ext_sse_reg_operand"))
2056 (and (eq_attr "alternative" "3")
2057 (match_test "TARGET_AVX512VL"))
2059 (ior (not (match_test "TARGET_SSE2"))
2060 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2061 (and (eq_attr "alternative" "5")
2062 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2063 (const_string "V4SF")
2064 (match_test "TARGET_AVX")
2066 (match_test "optimize_function_for_size_p (cfun)")
2067 (const_string "V4SF")
2069 (const_string "TI")))
2070 (set (attr "preferred_for_speed")
2071 (cond [(eq_attr "alternative" "6")
2072 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2073 (eq_attr "alternative" "7")
2074 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2076 (symbol_ref "true")))])
2079 [(set (match_operand:TI 0 "sse_reg_operand")
2080 (match_operand:TI 1 "general_reg_operand"))]
2081 "TARGET_64BIT && TARGET_SSE4_1
2082 && reload_completed"
2085 (vec_duplicate:V2DI (match_dup 3))
2089 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2090 operands[3] = gen_highpart (DImode, operands[1]);
2092 emit_move_insn (gen_lowpart (DImode, operands[0]),
2093 gen_lowpart (DImode, operands[1]));
2096 (define_insn "*movdi_internal"
2097 [(set (match_operand:DI 0 "nonimmediate_operand"
2098 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
2099 (match_operand:DI 1 "general_operand"
2100 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2101 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103 switch (get_attr_type (insn))
2106 return "kmovq\t{%1, %0|%0, %1}";
2109 if (operands[1] == const0_rtx)
2110 return "kxorq\t%0, %0, %0";
2111 else if (operands[1] == constm1_rtx)
2112 return "kxnorq\t%0, %0, %0";
2119 return "pxor\t%0, %0";
2122 /* Handle broken assemblers that require movd instead of movq. */
2123 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2124 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2125 return "movd\t{%1, %0|%0, %1}";
2126 return "movq\t{%1, %0|%0, %1}";
2129 return standard_sse_constant_opcode (insn, operands);
2132 switch (get_attr_mode (insn))
2135 /* Handle broken assemblers that require movd instead of movq. */
2136 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2137 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2138 return "%vmovd\t{%1, %0|%0, %1}";
2139 return "%vmovq\t{%1, %0|%0, %1}";
2142 /* Handle AVX512 registers set. */
2143 if (EXT_REX_SSE_REG_P (operands[0])
2144 || EXT_REX_SSE_REG_P (operands[1]))
2145 return "vmovdqa64\t{%1, %0|%0, %1}";
2146 return "%vmovdqa\t{%1, %0|%0, %1}";
2149 gcc_assert (!TARGET_AVX);
2150 return "movlps\t{%1, %0|%0, %1}";
2152 return "%vmovaps\t{%1, %0|%0, %1}";
2159 if (SSE_REG_P (operands[0]))
2160 return "movq2dq\t{%1, %0|%0, %1}";
2162 return "movdq2q\t{%1, %0|%0, %1}";
2165 return "lea{q}\t{%E1, %0|%0, %E1}";
2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169 if (get_attr_mode (insn) == MODE_SI)
2170 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2171 else if (which_alternative == 4)
2172 return "movabs{q}\t{%1, %0|%0, %1}";
2173 else if (ix86_use_lea_for_mov (insn, operands))
2174 return "lea{q}\t{%E1, %0|%0, %E1}";
2176 return "mov{q}\t{%1, %0|%0, %1}";
2183 (cond [(eq_attr "alternative" "0,1,17,18")
2184 (const_string "nox64")
2185 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2186 (const_string "x64")
2187 (eq_attr "alternative" "19,20")
2188 (const_string "x64_sse2")
2189 (eq_attr "alternative" "21,22")
2190 (const_string "sse2")
2192 (const_string "*")))
2194 (cond [(eq_attr "alternative" "0,1,17,18")
2195 (const_string "multi")
2196 (eq_attr "alternative" "6")
2197 (const_string "mmx")
2198 (eq_attr "alternative" "7,8,9,10,11")
2199 (const_string "mmxmov")
2200 (eq_attr "alternative" "12")
2201 (const_string "sselog1")
2202 (eq_attr "alternative" "13,14,15,16,19,20")
2203 (const_string "ssemov")
2204 (eq_attr "alternative" "21,22")
2205 (const_string "ssecvt")
2206 (eq_attr "alternative" "23,24,25,26")
2207 (const_string "mskmov")
2208 (eq_attr "alternative" "27")
2209 (const_string "msklog")
2210 (and (match_operand 0 "register_operand")
2211 (match_operand 1 "pic_32bit_operand"))
2212 (const_string "lea")
2214 (const_string "imov")))
2217 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2219 (const_string "*")))
2220 (set (attr "length_immediate")
2222 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2224 (const_string "*")))
2225 (set (attr "prefix_rex")
2227 (eq_attr "alternative" "10,11,19,20")
2229 (const_string "*")))
2230 (set (attr "prefix")
2231 (if_then_else (eq_attr "type" "sselog1,ssemov")
2232 (const_string "maybe_vex")
2233 (const_string "orig")))
2234 (set (attr "prefix_data16")
2235 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2237 (const_string "*")))
2239 (cond [(eq_attr "alternative" "2")
2241 (eq_attr "alternative" "12,13")
2242 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2243 (match_operand 1 "ext_sse_reg_operand"))
2245 (ior (not (match_test "TARGET_SSE2"))
2246 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2247 (const_string "V4SF")
2248 (match_test "TARGET_AVX")
2250 (match_test "optimize_function_for_size_p (cfun)")
2251 (const_string "V4SF")
2253 (const_string "TI"))
2255 (and (eq_attr "alternative" "14,15,16")
2256 (not (match_test "TARGET_SSE2")))
2257 (const_string "V2SF")
2259 (const_string "DI")))
2260 (set (attr "preferred_for_speed")
2261 (cond [(eq_attr "alternative" "10,17,19")
2262 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2263 (eq_attr "alternative" "11,18,20")
2264 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2266 (symbol_ref "true")))
2267 (set (attr "enabled")
2268 (cond [(eq_attr "alternative" "15")
2270 (match_test "TARGET_STV && TARGET_SSE2")
2271 (symbol_ref "false")
2273 (eq_attr "alternative" "16")
2275 (match_test "TARGET_STV && TARGET_SSE2")
2277 (symbol_ref "false"))
2279 (const_string "*")))])
2282 [(set (match_operand:<DWI> 0 "general_reg_operand")
2283 (match_operand:<DWI> 1 "sse_reg_operand"))]
2285 && reload_completed"
2289 (parallel [(const_int 1)])))]
2291 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2292 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2294 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2295 gen_lowpart (<MODE>mode, operands[1]));
2299 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2300 (match_operand:DWI 1 "general_gr_operand"))]
2303 "ix86_split_long_move (operands); DONE;")
2306 [(set (match_operand:DI 0 "sse_reg_operand")
2307 (match_operand:DI 1 "general_reg_operand"))]
2308 "!TARGET_64BIT && TARGET_SSE4_1
2309 && reload_completed"
2312 (vec_duplicate:V4SI (match_dup 3))
2316 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2317 operands[3] = gen_highpart (SImode, operands[1]);
2319 emit_move_insn (gen_lowpart (SImode, operands[0]),
2320 gen_lowpart (SImode, operands[1]));
2323 ;; movabsq $0x0012345678000000, %rax is longer
2324 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2326 [(set (match_operand:DI 0 "register_operand")
2327 (match_operand:DI 1 "const_int_operand"))]
2329 && optimize_insn_for_size_p ()
2330 && LEGACY_INT_REG_P (operands[0])
2331 && !x86_64_immediate_operand (operands[1], DImode)
2332 && !x86_64_zext_immediate_operand (operands[1], DImode)
2333 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2334 & ~(HOST_WIDE_INT) 0xffffffff)
2335 && peep2_regno_dead_p (0, FLAGS_REG)"
2336 [(set (match_dup 0) (match_dup 1))
2337 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2338 (clobber (reg:CC FLAGS_REG))])]
2340 int shift = ctz_hwi (UINTVAL (operands[1]));
2341 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2342 operands[2] = gen_int_mode (shift, QImode);
2345 (define_insn "*movsi_internal"
2346 [(set (match_operand:SI 0 "nonimmediate_operand"
2347 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2348 (match_operand:SI 1 "general_operand"
2349 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2350 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2352 switch (get_attr_type (insn))
2355 return standard_sse_constant_opcode (insn, operands);
2358 return "kmovd\t{%1, %0|%0, %1}";
2361 if (operands[1] == const0_rtx)
2362 return "kxord\t%0, %0, %0";
2363 else if (operands[1] == constm1_rtx)
2364 return "kxnord\t%0, %0, %0";
2368 switch (get_attr_mode (insn))
2371 return "%vmovd\t{%1, %0|%0, %1}";
2373 return "%vmovdqa\t{%1, %0|%0, %1}";
2375 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2378 return "%vmovaps\t{%1, %0|%0, %1}";
2381 gcc_assert (!TARGET_AVX);
2382 return "movss\t{%1, %0|%0, %1}";
2389 return "pxor\t%0, %0";
2392 switch (get_attr_mode (insn))
2395 return "movq\t{%1, %0|%0, %1}";
2397 return "movd\t{%1, %0|%0, %1}";
2404 return "lea{l}\t{%E1, %0|%0, %E1}";
2407 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2408 if (ix86_use_lea_for_mov (insn, operands))
2409 return "lea{l}\t{%E1, %0|%0, %E1}";
2411 return "mov{l}\t{%1, %0|%0, %1}";
2418 (cond [(eq_attr "alternative" "12,13")
2419 (const_string "sse2")
2421 (const_string "*")))
2423 (cond [(eq_attr "alternative" "2")
2424 (const_string "mmx")
2425 (eq_attr "alternative" "3,4,5,6,7")
2426 (const_string "mmxmov")
2427 (eq_attr "alternative" "8")
2428 (const_string "sselog1")
2429 (eq_attr "alternative" "9,10,11,12,13")
2430 (const_string "ssemov")
2431 (eq_attr "alternative" "14,15,16")
2432 (const_string "mskmov")
2433 (eq_attr "alternative" "17")
2434 (const_string "msklog")
2435 (and (match_operand 0 "register_operand")
2436 (match_operand 1 "pic_32bit_operand"))
2437 (const_string "lea")
2439 (const_string "imov")))
2440 (set (attr "prefix")
2441 (if_then_else (eq_attr "type" "sselog1,ssemov")
2442 (const_string "maybe_vex")
2443 (const_string "orig")))
2444 (set (attr "prefix_data16")
2445 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2447 (const_string "*")))
2449 (cond [(eq_attr "alternative" "2,3")
2451 (eq_attr "alternative" "8,9")
2452 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2453 (match_operand 1 "ext_sse_reg_operand"))
2455 (ior (not (match_test "TARGET_SSE2"))
2456 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2457 (const_string "V4SF")
2458 (match_test "TARGET_AVX")
2460 (match_test "optimize_function_for_size_p (cfun)")
2461 (const_string "V4SF")
2463 (const_string "TI"))
2465 (and (eq_attr "alternative" "10,11")
2466 (not (match_test "TARGET_SSE2")))
2469 (const_string "SI")))
2470 (set (attr "preferred_for_speed")
2471 (cond [(eq_attr "alternative" "6,12")
2472 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2473 (eq_attr "alternative" "7,13")
2474 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2476 (symbol_ref "true")))])
2478 (define_insn "*movhi_internal"
2479 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2480 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
2481 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2483 switch (get_attr_type (insn))
2486 /* movzwl is faster than movw on p2 due to partial word stalls,
2487 though not as fast as an aligned movl. */
2488 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2491 switch (which_alternative)
2494 return "kmovw\t{%k1, %0|%0, %k1}";
2496 return "kmovw\t{%1, %k0|%k0, %1}";
2499 return "kmovw\t{%1, %0|%0, %1}";
2505 if (operands[1] == const0_rtx)
2506 return "kxorw\t%0, %0, %0";
2507 else if (operands[1] == constm1_rtx)
2508 return "kxnorw\t%0, %0, %0";
2512 if (get_attr_mode (insn) == MODE_SI)
2513 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2515 return "mov{w}\t{%1, %0|%0, %1}";
2519 (cond [(eq_attr "alternative" "4,5,6,7")
2520 (const_string "mskmov")
2521 (eq_attr "alternative" "8")
2522 (const_string "msklog")
2523 (match_test "optimize_function_for_size_p (cfun)")
2524 (const_string "imov")
2525 (and (eq_attr "alternative" "0")
2526 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2527 (not (match_test "TARGET_HIMODE_MATH"))))
2528 (const_string "imov")
2529 (and (eq_attr "alternative" "1,2")
2530 (match_operand:HI 1 "aligned_operand"))
2531 (const_string "imov")
2532 (and (match_test "TARGET_MOVX")
2533 (eq_attr "alternative" "0,2"))
2534 (const_string "imovx")
2536 (const_string "imov")))
2537 (set (attr "prefix")
2538 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2539 (const_string "vex")
2540 (const_string "orig")))
2542 (cond [(eq_attr "type" "imovx")
2544 (and (eq_attr "alternative" "1,2")
2545 (match_operand:HI 1 "aligned_operand"))
2547 (and (eq_attr "alternative" "0")
2548 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2549 (not (match_test "TARGET_HIMODE_MATH"))))
2552 (const_string "HI")))])
2554 ;; Situation is quite tricky about when to choose full sized (SImode) move
2555 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2556 ;; partial register dependency machines (such as AMD Athlon), where QImode
2557 ;; moves issue extra dependency and for partial register stalls machines
2558 ;; that don't use QImode patterns (and QImode move cause stall on the next
2561 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2562 ;; register stall machines with, where we use QImode instructions, since
2563 ;; partial register stall can be caused there. Then we use movzx.
2565 (define_insn "*movqi_internal"
2566 [(set (match_operand:QI 0 "nonimmediate_operand"
2567 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2568 (match_operand:QI 1 "general_operand"
2569 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2570 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2576 switch (get_attr_type (insn))
2579 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2580 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2583 switch (which_alternative)
2586 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2589 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2593 gcc_assert (TARGET_AVX512DQ);
2596 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2602 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2604 snprintf (buf, sizeof (buf), ops, suffix);
2605 output_asm_insn (buf, operands);
2609 if (operands[1] == const0_rtx)
2611 if (get_attr_mode (insn) == MODE_HI)
2612 return "kxorw\t%0, %0, %0";
2614 return "kxorb\t%0, %0, %0";
2616 else if (operands[1] == constm1_rtx)
2618 gcc_assert (TARGET_AVX512DQ);
2619 return "kxnorb\t%0, %0, %0";
2624 if (get_attr_mode (insn) == MODE_SI)
2625 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2627 return "mov{b}\t{%1, %0|%0, %1}";
2631 (cond [(eq_attr "alternative" "1,2")
2632 (const_string "x64")
2633 (eq_attr "alternative" "12,13,15")
2634 (const_string "avx512dq")
2636 (const_string "*")))
2638 (cond [(eq_attr "alternative" "9,10,11,12,13")
2639 (const_string "mskmov")
2640 (eq_attr "alternative" "14,15")
2641 (const_string "msklog")
2642 (and (eq_attr "alternative" "7")
2643 (not (match_operand:QI 1 "aligned_operand")))
2644 (const_string "imovx")
2645 (match_test "optimize_function_for_size_p (cfun)")
2646 (const_string "imov")
2647 (and (eq_attr "alternative" "5")
2648 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2649 (not (match_test "TARGET_QIMODE_MATH"))))
2650 (const_string "imov")
2651 (eq_attr "alternative" "5,7")
2652 (const_string "imovx")
2653 (and (match_test "TARGET_MOVX")
2654 (eq_attr "alternative" "4"))
2655 (const_string "imovx")
2657 (const_string "imov")))
2658 (set (attr "prefix")
2659 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2660 (const_string "vex")
2661 (const_string "orig")))
2663 (cond [(eq_attr "alternative" "5,6,7")
2665 (eq_attr "alternative" "8")
2667 (and (eq_attr "alternative" "9,10,11,14")
2668 (not (match_test "TARGET_AVX512DQ")))
2670 (eq_attr "type" "imovx")
2672 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2674 (and (eq_attr "type" "imov")
2675 (and (eq_attr "alternative" "3")
2676 (match_test "optimize_function_for_size_p (cfun)")))
2678 ;; For -Os, movl where one or both operands are NON_Q_REGS
2679 ;; and both are LEGACY_REGS is shorter than movb.
2680 ;; Otherwise movb and movl sizes are the same, so decide purely
2681 ;; based on speed factors.
2682 (and (eq_attr "type" "imov")
2683 (and (eq_attr "alternative" "1")
2684 (match_test "optimize_function_for_size_p (cfun)")))
2686 (and (eq_attr "type" "imov")
2687 (and (eq_attr "alternative" "0,1,2,3")
2688 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2689 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2691 ;; Avoid partial register stalls when not using QImode arithmetic
2692 (and (eq_attr "type" "imov")
2693 (and (eq_attr "alternative" "0,1,2,3")
2694 (and (match_test "TARGET_PARTIAL_REG_STALL")
2695 (not (match_test "TARGET_QIMODE_MATH")))))
2698 (const_string "QI")))])
2700 ;; Stores and loads of ax to arbitrary constant address.
2701 ;; We fake an second form of instruction to force reload to load address
2702 ;; into register when rax is not available
2703 (define_insn "*movabs<mode>_1"
2704 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2705 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2706 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2708 /* Recover the full memory rtx. */
2709 operands[0] = SET_DEST (PATTERN (insn));
2710 switch (which_alternative)
2713 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2715 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2720 [(set_attr "type" "imov")
2721 (set_attr "modrm" "0,*")
2722 (set_attr "length_address" "8,0")
2723 (set_attr "length_immediate" "0,*")
2724 (set_attr "memory" "store")
2725 (set_attr "mode" "<MODE>")])
2727 (define_insn "*movabs<mode>_2"
2728 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2729 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2730 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2732 /* Recover the full memory rtx. */
2733 operands[1] = SET_SRC (PATTERN (insn));
2734 switch (which_alternative)
2737 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2739 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2744 [(set_attr "type" "imov")
2745 (set_attr "modrm" "0,*")
2746 (set_attr "length_address" "8,0")
2747 (set_attr "length_immediate" "0")
2748 (set_attr "memory" "load")
2749 (set_attr "mode" "<MODE>")])
2751 (define_insn "*swap<mode>"
2752 [(set (match_operand:SWI48 0 "register_operand" "+r")
2753 (match_operand:SWI48 1 "register_operand" "+r"))
2757 "xchg{<imodesuffix>}\t%1, %0"
2758 [(set_attr "type" "imov")
2759 (set_attr "mode" "<MODE>")
2760 (set_attr "pent_pair" "np")
2761 (set_attr "athlon_decode" "vector")
2762 (set_attr "amdfam10_decode" "double")
2763 (set_attr "bdver1_decode" "double")])
2765 (define_insn "*swap<mode>"
2766 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2767 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2772 xchg{<imodesuffix>}\t%1, %0
2774 [(set_attr "type" "imov")
2775 (set_attr "mode" "<MODE>,SI")
2776 (set (attr "preferred_for_size")
2777 (cond [(eq_attr "alternative" "0")
2778 (symbol_ref "false")]
2779 (symbol_ref "true")))
2780 ;; Potential partial reg stall on alternative 1.
2781 (set (attr "preferred_for_speed")
2782 (cond [(eq_attr "alternative" "1")
2783 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2784 (symbol_ref "true")))
2785 (set_attr "pent_pair" "np")
2786 (set_attr "athlon_decode" "vector")
2787 (set_attr "amdfam10_decode" "double")
2788 (set_attr "bdver1_decode" "double")])
2791 [(set (match_operand:SWI 0 "general_reg_operand")
2792 (match_operand:SWI 1 "general_reg_operand"))
2794 (match_operand:SWI 2 "general_reg_operand"))
2795 (set (match_dup 2) (match_dup 0))]
2796 "peep2_reg_dead_p (3, operands[0])
2797 && optimize_insn_for_size_p ()"
2798 [(parallel [(set (match_dup 1) (match_dup 2))
2799 (set (match_dup 2) (match_dup 1))])])
2801 (define_expand "movstrict<mode>"
2802 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2803 (match_operand:SWI12 1 "general_operand"))]
2806 gcc_assert (SUBREG_P (operands[0]));
2807 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2808 || GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2812 (define_insn "*movstrict<mode>_1"
2813 [(set (strict_low_part
2814 (match_operand:SWI12 0 "register_operand" "+<r>"))
2815 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
2816 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2817 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2818 [(set_attr "type" "imov")
2819 (set_attr "mode" "<MODE>")])
2821 (define_insn "*movstrict<mode>_xor"
2822 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2823 (match_operand:SWI12 1 "const0_operand"))
2824 (clobber (reg:CC FLAGS_REG))]
2826 "xor{<imodesuffix>}\t%0, %0"
2827 [(set_attr "type" "alu1")
2828 (set_attr "mode" "<MODE>")
2829 (set_attr "length_immediate" "0")])
2831 (define_expand "extv<mode>"
2832 [(set (match_operand:SWI24 0 "register_operand")
2833 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2834 (match_operand:SI 2 "const_int_operand")
2835 (match_operand:SI 3 "const_int_operand")))]
2838 /* Handle extractions from %ah et al. */
2839 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2842 unsigned int regno = reg_or_subregno (operands[1]);
2844 /* Be careful to expand only with registers having upper parts. */
2845 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2846 operands[1] = copy_to_reg (operands[1]);
2849 (define_insn "*extv<mode>"
2850 [(set (match_operand:SWI24 0 "register_operand" "=R")
2851 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2855 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2856 [(set_attr "type" "imovx")
2857 (set_attr "mode" "SI")])
2859 (define_expand "extzv<mode>"
2860 [(set (match_operand:SWI248 0 "register_operand")
2861 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2862 (match_operand:SI 2 "const_int_operand")
2863 (match_operand:SI 3 "const_int_operand")))]
2866 if (ix86_expand_pextr (operands))
2869 /* Handle extractions from %ah et al. */
2870 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2873 unsigned int regno = reg_or_subregno (operands[1]);
2875 /* Be careful to expand only with registers having upper parts. */
2876 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2877 operands[1] = copy_to_reg (operands[1]);
2880 (define_insn "*extzvqi_mem_rex64"
2881 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2883 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2886 "TARGET_64BIT && reload_completed"
2887 "mov{b}\t{%h1, %0|%0, %h1}"
2888 [(set_attr "type" "imov")
2889 (set_attr "mode" "QI")])
2891 (define_insn "*extzv<mode>"
2892 [(set (match_operand:SWI248 0 "register_operand" "=R")
2893 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2897 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2898 [(set_attr "type" "imovx")
2899 (set_attr "mode" "SI")])
2901 (define_insn "*extzvqi"
2902 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2904 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2909 switch (get_attr_type (insn))
2912 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2914 return "mov{b}\t{%h1, %0|%0, %h1}";
2917 [(set_attr "isa" "*,*,nox64")
2919 (if_then_else (and (match_operand:QI 0 "register_operand")
2920 (ior (not (match_operand:QI 0 "QIreg_operand"))
2921 (match_test "TARGET_MOVX")))
2922 (const_string "imovx")
2923 (const_string "imov")))
2925 (if_then_else (eq_attr "type" "imovx")
2927 (const_string "QI")))])
2930 [(set (match_operand:QI 0 "register_operand")
2932 (zero_extract:SI (match_operand 1 "ext_register_operand")
2935 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2937 && peep2_reg_dead_p (2, operands[0])"
2940 (zero_extract:SI (match_dup 1)
2942 (const_int 8)) 0))])
2944 (define_expand "insv<mode>"
2945 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2946 (match_operand:SI 1 "const_int_operand")
2947 (match_operand:SI 2 "const_int_operand"))
2948 (match_operand:SWI248 3 "register_operand"))]
2953 if (ix86_expand_pinsr (operands))
2956 /* Handle insertions to %ah et al. */
2957 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2960 unsigned int regno = reg_or_subregno (operands[0]);
2962 /* Be careful to expand only with registers having upper parts. */
2963 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2964 dst = copy_to_reg (operands[0]);
2968 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2970 /* Fix up the destination if needed. */
2971 if (dst != operands[0])
2972 emit_move_insn (operands[0], dst);
2977 (define_insn "*insvqi_1_mem_rex64"
2978 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2982 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2983 "TARGET_64BIT && reload_completed"
2984 "mov{b}\t{%1, %h0|%h0, %1}"
2985 [(set_attr "type" "imov")
2986 (set_attr "mode" "QI")])
2988 (define_insn "insv<mode>_1"
2989 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2992 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2995 if (CONST_INT_P (operands[1]))
2996 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2997 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2999 [(set_attr "isa" "*,nox64")
3000 (set_attr "type" "imov")
3001 (set_attr "mode" "QI")])
3003 (define_insn "*insvqi_1"
3004 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3008 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3010 "mov{b}\t{%1, %h0|%h0, %1}"
3011 [(set_attr "isa" "*,nox64")
3012 (set_attr "type" "imov")
3013 (set_attr "mode" "QI")])
3016 [(set (match_operand:QI 0 "register_operand")
3017 (match_operand:QI 1 "norex_memory_operand"))
3018 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3021 (subreg:SI (match_dup 0) 0))]
3023 && peep2_reg_dead_p (2, operands[0])"
3024 [(set (zero_extract:SI (match_dup 2)
3027 (subreg:SI (match_dup 1) 0))])
3029 (define_code_iterator any_extract [sign_extract zero_extract])
3031 (define_insn "*insvqi_2"
3032 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3035 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3039 "mov{b}\t{%h1, %h0|%h0, %h1}"
3040 [(set_attr "type" "imov")
3041 (set_attr "mode" "QI")])
3043 (define_insn "*insvqi_3"
3044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3047 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3050 "mov{b}\t{%h1, %h0|%h0, %h1}"
3051 [(set_attr "type" "imov")
3052 (set_attr "mode" "QI")])
3054 ;; Floating point push instructions.
3056 (define_insn "*pushtf"
3057 [(set (match_operand:TF 0 "push_operand" "=<,<")
3058 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3059 "TARGET_64BIT || TARGET_SSE"
3061 /* This insn should be already split before reg-stack. */
3064 [(set_attr "isa" "*,x64")
3065 (set_attr "type" "multi")
3066 (set_attr "unit" "sse,*")
3067 (set_attr "mode" "TF,DI")])
3069 ;; %%% Kill this when call knows how to work this out.
3071 [(set (match_operand:TF 0 "push_operand")
3072 (match_operand:TF 1 "sse_reg_operand"))]
3073 "TARGET_SSE && reload_completed"
3074 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3075 (set (match_dup 0) (match_dup 1))]
3077 /* Preserve memory attributes. */
3078 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3081 (define_insn_and_split "*pushxf_rounded"
3085 (plus:P (reg:P SP_REG) (const_int -16))))
3086 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3090 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3091 (set (match_dup 1) (match_dup 0))]
3093 rtx pat = PATTERN (curr_insn);
3094 operands[1] = SET_DEST (pat);
3096 /* Preserve memory attributes. */
3097 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3099 [(set_attr "type" "multi")
3100 (set_attr "unit" "i387,*,*,*")
3102 (cond [(eq_attr "alternative" "1,2,3")
3105 (const_string "XF")))
3106 (set (attr "preferred_for_size")
3107 (cond [(eq_attr "alternative" "1")
3108 (symbol_ref "false")]
3109 (symbol_ref "true")))])
3111 (define_insn "*pushxf"
3112 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3113 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3116 /* This insn should be already split before reg-stack. */
3119 [(set_attr "isa" "*,*,*,nox64,x64")
3120 (set_attr "type" "multi")
3121 (set_attr "unit" "i387,*,*,*,*")
3123 (cond [(eq_attr "alternative" "1,2,3,4")
3124 (if_then_else (match_test "TARGET_64BIT")
3126 (const_string "SI"))
3128 (const_string "XF")))
3129 (set (attr "preferred_for_size")
3130 (cond [(eq_attr "alternative" "1")
3131 (symbol_ref "false")]
3132 (symbol_ref "true")))])
3134 ;; %%% Kill this when call knows how to work this out.
3136 [(set (match_operand:XF 0 "push_operand")
3137 (match_operand:XF 1 "fp_register_operand"))]
3139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3140 (set (match_dup 0) (match_dup 1))]
3142 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3143 /* Preserve memory attributes. */
3144 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3147 (define_insn "*pushdf"
3148 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3149 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3152 /* This insn should be already split before reg-stack. */
3155 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3156 (set_attr "type" "multi")
3157 (set_attr "unit" "i387,*,*,*,*,sse")
3158 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3159 (set (attr "preferred_for_size")
3160 (cond [(eq_attr "alternative" "1")
3161 (symbol_ref "false")]
3162 (symbol_ref "true")))
3163 (set (attr "preferred_for_speed")
3164 (cond [(eq_attr "alternative" "1")
3165 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3166 (symbol_ref "true")))])
3168 ;; %%% Kill this when call knows how to work this out.
3170 [(set (match_operand:DF 0 "push_operand")
3171 (match_operand:DF 1 "any_fp_register_operand"))]
3173 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3174 (set (match_dup 0) (match_dup 1))]
3176 /* Preserve memory attributes. */
3177 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3180 (define_insn "*pushsf_rex64"
3181 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3182 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3185 /* Anything else should be already split before reg-stack. */
3186 gcc_assert (which_alternative == 1);
3187 return "push{q}\t%q1";
3189 [(set_attr "type" "multi,push,multi")
3190 (set_attr "unit" "i387,*,*")
3191 (set_attr "mode" "SF,DI,SF")])
3193 (define_insn "*pushsf"
3194 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3195 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3198 /* Anything else should be already split before reg-stack. */
3199 gcc_assert (which_alternative == 1);
3200 return "push{l}\t%1";
3202 [(set_attr "type" "multi,push,multi")
3203 (set_attr "unit" "i387,*,*")
3204 (set_attr "mode" "SF,SI,SF")])
3206 ;; %%% Kill this when call knows how to work this out.
3208 [(set (match_operand:SF 0 "push_operand")
3209 (match_operand:SF 1 "any_fp_register_operand"))]
3211 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3212 (set (match_dup 0) (match_dup 1))]
3214 rtx op = XEXP (operands[0], 0);
3215 if (GET_CODE (op) == PRE_DEC)
3217 gcc_assert (!TARGET_64BIT);
3222 op = XEXP (XEXP (op, 1), 1);
3223 gcc_assert (CONST_INT_P (op));
3226 /* Preserve memory attributes. */
3227 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3231 [(set (match_operand:SF 0 "push_operand")
3232 (match_operand:SF 1 "memory_operand"))]
3234 && find_constant_src (insn)"
3235 [(set (match_dup 0) (match_dup 2))]
3236 "operands[2] = find_constant_src (curr_insn);")
3239 [(set (match_operand 0 "push_operand")
3240 (match_operand 1 "general_gr_operand"))]
3242 && (GET_MODE (operands[0]) == TFmode
3243 || GET_MODE (operands[0]) == XFmode
3244 || GET_MODE (operands[0]) == DFmode)"
3246 "ix86_split_long_move (operands); DONE;")
3248 ;; Floating point move instructions.
3250 (define_expand "movtf"
3251 [(set (match_operand:TF 0 "nonimmediate_operand")
3252 (match_operand:TF 1 "nonimmediate_operand"))]
3253 "TARGET_64BIT || TARGET_SSE"
3254 "ix86_expand_move (TFmode, operands); DONE;")
3256 (define_expand "mov<mode>"
3257 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3258 (match_operand:X87MODEF 1 "general_operand"))]
3260 "ix86_expand_move (<MODE>mode, operands); DONE;")
3262 (define_insn "*movtf_internal"
3263 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3264 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3265 "(TARGET_64BIT || TARGET_SSE)
3266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3267 && (lra_in_progress || reload_completed
3268 || !CONST_DOUBLE_P (operands[1])
3269 || ((optimize_function_for_size_p (cfun)
3270 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3271 && standard_sse_constant_p (operands[1], TFmode) == 1
3272 && !memory_operand (operands[0], TFmode))
3273 || (!TARGET_MEMORY_MISMATCH_STALL
3274 && memory_operand (operands[0], TFmode)))"
3276 switch (get_attr_type (insn))
3279 return standard_sse_constant_opcode (insn, operands);
3282 /* Handle misaligned load/store since we
3283 don't have movmisaligntf pattern. */
3284 if (misaligned_operand (operands[0], TFmode)
3285 || misaligned_operand (operands[1], TFmode))
3287 if (get_attr_mode (insn) == MODE_V4SF)
3288 return "%vmovups\t{%1, %0|%0, %1}";
3289 else if (TARGET_AVX512VL
3290 && (EXT_REX_SSE_REG_P (operands[0])
3291 || EXT_REX_SSE_REG_P (operands[1])))
3292 return "vmovdqu64\t{%1, %0|%0, %1}";
3294 return "%vmovdqu\t{%1, %0|%0, %1}";
3298 if (get_attr_mode (insn) == MODE_V4SF)
3299 return "%vmovaps\t{%1, %0|%0, %1}";
3300 else if (TARGET_AVX512VL
3301 && (EXT_REX_SSE_REG_P (operands[0])
3302 || EXT_REX_SSE_REG_P (operands[1])))
3303 return "vmovdqa64\t{%1, %0|%0, %1}";
3305 return "%vmovdqa\t{%1, %0|%0, %1}";
3315 [(set_attr "isa" "*,*,*,x64,x64")
3316 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3317 (set (attr "prefix")
3318 (if_then_else (eq_attr "type" "sselog1,ssemov")
3319 (const_string "maybe_vex")
3320 (const_string "orig")))
3322 (cond [(eq_attr "alternative" "3,4")
3324 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3325 (const_string "V4SF")
3326 (and (eq_attr "alternative" "2")
3327 (match_test "TARGET_SSE_TYPELESS_STORES"))
3328 (const_string "V4SF")
3329 (match_test "TARGET_AVX")
3331 (ior (not (match_test "TARGET_SSE2"))
3332 (match_test "optimize_function_for_size_p (cfun)"))
3333 (const_string "V4SF")
3335 (const_string "TI")))])
3338 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3339 (match_operand:TF 1 "general_gr_operand"))]
3342 "ix86_split_long_move (operands); DONE;")
3344 ;; Possible store forwarding (partial memory) stall
3345 ;; in alternatives 4, 6, 7 and 8.
3346 (define_insn "*movxf_internal"
3347 [(set (match_operand:XF 0 "nonimmediate_operand"
3348 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3349 (match_operand:XF 1 "general_operand"
3350 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3351 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3352 && (lra_in_progress || reload_completed
3353 || !CONST_DOUBLE_P (operands[1])
3354 || ((optimize_function_for_size_p (cfun)
3355 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3356 && standard_80387_constant_p (operands[1]) > 0
3357 && !memory_operand (operands[0], XFmode))
3358 || (!TARGET_MEMORY_MISMATCH_STALL
3359 && memory_operand (operands[0], XFmode))
3360 || !TARGET_HARD_XF_REGS)"
3362 switch (get_attr_type (insn))
3365 if (which_alternative == 2)
3366 return standard_80387_constant_opcode (operands[1]);
3367 return output_387_reg_move (insn, operands);
3377 (cond [(eq_attr "alternative" "7,10")
3378 (const_string "nox64")
3379 (eq_attr "alternative" "8,11")
3380 (const_string "x64")
3382 (const_string "*")))
3384 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3385 (const_string "multi")
3387 (const_string "fmov")))
3389 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3390 (if_then_else (match_test "TARGET_64BIT")
3392 (const_string "SI"))
3394 (const_string "XF")))
3395 (set (attr "preferred_for_size")
3396 (cond [(eq_attr "alternative" "3,4")
3397 (symbol_ref "false")]
3398 (symbol_ref "true")))
3399 (set (attr "enabled")
3400 (cond [(eq_attr "alternative" "9,10,11")
3402 (match_test "TARGET_HARD_XF_REGS")
3403 (symbol_ref "false")
3405 (not (match_test "TARGET_HARD_XF_REGS"))
3406 (symbol_ref "false")
3408 (const_string "*")))])
3411 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3412 (match_operand:XF 1 "general_gr_operand"))]
3415 "ix86_split_long_move (operands); DONE;")
3417 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3418 (define_insn "*movdf_internal"
3419 [(set (match_operand:DF 0 "nonimmediate_operand"
3420 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m")
3421 (match_operand:DF 1 "general_operand"
3422 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3423 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3424 && (lra_in_progress || reload_completed
3425 || !CONST_DOUBLE_P (operands[1])
3426 || ((optimize_function_for_size_p (cfun)
3427 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3428 && ((IS_STACK_MODE (DFmode)
3429 && standard_80387_constant_p (operands[1]) > 0)
3430 || (TARGET_SSE2 && TARGET_SSE_MATH
3431 && standard_sse_constant_p (operands[1], DFmode) == 1))
3432 && !memory_operand (operands[0], DFmode))
3433 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3434 && memory_operand (operands[0], DFmode))
3435 || !TARGET_HARD_DF_REGS)"
3437 switch (get_attr_type (insn))
3440 if (which_alternative == 2)
3441 return standard_80387_constant_opcode (operands[1]);
3442 return output_387_reg_move (insn, operands);
3448 if (get_attr_mode (insn) == MODE_SI)
3449 return "mov{l}\t{%1, %k0|%k0, %1}";
3450 else if (which_alternative == 11)
3451 return "movabs{q}\t{%1, %0|%0, %1}";
3453 return "mov{q}\t{%1, %0|%0, %1}";
3456 return standard_sse_constant_opcode (insn, operands);
3459 switch (get_attr_mode (insn))
3462 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3463 return "vmovsd\t{%d1, %0|%0, %d1}";
3464 return "%vmovsd\t{%1, %0|%0, %1}";
3467 return "%vmovaps\t{%1, %0|%0, %1}";
3469 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3471 return "%vmovapd\t{%1, %0|%0, %1}";
3474 gcc_assert (!TARGET_AVX);
3475 return "movlps\t{%1, %0|%0, %1}";
3477 gcc_assert (!TARGET_AVX);
3478 return "movlpd\t{%1, %0|%0, %1}";
3481 /* Handle broken assemblers that require movd instead of movq. */
3482 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3483 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3484 return "%vmovd\t{%1, %0|%0, %1}";
3485 return "%vmovq\t{%1, %0|%0, %1}";
3496 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3497 (const_string "nox64")
3498 (eq_attr "alternative" "8,9,10,11,24,25")
3499 (const_string "x64")
3500 (eq_attr "alternative" "12,13,14,15")
3501 (const_string "sse2")
3502 (eq_attr "alternative" "20,21")
3503 (const_string "x64_sse2")
3505 (const_string "*")))
3507 (cond [(eq_attr "alternative" "0,1,2")
3508 (const_string "fmov")
3509 (eq_attr "alternative" "3,4,5,6,7,22,23")
3510 (const_string "multi")
3511 (eq_attr "alternative" "8,9,10,11,24,25")
3512 (const_string "imov")
3513 (eq_attr "alternative" "12,16")
3514 (const_string "sselog1")
3516 (const_string "ssemov")))
3518 (if_then_else (eq_attr "alternative" "11")
3520 (const_string "*")))
3521 (set (attr "length_immediate")
3522 (if_then_else (eq_attr "alternative" "11")
3524 (const_string "*")))
3525 (set (attr "prefix")
3526 (if_then_else (eq_attr "type" "sselog1,ssemov")
3527 (const_string "maybe_vex")
3528 (const_string "orig")))
3529 (set (attr "prefix_data16")
3531 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3532 (eq_attr "mode" "V1DF"))
3534 (const_string "*")))
3536 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3538 (eq_attr "alternative" "8,9,11,20,21,24,25")
3541 /* xorps is one byte shorter for non-AVX targets. */
3542 (eq_attr "alternative" "12,16")
3543 (cond [(not (match_test "TARGET_SSE2"))
3544 (const_string "V4SF")
3545 (and (match_test "TARGET_AVX512F")
3546 (not (match_test "TARGET_PREFER_AVX256")))
3548 (match_test "TARGET_AVX")
3549 (const_string "V2DF")
3550 (match_test "optimize_function_for_size_p (cfun)")
3551 (const_string "V4SF")
3552 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3555 (const_string "V2DF"))
3557 /* For architectures resolving dependencies on
3558 whole SSE registers use movapd to break dependency
3559 chains, otherwise use short move to avoid extra work. */
3561 /* movaps is one byte shorter for non-AVX targets. */
3562 (eq_attr "alternative" "13,17")
3563 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3564 (not (match_test "TARGET_AVX512VL")))
3565 (ior (match_operand 0 "ext_sse_reg_operand")
3566 (match_operand 1 "ext_sse_reg_operand")))
3567 (const_string "V8DF")
3568 (ior (not (match_test "TARGET_SSE2"))
3569 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3570 (const_string "V4SF")
3571 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3572 (const_string "V2DF")
3573 (match_test "TARGET_AVX")
3575 (match_test "optimize_function_for_size_p (cfun)")
3576 (const_string "V4SF")
3578 (const_string "DF"))
3580 /* For architectures resolving dependencies on register
3581 parts we may avoid extra work to zero out upper part
3583 (eq_attr "alternative" "14,18")
3584 (cond [(not (match_test "TARGET_SSE2"))
3585 (const_string "V2SF")
3586 (match_test "TARGET_AVX")
3588 (match_test "TARGET_SSE_SPLIT_REGS")
3589 (const_string "V1DF")
3591 (const_string "DF"))
3593 (and (eq_attr "alternative" "15,19")
3594 (not (match_test "TARGET_SSE2")))
3595 (const_string "V2SF")
3597 (const_string "DF")))
3598 (set (attr "preferred_for_size")
3599 (cond [(eq_attr "alternative" "3,4")
3600 (symbol_ref "false")]
3601 (symbol_ref "true")))
3602 (set (attr "preferred_for_speed")
3603 (cond [(eq_attr "alternative" "3,4")
3604 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3605 (eq_attr "alternative" "20")
3606 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3607 (eq_attr "alternative" "21")
3608 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3610 (symbol_ref "true")))
3611 (set (attr "enabled")
3612 (cond [(eq_attr "alternative" "22,23,24,25")
3614 (match_test "TARGET_HARD_DF_REGS")
3615 (symbol_ref "false")
3617 (not (match_test "TARGET_HARD_DF_REGS"))
3618 (symbol_ref "false")
3620 (const_string "*")))])
3623 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3624 (match_operand:DF 1 "general_gr_operand"))]
3625 "!TARGET_64BIT && reload_completed"
3627 "ix86_split_long_move (operands); DONE;")
3629 (define_insn "*movsf_internal"
3630 [(set (match_operand:SF 0 "nonimmediate_operand"
3631 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3632 (match_operand:SF 1 "general_operand"
3633 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3634 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3635 && (lra_in_progress || reload_completed
3636 || !CONST_DOUBLE_P (operands[1])
3637 || ((optimize_function_for_size_p (cfun)
3638 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3639 && ((IS_STACK_MODE (SFmode)
3640 && standard_80387_constant_p (operands[1]) > 0)
3641 || (TARGET_SSE && TARGET_SSE_MATH
3642 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3643 || memory_operand (operands[0], SFmode)
3644 || !TARGET_HARD_SF_REGS)"
3646 switch (get_attr_type (insn))
3649 if (which_alternative == 2)
3650 return standard_80387_constant_opcode (operands[1]);
3651 return output_387_reg_move (insn, operands);
3654 return "mov{l}\t{%1, %0|%0, %1}";
3657 return standard_sse_constant_opcode (insn, operands);
3660 switch (get_attr_mode (insn))
3663 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3664 return "vmovss\t{%d1, %0|%0, %d1}";
3665 return "%vmovss\t{%1, %0|%0, %1}";
3668 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3670 return "%vmovaps\t{%1, %0|%0, %1}";
3673 return "%vmovd\t{%1, %0|%0, %1}";
3680 switch (get_attr_mode (insn))
3683 return "movq\t{%1, %0|%0, %1}";
3685 return "movd\t{%1, %0|%0, %1}";
3696 (cond [(eq_attr "alternative" "14,15")
3697 (const_string "sse2")
3699 (const_string "*")))
3701 (cond [(eq_attr "alternative" "0,1,2")
3702 (const_string "fmov")
3703 (eq_attr "alternative" "3,4,16,17")
3704 (const_string "imov")
3705 (eq_attr "alternative" "5")
3706 (const_string "sselog1")
3707 (eq_attr "alternative" "11,12,13,14,15")
3708 (const_string "mmxmov")
3710 (const_string "ssemov")))
3711 (set (attr "prefix")
3712 (if_then_else (eq_attr "type" "sselog1,ssemov")
3713 (const_string "maybe_vex")
3714 (const_string "orig")))
3715 (set (attr "prefix_data16")
3716 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3718 (const_string "*")))
3720 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3722 (eq_attr "alternative" "11")
3724 (eq_attr "alternative" "5")
3725 (cond [(not (match_test "TARGET_SSE2"))
3726 (const_string "V4SF")
3727 (and (match_test "TARGET_AVX512F")
3728 (not (match_test "TARGET_PREFER_AVX256")))
3729 (const_string "V16SF")
3730 (match_test "TARGET_AVX")
3731 (const_string "V4SF")
3732 (match_test "optimize_function_for_size_p (cfun)")
3733 (const_string "V4SF")
3734 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3737 (const_string "V4SF"))
3739 /* For architectures resolving dependencies on
3740 whole SSE registers use APS move to break dependency
3741 chains, otherwise use short move to avoid extra work.
3743 Do the same for architectures resolving dependencies on
3744 the parts. While in DF mode it is better to always handle
3745 just register parts, the SF mode is different due to lack
3746 of instructions to load just part of the register. It is
3747 better to maintain the whole registers in single format
3748 to avoid problems on using packed logical operations. */
3749 (eq_attr "alternative" "6")
3750 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3751 (not (match_test "TARGET_AVX512VL")))
3752 (ior (match_operand 0 "ext_sse_reg_operand")
3753 (match_operand 1 "ext_sse_reg_operand")))
3754 (const_string "V16SF")
3755 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3756 (match_test "TARGET_SSE_SPLIT_REGS"))
3757 (const_string "V4SF")
3759 (const_string "SF"))
3761 (const_string "SF")))
3762 (set (attr "preferred_for_speed")
3763 (cond [(eq_attr "alternative" "9,14")
3764 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3765 (eq_attr "alternative" "10,15")
3766 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3768 (symbol_ref "true")))
3769 (set (attr "enabled")
3770 (cond [(eq_attr "alternative" "16,17")
3772 (match_test "TARGET_HARD_SF_REGS")
3773 (symbol_ref "false")
3775 (not (match_test "TARGET_HARD_SF_REGS"))
3776 (symbol_ref "false")
3778 (const_string "*")))])
3781 [(set (match_operand 0 "any_fp_register_operand")
3782 (match_operand 1 "memory_operand"))]
3784 && (GET_MODE (operands[0]) == TFmode
3785 || GET_MODE (operands[0]) == XFmode
3786 || GET_MODE (operands[0]) == DFmode
3787 || GET_MODE (operands[0]) == SFmode)
3788 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3789 [(set (match_dup 0) (match_dup 2))]
3790 "operands[2] = find_constant_src (curr_insn);")
3793 [(set (match_operand 0 "any_fp_register_operand")
3794 (float_extend (match_operand 1 "memory_operand")))]
3796 && (GET_MODE (operands[0]) == TFmode
3797 || GET_MODE (operands[0]) == XFmode
3798 || GET_MODE (operands[0]) == DFmode)
3799 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3800 [(set (match_dup 0) (match_dup 2))]
3801 "operands[2] = find_constant_src (curr_insn);")
3803 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3805 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3806 (match_operand:X87MODEF 1 "immediate_operand"))]
3808 && (standard_80387_constant_p (operands[1]) == 8
3809 || standard_80387_constant_p (operands[1]) == 9)"
3810 [(set (match_dup 0)(match_dup 1))
3812 (neg:X87MODEF (match_dup 0)))]
3814 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3815 operands[1] = CONST0_RTX (<MODE>mode);
3817 operands[1] = CONST1_RTX (<MODE>mode);
3820 (define_insn "*swapxf"
3821 [(set (match_operand:XF 0 "register_operand" "+f")
3822 (match_operand:XF 1 "register_operand" "+f"))
3827 if (STACK_TOP_P (operands[0]))
3832 [(set_attr "type" "fxch")
3833 (set_attr "mode" "XF")])
3836 ;; Zero extension instructions
3838 (define_expand "zero_extendsidi2"
3839 [(set (match_operand:DI 0 "nonimmediate_operand")
3840 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3842 (define_insn "*zero_extendsidi2"
3843 [(set (match_operand:DI 0 "nonimmediate_operand"
3844 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3846 (match_operand:SI 1 "x86_64_zext_operand"
3847 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3850 switch (get_attr_type (insn))
3853 if (ix86_use_lea_for_mov (insn, operands))
3854 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3856 return "mov{l}\t{%1, %k0|%k0, %1}";
3862 return "movd\t{%1, %0|%0, %1}";
3865 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3867 if (EXT_REX_SSE_REG_P (operands[0])
3868 || EXT_REX_SSE_REG_P (operands[1]))
3869 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3871 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3874 if (GENERAL_REG_P (operands[0]))
3875 return "%vmovd\t{%1, %k0|%k0, %1}";
3877 return "%vmovd\t{%1, %0|%0, %1}";
3880 return "kmovd\t{%1, %k0|%k0, %1}";
3887 (cond [(eq_attr "alternative" "0,1,2")
3888 (const_string "nox64")
3889 (eq_attr "alternative" "3")
3890 (const_string "x64")
3891 (eq_attr "alternative" "7,8,9")
3892 (const_string "sse2")
3893 (eq_attr "alternative" "10")
3894 (const_string "sse4")
3895 (eq_attr "alternative" "11")
3896 (const_string "avx512f")
3897 (eq_attr "alternative" "12")
3898 (const_string "x64_avx512bw")
3899 (eq_attr "alternative" "13")
3900 (const_string "avx512bw")
3902 (const_string "*")))
3903 (set (attr "mmx_isa")
3904 (if_then_else (eq_attr "alternative" "5,6")
3905 (const_string "native")
3906 (const_string "*")))
3908 (cond [(eq_attr "alternative" "0,1,2,4")
3909 (const_string "multi")
3910 (eq_attr "alternative" "5,6")
3911 (const_string "mmxmov")
3912 (eq_attr "alternative" "7")
3913 (if_then_else (match_test "TARGET_64BIT")
3914 (const_string "ssemov")
3915 (const_string "multi"))
3916 (eq_attr "alternative" "8,9,10,11")
3917 (const_string "ssemov")
3918 (eq_attr "alternative" "12,13")
3919 (const_string "mskmov")
3921 (const_string "imovx")))
3922 (set (attr "prefix_extra")
3923 (if_then_else (eq_attr "alternative" "10,11")
3925 (const_string "*")))
3926 (set (attr "prefix")
3927 (if_then_else (eq_attr "type" "ssemov")
3928 (const_string "maybe_vex")
3929 (const_string "orig")))
3930 (set (attr "prefix_0f")
3931 (if_then_else (eq_attr "type" "imovx")
3933 (const_string "*")))
3935 (cond [(eq_attr "alternative" "5,6")
3937 (and (eq_attr "alternative" "7")
3938 (match_test "TARGET_64BIT"))
3940 (eq_attr "alternative" "8,10,11")
3943 (const_string "SI")))
3944 (set (attr "preferred_for_speed")
3945 (cond [(eq_attr "alternative" "7")
3946 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3947 (eq_attr "alternative" "5,8")
3948 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3950 (symbol_ref "true")))])
3953 [(set (match_operand:DI 0 "memory_operand")
3954 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3956 [(set (match_dup 4) (const_int 0))]
3957 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3960 [(set (match_operand:DI 0 "general_reg_operand")
3961 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3962 "!TARGET_64BIT && reload_completed
3963 && REGNO (operands[0]) == REGNO (operands[1])"
3964 [(set (match_dup 4) (const_int 0))]
3965 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3968 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3969 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3970 "!TARGET_64BIT && reload_completed
3971 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3972 [(set (match_dup 3) (match_dup 1))
3973 (set (match_dup 4) (const_int 0))]
3974 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3976 (define_mode_attr kmov_isa
3977 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3979 (define_insn "zero_extend<mode>di2"
3980 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3982 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3985 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3986 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3987 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3988 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3989 (set_attr "type" "imovx,mskmov,mskmov")
3990 (set_attr "mode" "SI,<MODE>,<MODE>")])
3992 (define_expand "zero_extend<mode>si2"
3993 [(set (match_operand:SI 0 "register_operand")
3994 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3997 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3999 operands[1] = force_reg (<MODE>mode, operands[1]);
4000 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4005 (define_insn_and_split "zero_extend<mode>si2_and"
4006 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4008 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4009 (clobber (reg:CC FLAGS_REG))]
4010 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4012 "&& reload_completed"
4013 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4014 (clobber (reg:CC FLAGS_REG))])]
4016 if (!REG_P (operands[1])
4017 || REGNO (operands[0]) != REGNO (operands[1]))
4019 ix86_expand_clear (operands[0]);
4021 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4022 emit_insn (gen_rtx_SET
4023 (gen_rtx_STRICT_LOW_PART
4024 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4029 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4031 [(set_attr "type" "alu1")
4032 (set_attr "mode" "SI")])
4034 (define_insn "*zero_extend<mode>si2"
4035 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4037 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4038 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4040 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4041 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4042 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4043 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4044 (set_attr "type" "imovx,mskmov,mskmov")
4045 (set_attr "mode" "SI,<MODE>,<MODE>")])
4047 (define_expand "zero_extendqihi2"
4048 [(set (match_operand:HI 0 "register_operand")
4049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4052 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4054 operands[1] = force_reg (QImode, operands[1]);
4055 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4060 (define_insn_and_split "zero_extendqihi2_and"
4061 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4062 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4063 (clobber (reg:CC FLAGS_REG))]
4064 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4066 "&& reload_completed"
4067 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4068 (clobber (reg:CC FLAGS_REG))])]
4070 if (!REG_P (operands[1])
4071 || REGNO (operands[0]) != REGNO (operands[1]))
4073 ix86_expand_clear (operands[0]);
4075 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4076 emit_insn (gen_rtx_SET
4077 (gen_rtx_STRICT_LOW_PART
4078 (VOIDmode, gen_lowpart (QImode, operands[0])),
4083 operands[0] = gen_lowpart (SImode, operands[0]);
4085 [(set_attr "type" "alu1")
4086 (set_attr "mode" "SI")])
4088 ; zero extend to SImode to avoid partial register stalls
4089 (define_insn "*zero_extendqihi2"
4090 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4091 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4092 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4094 movz{bl|x}\t{%1, %k0|%k0, %1}
4095 kmovb\t{%1, %k0|%k0, %1}
4096 kmovb\t{%1, %0|%0, %1}"
4097 [(set_attr "isa" "*,avx512dq,avx512dq")
4098 (set_attr "type" "imovx,mskmov,mskmov")
4099 (set_attr "mode" "SI,QI,QI")])
4101 ;; Sign extension instructions
4103 (define_expand "extendsidi2"
4104 [(set (match_operand:DI 0 "register_operand")
4105 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4110 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4115 (define_insn "*extendsidi2_rex64"
4116 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4117 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4121 movs{lq|x}\t{%1, %0|%0, %1}"
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "DI")
4124 (set_attr "prefix_0f" "0")
4125 (set_attr "modrm" "0,1")])
4127 (define_insn "extendsidi2_1"
4128 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4129 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4130 (clobber (reg:CC FLAGS_REG))
4131 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4135 ;; Split the memory case. If the source register doesn't die, it will stay
4136 ;; this way, if it does die, following peephole2s take care of it.
4138 [(set (match_operand:DI 0 "memory_operand")
4139 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4140 (clobber (reg:CC FLAGS_REG))
4141 (clobber (match_operand:SI 2 "register_operand"))]
4145 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4147 emit_move_insn (operands[3], operands[1]);
4149 /* Generate a cltd if possible and doing so it profitable. */
4150 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4151 && REGNO (operands[1]) == AX_REG
4152 && REGNO (operands[2]) == DX_REG)
4154 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4158 emit_move_insn (operands[2], operands[1]);
4159 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4161 emit_move_insn (operands[4], operands[2]);
4165 ;; Peepholes for the case where the source register does die, after
4166 ;; being split with the above splitter.
4168 [(set (match_operand:SI 0 "memory_operand")
4169 (match_operand:SI 1 "general_reg_operand"))
4170 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4171 (parallel [(set (match_dup 2)
4172 (ashiftrt:SI (match_dup 2) (const_int 31)))
4173 (clobber (reg:CC FLAGS_REG))])
4174 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4175 "REGNO (operands[1]) != REGNO (operands[2])
4176 && peep2_reg_dead_p (2, operands[1])
4177 && peep2_reg_dead_p (4, operands[2])
4178 && !reg_mentioned_p (operands[2], operands[3])"
4179 [(set (match_dup 0) (match_dup 1))
4180 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181 (clobber (reg:CC FLAGS_REG))])
4182 (set (match_dup 3) (match_dup 1))])
4185 [(set (match_operand:SI 0 "memory_operand")
4186 (match_operand:SI 1 "general_reg_operand"))
4187 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4188 (ashiftrt:SI (match_dup 1) (const_int 31)))
4189 (clobber (reg:CC FLAGS_REG))])
4190 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4191 "/* cltd is shorter than sarl $31, %eax */
4192 !optimize_function_for_size_p (cfun)
4193 && REGNO (operands[1]) == AX_REG
4194 && REGNO (operands[2]) == DX_REG
4195 && peep2_reg_dead_p (2, operands[1])
4196 && peep2_reg_dead_p (3, operands[2])
4197 && !reg_mentioned_p (operands[2], operands[3])"
4198 [(set (match_dup 0) (match_dup 1))
4199 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4200 (clobber (reg:CC FLAGS_REG))])
4201 (set (match_dup 3) (match_dup 1))])
4203 ;; Extend to register case. Optimize case where source and destination
4204 ;; registers match and cases where we can use cltd.
4206 [(set (match_operand:DI 0 "register_operand")
4207 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4208 (clobber (reg:CC FLAGS_REG))
4209 (clobber (match_scratch:SI 2))]
4213 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4215 if (REGNO (operands[3]) != REGNO (operands[1]))
4216 emit_move_insn (operands[3], operands[1]);
4218 /* Generate a cltd if possible and doing so it profitable. */
4219 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4220 && REGNO (operands[3]) == AX_REG
4221 && REGNO (operands[4]) == DX_REG)
4223 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4227 if (REGNO (operands[4]) != REGNO (operands[1]))
4228 emit_move_insn (operands[4], operands[1]);
4230 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4234 (define_insn "extend<mode>di2"
4235 [(set (match_operand:DI 0 "register_operand" "=r")
4237 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4239 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4240 [(set_attr "type" "imovx")
4241 (set_attr "mode" "DI")])
4243 (define_insn "extendhisi2"
4244 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4245 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4248 switch (get_attr_prefix_0f (insn))
4251 return "{cwtl|cwde}";
4253 return "movs{wl|x}\t{%1, %0|%0, %1}";
4256 [(set_attr "type" "imovx")
4257 (set_attr "mode" "SI")
4258 (set (attr "prefix_0f")
4259 ;; movsx is short decodable while cwtl is vector decoded.
4260 (if_then_else (and (eq_attr "cpu" "!k6")
4261 (eq_attr "alternative" "0"))
4263 (const_string "1")))
4264 (set (attr "znver1_decode")
4265 (if_then_else (eq_attr "prefix_0f" "0")
4266 (const_string "double")
4267 (const_string "direct")))
4269 (if_then_else (eq_attr "prefix_0f" "0")
4271 (const_string "1")))])
4273 (define_insn "*extendhisi2_zext"
4274 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4277 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4280 switch (get_attr_prefix_0f (insn))
4283 return "{cwtl|cwde}";
4285 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4288 [(set_attr "type" "imovx")
4289 (set_attr "mode" "SI")
4290 (set (attr "prefix_0f")
4291 ;; movsx is short decodable while cwtl is vector decoded.
4292 (if_then_else (and (eq_attr "cpu" "!k6")
4293 (eq_attr "alternative" "0"))
4295 (const_string "1")))
4297 (if_then_else (eq_attr "prefix_0f" "0")
4299 (const_string "1")))])
4301 (define_insn "extendqisi2"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4303 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4305 "movs{bl|x}\t{%1, %0|%0, %1}"
4306 [(set_attr "type" "imovx")
4307 (set_attr "mode" "SI")])
4309 (define_insn "*extendqisi2_zext"
4310 [(set (match_operand:DI 0 "register_operand" "=r")
4312 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4314 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4315 [(set_attr "type" "imovx")
4316 (set_attr "mode" "SI")])
4318 (define_insn "extendqihi2"
4319 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4323 switch (get_attr_prefix_0f (insn))
4326 return "{cbtw|cbw}";
4328 return "movs{bw|x}\t{%1, %0|%0, %1}";
4331 [(set_attr "type" "imovx")
4332 (set_attr "mode" "HI")
4333 (set (attr "prefix_0f")
4334 ;; movsx is short decodable while cwtl is vector decoded.
4335 (if_then_else (and (eq_attr "cpu" "!k6")
4336 (eq_attr "alternative" "0"))
4338 (const_string "1")))
4340 (if_then_else (eq_attr "prefix_0f" "0")
4342 (const_string "1")))])
4344 ;; Conversions between float and double.
4346 ;; These are all no-ops in the model used for the 80387.
4347 ;; So just emit moves.
4349 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4351 [(set (match_operand:DF 0 "push_operand")
4352 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4354 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4355 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4358 [(set (match_operand:XF 0 "push_operand")
4359 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4361 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4362 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4363 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4365 (define_expand "extendsfdf2"
4366 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4367 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4368 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4370 /* ??? Needed for compress_float_constant since all fp constants
4371 are TARGET_LEGITIMATE_CONSTANT_P. */
4372 if (CONST_DOUBLE_P (operands[1]))
4374 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4375 && standard_80387_constant_p (operands[1]) > 0)
4377 operands[1] = simplify_const_unary_operation
4378 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4379 emit_move_insn_1 (operands[0], operands[1]);
4382 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4386 (define_insn "*extendsfdf2"
4387 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4389 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4390 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4392 switch (which_alternative)
4396 return output_387_reg_move (insn, operands);
4399 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4401 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4407 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4408 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4409 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4410 (set_attr "mode" "SF,XF,DF,DF")
4411 (set (attr "enabled")
4413 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4415 (eq_attr "alternative" "0,1")
4416 (symbol_ref "TARGET_MIX_SSE_I387")
4417 (symbol_ref "true"))
4419 (eq_attr "alternative" "0,1")
4421 (symbol_ref "false"))))])
4423 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4425 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4427 We do the conversion post reload to avoid producing of 128bit spills
4428 that might lead to ICE on 32bit target. The sequence unlikely combine
4431 [(set (match_operand:DF 0 "sse_reg_operand")
4433 (match_operand:SF 1 "nonimmediate_operand")))]
4434 "TARGET_USE_VECTOR_FP_CONVERTS
4435 && optimize_insn_for_speed_p ()
4437 && (!EXT_REX_SSE_REG_P (operands[0])
4438 || TARGET_AVX512VL)"
4443 (parallel [(const_int 0) (const_int 1)]))))]
4445 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4446 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4447 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4448 Try to avoid move when unpacking can be done in source. */
4449 if (REG_P (operands[1]))
4451 /* If it is unsafe to overwrite upper half of source, we need
4452 to move to destination and unpack there. */
4453 if (REGNO (operands[0]) != REGNO (operands[1])
4454 || (EXT_REX_SSE_REG_P (operands[1])
4455 && !TARGET_AVX512VL))
4457 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4458 emit_move_insn (tmp, operands[1]);
4461 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4462 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4463 =v, v, then vbroadcastss will be only needed for AVX512F without
4465 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4466 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4470 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4471 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4475 emit_insn (gen_vec_setv4sf_0 (operands[3],
4476 CONST0_RTX (V4SFmode), operands[1]));
4479 ;; It's more profitable to split and then extend in the same register.
4481 [(set (match_operand:DF 0 "sse_reg_operand")
4483 (match_operand:SF 1 "memory_operand")))]
4484 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4485 && optimize_insn_for_speed_p ()"
4486 [(set (match_dup 2) (match_dup 1))
4487 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4488 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4490 ;; Break partial SSE register dependency stall. This splitter should split
4491 ;; late in the pass sequence (after register rename pass), so allocated
4492 ;; registers won't change anymore
4495 [(set (match_operand:DF 0 "sse_reg_operand")
4497 (match_operand:SF 1 "nonimmediate_operand")))]
4499 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4500 && optimize_function_for_speed_p (cfun)
4501 && (!REG_P (operands[1])
4502 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4503 && (!EXT_REX_SSE_REG_P (operands[0])
4504 || TARGET_AVX512VL)"
4513 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4514 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4517 (define_expand "extend<mode>xf2"
4518 [(set (match_operand:XF 0 "nonimmediate_operand")
4519 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4522 /* ??? Needed for compress_float_constant since all fp constants
4523 are TARGET_LEGITIMATE_CONSTANT_P. */
4524 if (CONST_DOUBLE_P (operands[1]))
4526 if (standard_80387_constant_p (operands[1]) > 0)
4528 operands[1] = simplify_const_unary_operation
4529 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4530 emit_move_insn_1 (operands[0], operands[1]);
4533 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4537 (define_insn "*extend<mode>xf2_i387"
4538 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4540 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4542 "* return output_387_reg_move (insn, operands);"
4543 [(set_attr "type" "fmov")
4544 (set_attr "mode" "<MODE>,XF")])
4546 ;; %%% This seems like bad news.
4547 ;; This cannot output into an f-reg because there is no way to be sure
4548 ;; of truncating in that case. Otherwise this is just like a simple move
4549 ;; insn. So we pretend we can output to a reg in order to get better
4550 ;; register preferencing, but we really use a stack slot.
4552 ;; Conversion from DFmode to SFmode.
4554 (define_insn "truncdfsf2"
4555 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4557 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4558 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4560 switch (which_alternative)
4564 return output_387_reg_move (insn, operands);
4567 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4569 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4575 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4576 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4577 (set_attr "mode" "SF")
4578 (set (attr "enabled")
4580 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4581 (cond [(eq_attr "alternative" "0")
4582 (symbol_ref "TARGET_MIX_SSE_I387")
4583 (eq_attr "alternative" "1")
4584 (symbol_ref "TARGET_MIX_SSE_I387
4585 && flag_unsafe_math_optimizations")
4587 (symbol_ref "true"))
4588 (cond [(eq_attr "alternative" "0")
4590 (eq_attr "alternative" "1")
4591 (symbol_ref "flag_unsafe_math_optimizations")
4593 (symbol_ref "false"))))])
4595 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4597 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4599 We do the conversion post reload to avoid producing of 128bit spills
4600 that might lead to ICE on 32bit target. The sequence unlikely combine
4603 [(set (match_operand:SF 0 "sse_reg_operand")
4605 (match_operand:DF 1 "nonimmediate_operand")))]
4606 "TARGET_USE_VECTOR_FP_CONVERTS
4607 && optimize_insn_for_speed_p ()
4609 && (!EXT_REX_SSE_REG_P (operands[0])
4610 || TARGET_AVX512VL)"
4613 (float_truncate:V2SF
4617 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4618 operands[3] = CONST0_RTX (V2SFmode);
4619 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4620 /* Use movsd for loading from memory, unpcklpd for registers.
4621 Try to avoid move when unpacking can be done in source, or SSE3
4622 movddup is available. */
4623 if (REG_P (operands[1]))
4626 && REGNO (operands[0]) != REGNO (operands[1]))
4628 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4629 emit_move_insn (tmp, operands[1]);
4632 else if (!TARGET_SSE3)
4633 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4634 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4637 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4638 CONST0_RTX (DFmode)));
4641 ;; It's more profitable to split and then truncate in the same register.
4643 [(set (match_operand:SF 0 "sse_reg_operand")
4645 (match_operand:DF 1 "memory_operand")))]
4646 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4647 && optimize_insn_for_speed_p ()"
4648 [(set (match_dup 2) (match_dup 1))
4649 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4650 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4652 ;; Break partial SSE register dependency stall. This splitter should split
4653 ;; late in the pass sequence (after register rename pass), so allocated
4654 ;; registers won't change anymore
4657 [(set (match_operand:SF 0 "sse_reg_operand")
4659 (match_operand:DF 1 "nonimmediate_operand")))]
4661 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4662 && optimize_function_for_speed_p (cfun)
4663 && (!REG_P (operands[1])
4664 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4665 && (!EXT_REX_SSE_REG_P (operands[0])
4666 || TARGET_AVX512VL)"
4675 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4676 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4679 ;; Conversion from XFmode to {SF,DF}mode
4681 (define_insn "truncxf<mode>2"
4682 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4683 (float_truncate:MODEF
4684 (match_operand:XF 1 "register_operand" "f,f")))]
4686 "* return output_387_reg_move (insn, operands);"
4687 [(set_attr "type" "fmov")
4688 (set_attr "mode" "<MODE>")
4689 (set (attr "enabled")
4690 (cond [(eq_attr "alternative" "1")
4691 (symbol_ref "flag_unsafe_math_optimizations")
4693 (symbol_ref "true")))])
4695 ;; Signed conversion to DImode.
4697 (define_expand "fix_truncxfdi2"
4698 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4699 (fix:DI (match_operand:XF 1 "register_operand")))
4700 (clobber (reg:CC FLAGS_REG))])]
4705 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4710 (define_expand "fix_trunc<mode>di2"
4711 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4712 (fix:DI (match_operand:MODEF 1 "register_operand")))
4713 (clobber (reg:CC FLAGS_REG))])]
4714 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4717 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4719 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4722 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4724 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4725 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4726 if (out != operands[0])
4727 emit_move_insn (operands[0], out);
4732 ;; Signed conversion to SImode.
4734 (define_expand "fix_truncxfsi2"
4735 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4736 (fix:SI (match_operand:XF 1 "register_operand")))
4737 (clobber (reg:CC FLAGS_REG))])]
4742 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4747 (define_expand "fix_trunc<mode>si2"
4748 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4749 (fix:SI (match_operand:MODEF 1 "register_operand")))
4750 (clobber (reg:CC FLAGS_REG))])]
4751 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4754 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4756 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4759 if (SSE_FLOAT_MODE_P (<MODE>mode))
4761 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4762 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4763 if (out != operands[0])
4764 emit_move_insn (operands[0], out);
4769 ;; Signed conversion to HImode.
4771 (define_expand "fix_trunc<mode>hi2"
4772 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4773 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4774 (clobber (reg:CC FLAGS_REG))])]
4776 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4780 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4785 ;; Unsigned conversion to DImode
4787 (define_insn "fixuns_trunc<mode>di2"
4788 [(set (match_operand:DI 0 "register_operand" "=r")
4790 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4791 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4792 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4793 [(set_attr "type" "sseicvt")
4794 (set_attr "prefix" "evex")
4795 (set_attr "mode" "DI")])
4797 ;; Unsigned conversion to SImode.
4799 (define_expand "fixuns_trunc<mode>si2"
4801 [(set (match_operand:SI 0 "register_operand")
4803 (match_operand:MODEF 1 "nonimmediate_operand")))
4805 (clobber (match_scratch:<ssevecmode> 3))
4806 (clobber (match_scratch:<ssevecmode> 4))])]
4807 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4809 machine_mode mode = <MODE>mode;
4810 machine_mode vecmode = <ssevecmode>mode;
4811 REAL_VALUE_TYPE TWO31r;
4816 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4820 if (optimize_insn_for_size_p ())
4823 real_ldexp (&TWO31r, &dconst1, 31);
4824 two31 = const_double_from_real_value (TWO31r, mode);
4825 two31 = ix86_build_const_vector (vecmode, true, two31);
4826 operands[2] = force_reg (vecmode, two31);
4829 (define_insn "fixuns_trunc<mode>si2_avx512f"
4830 [(set (match_operand:SI 0 "register_operand" "=r")
4832 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4833 "TARGET_AVX512F && TARGET_SSE_MATH"
4834 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4835 [(set_attr "type" "sseicvt")
4836 (set_attr "prefix" "evex")
4837 (set_attr "mode" "SI")])
4839 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4840 [(set (match_operand:DI 0 "register_operand" "=r")
4843 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4844 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4845 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4846 [(set_attr "type" "sseicvt")
4847 (set_attr "prefix" "evex")
4848 (set_attr "mode" "SI")])
4850 (define_insn_and_split "*fixuns_trunc<mode>_1"
4851 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4853 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4854 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4855 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4856 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4857 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4858 && optimize_function_for_speed_p (cfun)"
4860 "&& reload_completed"
4863 ix86_split_convert_uns_si_sse (operands);
4867 ;; Unsigned conversion to HImode.
4868 ;; Without these patterns, we'll try the unsigned SI conversion which
4869 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4871 (define_expand "fixuns_trunc<mode>hi2"
4873 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4874 (set (match_operand:HI 0 "nonimmediate_operand")
4875 (subreg:HI (match_dup 2) 0))]
4876 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4877 "operands[2] = gen_reg_rtx (SImode);")
4879 ;; When SSE is available, it is always faster to use it!
4880 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4881 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4882 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4883 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4884 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4885 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4886 [(set_attr "type" "sseicvt")
4887 (set_attr "prefix" "maybe_vex")
4888 (set (attr "prefix_rex")
4890 (match_test "<SWI48:MODE>mode == DImode")
4892 (const_string "*")))
4893 (set_attr "mode" "<MODEF:MODE>")
4894 (set_attr "athlon_decode" "double,vector")
4895 (set_attr "amdfam10_decode" "double,double")
4896 (set_attr "bdver1_decode" "double,double")])
4898 ;; Avoid vector decoded forms of the instruction.
4900 [(match_scratch:MODEF 2 "x")
4901 (set (match_operand:SWI48 0 "register_operand")
4902 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4903 "TARGET_AVOID_VECTOR_DECODE
4904 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4905 && optimize_insn_for_speed_p ()"
4906 [(set (match_dup 2) (match_dup 1))
4907 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4909 (define_insn "fix_trunc<mode>_i387_fisttp"
4910 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4911 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4912 (clobber (match_scratch:XF 2 "=&f"))]
4913 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4915 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4916 && (TARGET_64BIT || <MODE>mode != DImode))
4917 && TARGET_SSE_MATH)"
4918 "* return output_fix_trunc (insn, operands, true);"
4919 [(set_attr "type" "fisttp")
4920 (set_attr "mode" "<MODE>")])
4922 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4923 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4924 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4925 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4926 ;; function in i386.c.
4927 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4928 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4929 (fix:SWI248x (match_operand 1 "register_operand")))
4930 (clobber (reg:CC FLAGS_REG))]
4931 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4933 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4934 && (TARGET_64BIT || <MODE>mode != DImode))
4935 && ix86_pre_reload_split ()"
4940 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4945 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4946 operands[2], operands[3]));
4949 [(set_attr "type" "fistp")
4950 (set_attr "i387_cw" "trunc")
4951 (set_attr "mode" "<MODE>")])
4953 (define_insn "fix_truncdi_i387"
4954 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4955 (fix:DI (match_operand 1 "register_operand" "f")))
4956 (use (match_operand:HI 2 "memory_operand" "m"))
4957 (use (match_operand:HI 3 "memory_operand" "m"))
4958 (clobber (match_scratch:XF 4 "=&f"))]
4959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4961 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4962 "* return output_fix_trunc (insn, operands, false);"
4963 [(set_attr "type" "fistp")
4964 (set_attr "i387_cw" "trunc")
4965 (set_attr "mode" "DI")])
4967 (define_insn "fix_trunc<mode>_i387"
4968 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4969 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4970 (use (match_operand:HI 2 "memory_operand" "m"))
4971 (use (match_operand:HI 3 "memory_operand" "m"))]
4972 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4974 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4975 "* return output_fix_trunc (insn, operands, false);"
4976 [(set_attr "type" "fistp")
4977 (set_attr "i387_cw" "trunc")
4978 (set_attr "mode" "<MODE>")])
4980 (define_insn "x86_fnstcw_1"
4981 [(set (match_operand:HI 0 "memory_operand" "=m")
4982 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4985 [(set (attr "length")
4986 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4987 (set_attr "mode" "HI")
4988 (set_attr "unit" "i387")
4989 (set_attr "bdver1_decode" "vector")])
4991 ;; Conversion between fixed point and floating point.
4993 ;; Even though we only accept memory inputs, the backend _really_
4994 ;; wants to be able to do this between registers. Thankfully, LRA
4995 ;; will fix this up for us during register allocation.
4997 (define_insn "floathi<mode>2"
4998 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4999 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5002 || TARGET_MIX_SSE_I387)"
5004 [(set_attr "type" "fmov")
5005 (set_attr "mode" "<MODE>")
5006 (set_attr "znver1_decode" "double")
5007 (set_attr "fp_int_src" "true")])
5009 (define_insn "float<SWI48x:mode>xf2"
5010 [(set (match_operand:XF 0 "register_operand" "=f")
5011 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5014 [(set_attr "type" "fmov")
5015 (set_attr "mode" "XF")
5016 (set_attr "znver1_decode" "double")
5017 (set_attr "fp_int_src" "true")])
5019 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5020 [(set (match_operand:MODEF 0 "register_operand")
5021 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5022 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5023 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5024 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5026 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5027 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5029 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5030 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5031 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5034 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5035 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5036 [(set_attr "type" "fmov,sseicvt,sseicvt")
5037 (set_attr "avx_partial_xmm_update" "false,true,true")
5038 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5039 (set_attr "mode" "<MODEF:MODE>")
5040 (set (attr "prefix_rex")
5042 (and (eq_attr "prefix" "maybe_vex")
5043 (match_test "<SWI48:MODE>mode == DImode"))
5045 (const_string "*")))
5046 (set_attr "unit" "i387,*,*")
5047 (set_attr "athlon_decode" "*,double,direct")
5048 (set_attr "amdfam10_decode" "*,vector,double")
5049 (set_attr "bdver1_decode" "*,double,direct")
5050 (set_attr "znver1_decode" "double,*,*")
5051 (set_attr "fp_int_src" "true")
5052 (set (attr "enabled")
5054 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5056 (eq_attr "alternative" "0")
5057 (symbol_ref "TARGET_MIX_SSE_I387
5058 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5060 (symbol_ref "true"))
5062 (eq_attr "alternative" "0")
5064 (symbol_ref "false"))))
5065 (set (attr "preferred_for_speed")
5066 (cond [(eq_attr "alternative" "1")
5067 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5068 (symbol_ref "true")))])
5070 (define_insn "*floatdi<MODEF:mode>2_i387"
5071 [(set (match_operand:MODEF 0 "register_operand" "=f")
5072 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5074 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5076 [(set_attr "type" "fmov")
5077 (set_attr "mode" "<MODEF:MODE>")
5078 (set_attr "znver1_decode" "double")
5079 (set_attr "fp_int_src" "true")])
5081 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5082 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5083 ;; alternative in sse2_loadld.
5085 [(set (match_operand:MODEF 0 "sse_reg_operand")
5086 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5088 && TARGET_USE_VECTOR_CONVERTS
5089 && optimize_function_for_speed_p (cfun)
5091 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5092 && (!EXT_REX_SSE_REG_P (operands[0])
5093 || TARGET_AVX512VL)"
5096 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5097 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5099 emit_insn (gen_sse2_loadld (operands[4],
5100 CONST0_RTX (V4SImode), operands[1]));
5102 if (<ssevecmode>mode == V4SFmode)
5103 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5105 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5109 ;; Avoid store forwarding (partial memory) stall penalty
5110 ;; by passing DImode value through XMM registers. */
5113 [(set (match_operand:X87MODEF 0 "register_operand")
5115 (match_operand:DI 1 "register_operand")))]
5116 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5117 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5118 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5119 && can_create_pseudo_p ()"
5122 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5123 (operands[0], operands[1],
5124 assign_386_stack_local (DImode, SLOT_TEMP)));
5128 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5129 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5131 (match_operand:DI 1 "register_operand" "r,r")))
5132 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5133 (clobber (match_scratch:V4SI 3 "=x,x"))
5134 (clobber (match_scratch:V4SI 4 "=X,x"))]
5135 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5136 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5137 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5139 "&& reload_completed"
5140 [(set (match_dup 2) (match_dup 3))
5141 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5143 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5144 Assemble the 64-bit DImode value in an xmm register. */
5145 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5146 gen_lowpart (SImode, operands[1])));
5148 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5149 gen_highpart (SImode, operands[1]),
5153 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5154 gen_highpart (SImode, operands[1])));
5155 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5158 operands[3] = gen_lowpart (DImode, operands[3]);
5160 [(set_attr "isa" "sse4,*")
5161 (set_attr "type" "multi")
5162 (set_attr "mode" "<X87MODEF:MODE>")
5163 (set_attr "unit" "i387")
5164 (set_attr "fp_int_src" "true")])
5166 ;; Break partial SSE register dependency stall. This splitter should split
5167 ;; late in the pass sequence (after register rename pass), so allocated
5168 ;; registers won't change anymore
5171 [(set (match_operand:MODEF 0 "sse_reg_operand")
5172 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5174 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5175 && optimize_function_for_speed_p (cfun)
5176 && (!EXT_REX_SSE_REG_P (operands[0])
5177 || TARGET_AVX512VL)"
5179 (vec_merge:<MODEF:ssevecmode>
5180 (vec_duplicate:<MODEF:ssevecmode>
5186 const machine_mode vmode = <MODEF:ssevecmode>mode;
5188 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5189 emit_move_insn (operands[0], CONST0_RTX (vmode));
5192 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5193 [(set (match_operand:MODEF 0 "register_operand")
5194 (unsigned_float:MODEF
5195 (match_operand:SWI12 1 "nonimmediate_operand")))]
5197 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5199 operands[1] = convert_to_mode (SImode, operands[1], 1);
5200 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5204 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5205 [(set (match_operand:MODEF 0 "register_operand" "=v")
5206 (unsigned_float:MODEF
5207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5208 "TARGET_AVX512F && TARGET_SSE_MATH"
5209 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5210 [(set_attr "type" "sseicvt")
5211 (set_attr "avx_partial_xmm_update" "true")
5212 (set_attr "prefix" "evex")
5213 (set_attr "mode" "<MODEF:MODE>")])
5215 ;; Avoid store forwarding (partial memory) stall penalty by extending
5216 ;; SImode value to DImode through XMM register instead of pushing two
5217 ;; SImode values to stack. Also note that fild loads from memory only.
5219 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5221 (unsigned_float:X87MODEF
5222 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5223 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5224 (clobber (match_scratch:DI 3 "=x"))]
5226 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5229 "&& reload_completed"
5230 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5231 (set (match_dup 2) (match_dup 3))
5233 (float:X87MODEF (match_dup 2)))]
5235 [(set_attr "type" "multi")
5236 (set_attr "mode" "<MODE>")])
5238 (define_expand "floatunssi<mode>2"
5239 [(set (match_operand:X87MODEF 0 "register_operand")
5240 (unsigned_float:X87MODEF
5241 (match_operand:SI 1 "nonimmediate_operand")))]
5243 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5244 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5245 || ((!TARGET_64BIT || TARGET_AVX512F)
5246 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5248 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5250 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5251 (operands[0], operands[1],
5252 assign_386_stack_local (DImode, SLOT_TEMP)));
5255 if (!TARGET_AVX512F)
5257 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5262 (define_expand "floatunsdisf2"
5263 [(set (match_operand:SF 0 "register_operand")
5265 (match_operand:DI 1 "nonimmediate_operand")))]
5266 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5268 if (!TARGET_AVX512F)
5270 x86_emit_floatuns (operands);
5275 (define_expand "floatunsdidf2"
5276 [(set (match_operand:DF 0 "register_operand")
5278 (match_operand:DI 1 "nonimmediate_operand")))]
5279 "((TARGET_64BIT && TARGET_AVX512F)
5280 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5281 && TARGET_SSE2 && TARGET_SSE_MATH"
5285 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5288 if (!TARGET_AVX512F)
5290 x86_emit_floatuns (operands);
5295 ;; Load effective address instructions
5297 (define_insn_and_split "*lea<mode>"
5298 [(set (match_operand:SWI48 0 "register_operand" "=r")
5299 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5302 if (SImode_address_operand (operands[1], VOIDmode))
5304 gcc_assert (TARGET_64BIT);
5305 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5308 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5310 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5313 machine_mode mode = <MODE>mode;
5316 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5317 change operands[] array behind our back. */
5318 pat = PATTERN (curr_insn);
5320 operands[0] = SET_DEST (pat);
5321 operands[1] = SET_SRC (pat);
5323 /* Emit all operations in SImode for zero-extended addresses. */
5324 if (SImode_address_operand (operands[1], VOIDmode))
5327 ix86_split_lea_for_addr (curr_insn, operands, mode);
5329 /* Zero-extend return register to DImode for zero-extended addresses. */
5330 if (mode != <MODE>mode)
5331 emit_insn (gen_zero_extendsidi2
5332 (operands[0], gen_lowpart (mode, operands[0])));
5336 [(set_attr "type" "lea")
5339 (match_operand 1 "SImode_address_operand")
5341 (const_string "<MODE>")))])
5345 (define_expand "add<mode>3"
5346 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5347 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5348 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5350 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5352 (define_insn_and_split "*add<dwi>3_doubleword"
5353 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5355 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5356 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5357 (clobber (reg:CC FLAGS_REG))]
5358 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5361 [(parallel [(set (reg:CCC FLAGS_REG)
5363 (plus:DWIH (match_dup 1) (match_dup 2))
5366 (plus:DWIH (match_dup 1) (match_dup 2)))])
5367 (parallel [(set (match_dup 3)
5370 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5373 (clobber (reg:CC FLAGS_REG))])]
5375 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5376 if (operands[2] == const0_rtx)
5378 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5383 (define_insn "*add<mode>_1"
5384 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5386 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5387 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5388 (clobber (reg:CC FLAGS_REG))]
5389 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5391 switch (get_attr_type (insn))
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (operands[2] == const1_rtx)
5399 return "inc{<imodesuffix>}\t%0";
5402 gcc_assert (operands[2] == constm1_rtx);
5403 return "dec{<imodesuffix>}\t%0";
5407 /* For most processors, ADD is faster than LEA. This alternative
5408 was added to use ADD as much as possible. */
5409 if (which_alternative == 2)
5410 std::swap (operands[1], operands[2]);
5412 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5413 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5414 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5416 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5420 (cond [(eq_attr "alternative" "3")
5421 (const_string "lea")
5422 (match_operand:SWI48 2 "incdec_operand")
5423 (const_string "incdec")
5425 (const_string "alu")))
5426 (set (attr "length_immediate")
5428 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5430 (const_string "*")))
5431 (set_attr "mode" "<MODE>")])
5433 ;; It may seem that nonimmediate operand is proper one for operand 1.
5434 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5435 ;; we take care in ix86_binary_operator_ok to not allow two memory
5436 ;; operands so proper swapping will be done in reload. This allow
5437 ;; patterns constructed from addsi_1 to match.
5439 (define_insn "addsi_1_zext"
5440 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5442 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5443 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5444 (clobber (reg:CC FLAGS_REG))]
5445 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5447 switch (get_attr_type (insn))
5453 if (operands[2] == const1_rtx)
5454 return "inc{l}\t%k0";
5457 gcc_assert (operands[2] == constm1_rtx);
5458 return "dec{l}\t%k0";
5462 /* For most processors, ADD is faster than LEA. This alternative
5463 was added to use ADD as much as possible. */
5464 if (which_alternative == 1)
5465 std::swap (operands[1], operands[2]);
5467 if (x86_maybe_negate_const_int (&operands[2], SImode))
5468 return "sub{l}\t{%2, %k0|%k0, %2}";
5470 return "add{l}\t{%2, %k0|%k0, %2}";
5474 (cond [(eq_attr "alternative" "2")
5475 (const_string "lea")
5476 (match_operand:SI 2 "incdec_operand")
5477 (const_string "incdec")
5479 (const_string "alu")))
5480 (set (attr "length_immediate")
5482 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5484 (const_string "*")))
5485 (set_attr "mode" "SI")])
5487 (define_insn "*addhi_1"
5488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5489 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5490 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5491 (clobber (reg:CC FLAGS_REG))]
5492 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5494 switch (get_attr_type (insn))
5500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501 if (operands[2] == const1_rtx)
5502 return "inc{w}\t%0";
5505 gcc_assert (operands[2] == constm1_rtx);
5506 return "dec{w}\t%0";
5510 /* For most processors, ADD is faster than LEA. This alternative
5511 was added to use ADD as much as possible. */
5512 if (which_alternative == 2)
5513 std::swap (operands[1], operands[2]);
5515 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5516 if (x86_maybe_negate_const_int (&operands[2], HImode))
5517 return "sub{w}\t{%2, %0|%0, %2}";
5519 return "add{w}\t{%2, %0|%0, %2}";
5523 (cond [(eq_attr "alternative" "3")
5524 (const_string "lea")
5525 (match_operand:HI 2 "incdec_operand")
5526 (const_string "incdec")
5528 (const_string "alu")))
5529 (set (attr "length_immediate")
5531 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5533 (const_string "*")))
5534 (set_attr "mode" "HI,HI,HI,SI")])
5536 (define_insn "*addqi_1"
5537 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5538 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5539 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5540 (clobber (reg:CC FLAGS_REG))]
5541 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5543 bool widen = (get_attr_mode (insn) != MODE_QI);
5545 switch (get_attr_type (insn))
5551 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5552 if (operands[2] == const1_rtx)
5553 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5556 gcc_assert (operands[2] == constm1_rtx);
5557 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5561 /* For most processors, ADD is faster than LEA. These alternatives
5562 were added to use ADD as much as possible. */
5563 if (which_alternative == 2 || which_alternative == 4)
5564 std::swap (operands[1], operands[2]);
5566 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5567 if (x86_maybe_negate_const_int (&operands[2], QImode))
5570 return "sub{l}\t{%2, %k0|%k0, %2}";
5572 return "sub{b}\t{%2, %0|%0, %2}";
5575 return "add{l}\t{%k2, %k0|%k0, %k2}";
5577 return "add{b}\t{%2, %0|%0, %2}";
5581 (cond [(eq_attr "alternative" "5")
5582 (const_string "lea")
5583 (match_operand:QI 2 "incdec_operand")
5584 (const_string "incdec")
5586 (const_string "alu")))
5587 (set (attr "length_immediate")
5589 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5591 (const_string "*")))
5592 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5593 ;; Potential partial reg stall on alternatives 3 and 4.
5594 (set (attr "preferred_for_speed")
5595 (cond [(eq_attr "alternative" "3,4")
5596 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5597 (symbol_ref "true")))])
5599 (define_insn "*add<mode>_1_slp"
5600 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5601 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5602 (match_operand:SWI12 2 "general_operand" "<r>mn")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5605 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
5606 && (rtx_equal_p (operands[0], operands[1])
5607 || rtx_equal_p (operands[0], operands[2]))"
5609 switch (get_attr_type (insn))
5612 if (operands[2] == const1_rtx)
5613 return "inc{<imodesuffix>}\t%0";
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{<imodesuffix>}\t%0";
5621 if (x86_maybe_negate_const_int (&operands[2], QImode))
5622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5628 (if_then_else (match_operand:QI 2 "incdec_operand")
5629 (const_string "incdec")
5630 (const_string "alu")))
5631 (set_attr "mode" "<MODE>")])
5633 ;; Split non destructive adds if we cannot use lea.
5635 [(set (match_operand:SWI48 0 "register_operand")
5636 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5637 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5638 (clobber (reg:CC FLAGS_REG))]
5639 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5640 [(set (match_dup 0) (match_dup 1))
5641 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5642 (clobber (reg:CC FLAGS_REG))])])
5644 ;; Split non destructive adds if we cannot use lea.
5646 [(set (match_operand:DI 0 "register_operand")
5648 (plus:SI (match_operand:SI 1 "register_operand")
5649 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5650 (clobber (reg:CC FLAGS_REG))]
5652 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5653 [(set (match_dup 3) (match_dup 1))
5654 (parallel [(set (match_dup 0)
5655 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5656 (clobber (reg:CC FLAGS_REG))])]
5657 "operands[3] = gen_lowpart (SImode, operands[0]);")
5659 ;; Convert add to the lea pattern to avoid flags dependency.
5661 [(set (match_operand:SWI 0 "register_operand")
5662 (plus:SWI (match_operand:SWI 1 "register_operand")
5663 (match_operand:SWI 2 "<nonmemory_operand>")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5667 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5669 if (<MODE>mode != <LEAMODE>mode)
5671 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5672 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5673 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5677 ;; Convert add to the lea pattern to avoid flags dependency.
5679 [(set (match_operand:DI 0 "register_operand")
5681 (plus:SI (match_operand:SI 1 "register_operand")
5682 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5683 (clobber (reg:CC FLAGS_REG))]
5684 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5686 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5688 (define_insn "*add<mode>_2"
5689 [(set (reg FLAGS_REG)
5692 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5693 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5695 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5696 (plus:SWI (match_dup 1) (match_dup 2)))]
5697 "ix86_match_ccmode (insn, CCGOCmode)
5698 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5700 switch (get_attr_type (insn))
5703 if (operands[2] == const1_rtx)
5704 return "inc{<imodesuffix>}\t%0";
5707 gcc_assert (operands[2] == constm1_rtx);
5708 return "dec{<imodesuffix>}\t%0";
5712 if (which_alternative == 2)
5713 std::swap (operands[1], operands[2]);
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5717 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5719 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5723 (if_then_else (match_operand:SWI 2 "incdec_operand")
5724 (const_string "incdec")
5725 (const_string "alu")))
5726 (set (attr "length_immediate")
5728 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5730 (const_string "*")))
5731 (set_attr "mode" "<MODE>")])
5733 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5734 (define_insn "*addsi_2_zext"
5735 [(set (reg FLAGS_REG)
5737 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5738 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5740 (set (match_operand:DI 0 "register_operand" "=r,r")
5741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5743 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5745 switch (get_attr_type (insn))
5748 if (operands[2] == const1_rtx)
5749 return "inc{l}\t%k0";
5752 gcc_assert (operands[2] == constm1_rtx);
5753 return "dec{l}\t%k0";
5757 if (which_alternative == 1)
5758 std::swap (operands[1], operands[2]);
5760 if (x86_maybe_negate_const_int (&operands[2], SImode))
5761 return "sub{l}\t{%2, %k0|%k0, %2}";
5763 return "add{l}\t{%2, %k0|%k0, %2}";
5767 (if_then_else (match_operand:SI 2 "incdec_operand")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set (attr "length_immediate")
5772 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5774 (const_string "*")))
5775 (set_attr "mode" "SI")])
5777 (define_insn "*add<mode>_3"
5778 [(set (reg FLAGS_REG)
5780 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5781 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5782 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5783 "ix86_match_ccmode (insn, CCZmode)
5784 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5786 switch (get_attr_type (insn))
5789 if (operands[2] == const1_rtx)
5790 return "inc{<imodesuffix>}\t%0";
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{<imodesuffix>}\t%0";
5798 if (which_alternative == 1)
5799 std::swap (operands[1], operands[2]);
5801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5802 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5803 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5805 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5809 (if_then_else (match_operand:SWI 2 "incdec_operand")
5810 (const_string "incdec")
5811 (const_string "alu")))
5812 (set (attr "length_immediate")
5814 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5816 (const_string "*")))
5817 (set_attr "mode" "<MODE>")])
5819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5820 (define_insn "*addsi_3_zext"
5821 [(set (reg FLAGS_REG)
5823 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5824 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5825 (set (match_operand:DI 0 "register_operand" "=r,r")
5826 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5827 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5828 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5830 switch (get_attr_type (insn))
5833 if (operands[2] == const1_rtx)
5834 return "inc{l}\t%k0";
5837 gcc_assert (operands[2] == constm1_rtx);
5838 return "dec{l}\t%k0";
5842 if (which_alternative == 1)
5843 std::swap (operands[1], operands[2]);
5845 if (x86_maybe_negate_const_int (&operands[2], SImode))
5846 return "sub{l}\t{%2, %k0|%k0, %2}";
5848 return "add{l}\t{%2, %k0|%k0, %2}";
5852 (if_then_else (match_operand:SI 2 "incdec_operand")
5853 (const_string "incdec")
5854 (const_string "alu")))
5855 (set (attr "length_immediate")
5857 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5859 (const_string "*")))
5860 (set_attr "mode" "SI")])
5862 ; For comparisons against 1, -1 and 128, we may generate better code
5863 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5864 ; is matched then. We can't accept general immediate, because for
5865 ; case of overflows, the result is messed up.
5866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5867 ; only for comparisons not depending on it.
5869 (define_insn "*adddi_4"
5870 [(set (reg FLAGS_REG)
5872 (match_operand:DI 1 "nonimmediate_operand" "0")
5873 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5874 (clobber (match_scratch:DI 0 "=rm"))]
5876 && ix86_match_ccmode (insn, CCGCmode)"
5878 switch (get_attr_type (insn))
5881 if (operands[2] == constm1_rtx)
5882 return "inc{q}\t%0";
5885 gcc_assert (operands[2] == const1_rtx);
5886 return "dec{q}\t%0";
5890 if (x86_maybe_negate_const_int (&operands[2], DImode))
5891 return "add{q}\t{%2, %0|%0, %2}";
5893 return "sub{q}\t{%2, %0|%0, %2}";
5897 (if_then_else (match_operand:DI 2 "incdec_operand")
5898 (const_string "incdec")
5899 (const_string "alu")))
5900 (set (attr "length_immediate")
5902 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5904 (const_string "*")))
5905 (set_attr "mode" "DI")])
5907 ; For comparisons against 1, -1 and 128, we may generate better code
5908 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5909 ; is matched then. We can't accept general immediate, because for
5910 ; case of overflows, the result is messed up.
5911 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5912 ; only for comparisons not depending on it.
5914 (define_insn "*add<mode>_4"
5915 [(set (reg FLAGS_REG)
5917 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5918 (match_operand:SWI124 2 "const_int_operand" "n")))
5919 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5920 "ix86_match_ccmode (insn, CCGCmode)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == constm1_rtx)
5926 return "inc{<imodesuffix>}\t%0";
5929 gcc_assert (operands[2] == const1_rtx);
5930 return "dec{<imodesuffix>}\t%0";
5934 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5935 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5937 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5941 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set (attr "length_immediate")
5946 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5948 (const_string "*")))
5949 (set_attr "mode" "<MODE>")])
5951 (define_insn "*add<mode>_5"
5952 [(set (reg FLAGS_REG)
5955 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5956 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5958 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5959 "ix86_match_ccmode (insn, CCGOCmode)
5960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5962 switch (get_attr_type (insn))
5965 if (operands[2] == const1_rtx)
5966 return "inc{<imodesuffix>}\t%0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{<imodesuffix>}\t%0";
5974 if (which_alternative == 1)
5975 std::swap (operands[1], operands[2]);
5977 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5978 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5979 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5981 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5985 (if_then_else (match_operand:SWI 2 "incdec_operand")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5992 (const_string "*")))
5993 (set_attr "mode" "<MODE>")])
5995 (define_insn "addqi_ext_1"
5996 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6002 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6005 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6006 (clobber (reg:CC FLAGS_REG))]
6007 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6008 rtx_equal_p (operands[0], operands[1])"
6010 switch (get_attr_type (insn))
6013 if (operands[2] == const1_rtx)
6014 return "inc{b}\t%h0";
6017 gcc_assert (operands[2] == constm1_rtx);
6018 return "dec{b}\t%h0";
6022 return "add{b}\t{%2, %h0|%h0, %2}";
6025 [(set_attr "isa" "*,nox64")
6027 (if_then_else (match_operand:QI 2 "incdec_operand")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "QI")])
6032 (define_insn "*addqi_ext_2"
6033 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6039 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6043 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6045 (const_int 8)) 0)) 0))
6046 (clobber (reg:CC FLAGS_REG))]
6047 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6048 rtx_equal_p (operands[0], operands[1])
6049 || rtx_equal_p (operands[0], operands[2])"
6050 "add{b}\t{%h2, %h0|%h0, %h2}"
6051 [(set_attr "type" "alu")
6052 (set_attr "mode" "QI")])
6054 ;; Add with jump on overflow.
6055 (define_expand "addv<mode>4"
6056 [(parallel [(set (reg:CCO FLAGS_REG)
6059 (match_operand:SWI 1 "nonimmediate_operand"))
6062 (plus:SWI (match_dup 1)
6063 (match_operand:SWI 2
6064 "<general_operand>")))))
6065 (set (match_operand:SWI 0 "register_operand")
6066 (plus:SWI (match_dup 1) (match_dup 2)))])
6067 (set (pc) (if_then_else
6068 (eq (reg:CCO FLAGS_REG) (const_int 0))
6069 (label_ref (match_operand 3))
6073 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6074 if (CONST_INT_P (operands[2]))
6075 operands[4] = operands[2];
6077 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6080 (define_insn "*addv<mode>4"
6081 [(set (reg:CCO FLAGS_REG)
6084 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6086 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6088 (plus:SWI (match_dup 1) (match_dup 2)))))
6089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6090 (plus:SWI (match_dup 1) (match_dup 2)))]
6091 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6092 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6093 [(set_attr "type" "alu")
6094 (set_attr "mode" "<MODE>")])
6096 (define_insn "*addv<mode>4_1"
6097 [(set (reg:CCO FLAGS_REG)
6100 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6101 (match_operand:<DWI> 3 "const_int_operand" "i"))
6105 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6106 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6107 (plus:SWI (match_dup 1) (match_dup 2)))]
6108 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6109 && CONST_INT_P (operands[2])
6110 && INTVAL (operands[2]) == INTVAL (operands[3])"
6111 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6112 [(set_attr "type" "alu")
6113 (set_attr "mode" "<MODE>")
6114 (set (attr "length_immediate")
6115 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6117 (match_test "<MODE_SIZE> == 8")
6119 (const_string "<MODE_SIZE>")))])
6121 (define_expand "uaddv<mode>4"
6122 [(parallel [(set (reg:CCC FLAGS_REG)
6125 (match_operand:SWI 1 "nonimmediate_operand")
6126 (match_operand:SWI 2 "<general_operand>"))
6128 (set (match_operand:SWI 0 "register_operand")
6129 (plus:SWI (match_dup 1) (match_dup 2)))])
6130 (set (pc) (if_then_else
6131 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6132 (label_ref (match_operand 3))
6135 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6137 ;; The lea patterns for modes less than 32 bits need to be matched by
6138 ;; several insns converted to real lea by splitters.
6140 (define_insn_and_split "*lea<mode>_general_1"
6141 [(set (match_operand:SWI12 0 "register_operand" "=r")
6143 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6144 (match_operand:SWI12 2 "register_operand" "r"))
6145 (match_operand:SWI12 3 "immediate_operand" "i")))]
6146 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6148 "&& reload_completed"
6151 (plus:SI (match_dup 1) (match_dup 2))
6154 operands[0] = gen_lowpart (SImode, operands[0]);
6155 operands[1] = gen_lowpart (SImode, operands[1]);
6156 operands[2] = gen_lowpart (SImode, operands[2]);
6157 operands[3] = gen_lowpart (SImode, operands[3]);
6159 [(set_attr "type" "lea")
6160 (set_attr "mode" "SI")])
6162 (define_insn_and_split "*lea<mode>_general_2"
6163 [(set (match_operand:SWI12 0 "register_operand" "=r")
6165 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6166 (match_operand 2 "const248_operand" "n"))
6167 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6168 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6170 "&& reload_completed"
6173 (mult:SI (match_dup 1) (match_dup 2))
6176 operands[0] = gen_lowpart (SImode, operands[0]);
6177 operands[1] = gen_lowpart (SImode, operands[1]);
6178 operands[3] = gen_lowpart (SImode, operands[3]);
6180 [(set_attr "type" "lea")
6181 (set_attr "mode" "SI")])
6183 (define_insn_and_split "*lea<mode>_general_2b"
6184 [(set (match_operand:SWI12 0 "register_operand" "=r")
6186 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6187 (match_operand 2 "const123_operand" "n"))
6188 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6189 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6191 "&& reload_completed"
6194 (ashift:SI (match_dup 1) (match_dup 2))
6197 operands[0] = gen_lowpart (SImode, operands[0]);
6198 operands[1] = gen_lowpart (SImode, operands[1]);
6199 operands[3] = gen_lowpart (SImode, operands[3]);
6201 [(set_attr "type" "lea")
6202 (set_attr "mode" "SI")])
6204 (define_insn_and_split "*lea<mode>_general_3"
6205 [(set (match_operand:SWI12 0 "register_operand" "=r")
6208 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6209 (match_operand 2 "const248_operand" "n"))
6210 (match_operand:SWI12 3 "register_operand" "r"))
6211 (match_operand:SWI12 4 "immediate_operand" "i")))]
6212 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6214 "&& reload_completed"
6218 (mult:SI (match_dup 1) (match_dup 2))
6222 operands[0] = gen_lowpart (SImode, operands[0]);
6223 operands[1] = gen_lowpart (SImode, operands[1]);
6224 operands[3] = gen_lowpart (SImode, operands[3]);
6225 operands[4] = gen_lowpart (SImode, operands[4]);
6227 [(set_attr "type" "lea")
6228 (set_attr "mode" "SI")])
6230 (define_insn_and_split "*lea<mode>_general_3b"
6231 [(set (match_operand:SWI12 0 "register_operand" "=r")
6234 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6235 (match_operand 2 "const123_operand" "n"))
6236 (match_operand:SWI12 3 "register_operand" "r"))
6237 (match_operand:SWI12 4 "immediate_operand" "i")))]
6238 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6240 "&& reload_completed"
6244 (ashift:SI (match_dup 1) (match_dup 2))
6248 operands[0] = gen_lowpart (SImode, operands[0]);
6249 operands[1] = gen_lowpart (SImode, operands[1]);
6250 operands[3] = gen_lowpart (SImode, operands[3]);
6251 operands[4] = gen_lowpart (SImode, operands[4]);
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6256 (define_insn_and_split "*lea<mode>_general_4"
6257 [(set (match_operand:SWI12 0 "register_operand" "=r")
6260 (match_operand:SWI12 1 "index_register_operand" "l")
6261 (match_operand 2 "const_0_to_3_operand" "n"))
6262 (match_operand 3 "const_int_operand" "n")))]
6263 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6264 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6265 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6267 "&& reload_completed"
6270 (mult:SI (match_dup 1) (match_dup 2))
6273 operands[0] = gen_lowpart (SImode, operands[0]);
6274 operands[1] = gen_lowpart (SImode, operands[1]);
6275 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6277 [(set_attr "type" "lea")
6278 (set_attr "mode" "SI")])
6280 (define_insn_and_split "*lea<mode>_general_4"
6281 [(set (match_operand:SWI48 0 "register_operand" "=r")
6284 (match_operand:SWI48 1 "index_register_operand" "l")
6285 (match_operand 2 "const_0_to_3_operand" "n"))
6286 (match_operand 3 "const_int_operand" "n")))]
6287 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6288 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6290 "&& reload_completed"
6293 (mult:SWI48 (match_dup 1) (match_dup 2))
6295 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6296 [(set_attr "type" "lea")
6297 (set_attr "mode" "<MODE>")])
6299 ;; Subtract instructions
6301 (define_expand "sub<mode>3"
6302 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6303 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6304 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6306 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6308 (define_insn_and_split "*sub<dwi>3_doubleword"
6309 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6311 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6312 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6313 (clobber (reg:CC FLAGS_REG))]
6314 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6317 [(parallel [(set (reg:CC FLAGS_REG)
6318 (compare:CC (match_dup 1) (match_dup 2)))
6320 (minus:DWIH (match_dup 1) (match_dup 2)))])
6321 (parallel [(set (match_dup 3)
6325 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6327 (clobber (reg:CC FLAGS_REG))])]
6329 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6330 if (operands[2] == const0_rtx)
6332 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6337 (define_insn "*sub<mode>_1"
6338 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6340 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6341 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6342 (clobber (reg:CC FLAGS_REG))]
6343 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6344 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6345 [(set_attr "type" "alu")
6346 (set_attr "mode" "<MODE>")])
6348 (define_insn "*subsi_1_zext"
6349 [(set (match_operand:DI 0 "register_operand" "=r")
6351 (minus:SI (match_operand:SI 1 "register_operand" "0")
6352 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6353 (clobber (reg:CC FLAGS_REG))]
6354 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6355 "sub{l}\t{%2, %k0|%k0, %2}"
6356 [(set_attr "type" "alu")
6357 (set_attr "mode" "SI")])
6359 (define_insn "*sub<mode>_1_slp"
6360 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6361 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6362 (match_operand:SWI12 2 "general_operand" "<r>mn")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6365 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
6366 && rtx_equal_p (operands[0], operands[1])"
6367 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6368 [(set_attr "type" "alu")
6369 (set_attr "mode" "<MODE>")])
6371 (define_insn "*sub<mode>_2"
6372 [(set (reg FLAGS_REG)
6375 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6376 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6379 (minus:SWI (match_dup 1) (match_dup 2)))]
6380 "ix86_match_ccmode (insn, CCGOCmode)
6381 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6382 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6383 [(set_attr "type" "alu")
6384 (set_attr "mode" "<MODE>")])
6386 (define_insn "*subsi_2_zext"
6387 [(set (reg FLAGS_REG)
6389 (minus:SI (match_operand:SI 1 "register_operand" "0")
6390 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6392 (set (match_operand:DI 0 "register_operand" "=r")
6394 (minus:SI (match_dup 1)
6396 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6397 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6398 "sub{l}\t{%2, %k0|%k0, %2}"
6399 [(set_attr "type" "alu")
6400 (set_attr "mode" "SI")])
6402 ;; Subtract with jump on overflow.
6403 (define_expand "subv<mode>4"
6404 [(parallel [(set (reg:CCO FLAGS_REG)
6405 (eq:CCO (minus:<DWI>
6407 (match_operand:SWI 1 "nonimmediate_operand"))
6410 (minus:SWI (match_dup 1)
6411 (match_operand:SWI 2
6412 "<general_operand>")))))
6413 (set (match_operand:SWI 0 "register_operand")
6414 (minus:SWI (match_dup 1) (match_dup 2)))])
6415 (set (pc) (if_then_else
6416 (eq (reg:CCO FLAGS_REG) (const_int 0))
6417 (label_ref (match_operand 3))
6421 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6422 if (CONST_INT_P (operands[2]))
6423 operands[4] = operands[2];
6425 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6428 (define_insn "*subv<mode>4"
6429 [(set (reg:CCO FLAGS_REG)
6430 (eq:CCO (minus:<DWI>
6432 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6434 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6436 (minus:SWI (match_dup 1) (match_dup 2)))))
6437 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6438 (minus:SWI (match_dup 1) (match_dup 2)))]
6439 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6440 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6441 [(set_attr "type" "alu")
6442 (set_attr "mode" "<MODE>")])
6444 (define_insn "*subv<mode>4_1"
6445 [(set (reg:CCO FLAGS_REG)
6446 (eq:CCO (minus:<DWI>
6448 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6449 (match_operand:<DWI> 3 "const_int_operand" "i"))
6453 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6454 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6455 (minus:SWI (match_dup 1) (match_dup 2)))]
6456 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6457 && CONST_INT_P (operands[2])
6458 && INTVAL (operands[2]) == INTVAL (operands[3])"
6459 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "mode" "<MODE>")
6462 (set (attr "length_immediate")
6463 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6465 (match_test "<MODE_SIZE> == 8")
6467 (const_string "<MODE_SIZE>")))])
6469 (define_expand "usubv<mode>4"
6470 [(parallel [(set (reg:CC FLAGS_REG)
6472 (match_operand:SWI 1 "nonimmediate_operand")
6473 (match_operand:SWI 2 "<general_operand>")))
6474 (set (match_operand:SWI 0 "register_operand")
6475 (minus:SWI (match_dup 1) (match_dup 2)))])
6476 (set (pc) (if_then_else
6477 (ltu (reg:CC FLAGS_REG) (const_int 0))
6478 (label_ref (match_operand 3))
6481 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6483 (define_insn "*sub<mode>_3"
6484 [(set (reg FLAGS_REG)
6485 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6487 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6488 (minus:SWI (match_dup 1) (match_dup 2)))]
6489 "ix86_match_ccmode (insn, CCmode)
6490 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6497 [(set (reg:CC FLAGS_REG)
6498 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6499 (match_operand:SWI 1 "general_gr_operand")))
6501 (minus:SWI (match_dup 0) (match_dup 1)))])]
6502 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6503 [(set (reg:CC FLAGS_REG)
6504 (compare:CC (match_dup 0) (match_dup 1)))])
6506 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6507 ;; subl $1, %eax; jnc .Lxx;
6510 [(set (match_operand:SWI 0 "general_reg_operand")
6511 (plus:SWI (match_dup 0) (const_int -1)))
6512 (clobber (reg FLAGS_REG))])
6513 (set (reg:CCZ FLAGS_REG)
6514 (compare:CCZ (match_dup 0) (const_int -1)))
6516 (if_then_else (match_operator 1 "bt_comparison_operator"
6517 [(reg:CCZ FLAGS_REG) (const_int 0)])
6520 "peep2_regno_dead_p (3, FLAGS_REG)"
6522 [(set (reg:CC FLAGS_REG)
6523 (compare:CC (match_dup 0) (const_int 1)))
6525 (minus:SWI (match_dup 0) (const_int 1)))])
6527 (if_then_else (match_dup 3)
6531 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6532 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6533 ? GEU : LTU, VOIDmode, cc, const0_rtx);
6536 (define_insn "*subsi_3_zext"
6537 [(set (reg FLAGS_REG)
6538 (compare (match_operand:SI 1 "register_operand" "0")
6539 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6540 (set (match_operand:DI 0 "register_operand" "=r")
6542 (minus:SI (match_dup 1)
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6545 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546 "sub{l}\t{%2, %1|%1, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "SI")])
6550 ;; Add with carry and subtract with borrow
6552 (define_insn "@add<mode>3_carry"
6553 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6556 (match_operator:SWI 4 "ix86_carry_flag_operator"
6557 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6558 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "adc{<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 "*add<mode>3_carry_0"
6569 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6571 (match_operator:SWI 3 "ix86_carry_flag_operator"
6572 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6573 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6574 (clobber (reg:CC FLAGS_REG))]
6575 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6576 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6577 [(set_attr "type" "alu")
6578 (set_attr "use_carry" "1")
6579 (set_attr "pent_pair" "pu")
6580 (set_attr "mode" "<MODE>")])
6582 (define_insn "*addsi3_carry_zext"
6583 [(set (match_operand:DI 0 "register_operand" "=r")
6586 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6587 [(reg FLAGS_REG) (const_int 0)])
6588 (match_operand:SI 1 "register_operand" "%0"))
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6590 (clobber (reg:CC FLAGS_REG))]
6591 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6592 "adc{l}\t{%2, %k0|%k0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "use_carry" "1")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6598 (define_insn "*addsi3_carry_zext_0"
6599 [(set (match_operand:DI 0 "register_operand" "=r")
6601 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6602 [(reg FLAGS_REG) (const_int 0)])
6603 (match_operand:SI 1 "register_operand" "0"))))
6604 (clobber (reg:CC FLAGS_REG))]
6606 "adc{l}\t{$0, %k0|%k0, 0}"
6607 [(set_attr "type" "alu")
6608 (set_attr "use_carry" "1")
6609 (set_attr "pent_pair" "pu")
6610 (set_attr "mode" "SI")])
6612 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6614 (define_insn "addcarry<mode>"
6615 [(set (reg:CCC FLAGS_REG)
6620 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6621 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6622 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6623 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6625 (zero_extend:<DWI> (match_dup 2))
6626 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6627 [(match_dup 3) (const_int 0)]))))
6628 (set (match_operand:SWI48 0 "register_operand" "=r")
6629 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6630 [(match_dup 3) (const_int 0)])
6633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6634 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "use_carry" "1")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "<MODE>")])
6640 (define_expand "addcarry<mode>_0"
6642 [(set (reg:CCC FLAGS_REG)
6645 (match_operand:SWI48 1 "nonimmediate_operand")
6646 (match_operand:SWI48 2 "x86_64_general_operand"))
6648 (set (match_operand:SWI48 0 "register_operand")
6649 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6650 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6652 (define_insn "@sub<mode>3_carry"
6653 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6656 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6657 (match_operator:SWI 4 "ix86_carry_flag_operator"
6658 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6659 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6662 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "use_carry" "1")
6665 (set_attr "pent_pair" "pu")
6666 (set_attr "mode" "<MODE>")])
6668 (define_insn "*sub<mode>3_carry_0"
6669 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6671 (match_operand:SWI 1 "nonimmediate_operand" "0")
6672 (match_operator:SWI 3 "ix86_carry_flag_operator"
6673 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6676 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6677 [(set_attr "type" "alu")
6678 (set_attr "use_carry" "1")
6679 (set_attr "pent_pair" "pu")
6680 (set_attr "mode" "<MODE>")])
6682 (define_insn "*subsi3_carry_zext"
6683 [(set (match_operand:DI 0 "register_operand" "=r")
6687 (match_operand:SI 1 "register_operand" "0")
6688 (match_operator:SI 3 "ix86_carry_flag_operator"
6689 [(reg FLAGS_REG) (const_int 0)]))
6690 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6691 (clobber (reg:CC FLAGS_REG))]
6692 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sbb{l}\t{%2, %k0|%k0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "use_carry" "1")
6696 (set_attr "pent_pair" "pu")
6697 (set_attr "mode" "SI")])
6699 (define_insn "*subsi3_carry_zext_0"
6700 [(set (match_operand:DI 0 "register_operand" "=r")
6703 (match_operand:SI 1 "register_operand" "0")
6704 (match_operator:SI 2 "ix86_carry_flag_operator"
6705 [(reg FLAGS_REG) (const_int 0)]))))
6706 (clobber (reg:CC FLAGS_REG))]
6708 "sbb{l}\t{$0, %k0|%k0, 0}"
6709 [(set_attr "type" "alu")
6710 (set_attr "use_carry" "1")
6711 (set_attr "pent_pair" "pu")
6712 (set_attr "mode" "SI")])
6714 (define_insn "@sub<mode>3_carry_ccc"
6715 [(set (reg:CCC FLAGS_REG)
6717 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6719 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6721 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6722 (clobber (match_scratch:DWIH 0 "=r"))]
6724 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6728 (define_insn "*sub<mode>3_carry_ccc_1"
6729 [(set (reg:CCC FLAGS_REG)
6731 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6733 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6734 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6735 (clobber (match_scratch:DWIH 0 "=r"))]
6738 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6739 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "<MODE>")])
6744 ;; The sign flag is set from the
6745 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6746 ;; result, the overflow flag likewise, but the overflow flag is also
6747 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6748 (define_insn "@sub<mode>3_carry_ccgz"
6749 [(set (reg:CCGZ FLAGS_REG)
6750 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6751 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6752 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6754 (clobber (match_scratch:DWIH 0 "=r"))]
6756 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "<MODE>")])
6760 (define_insn "subborrow<mode>"
6761 [(set (reg:CCC FLAGS_REG)
6764 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6766 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6767 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6769 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6770 (set (match_operand:SWI48 0 "register_operand" "=r")
6771 (minus:SWI48 (minus:SWI48
6773 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6774 [(match_dup 3) (const_int 0)]))
6776 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6777 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "use_carry" "1")
6780 (set_attr "pent_pair" "pu")
6781 (set_attr "mode" "<MODE>")])
6783 (define_expand "subborrow<mode>_0"
6785 [(set (reg:CC FLAGS_REG)
6787 (match_operand:SWI48 1 "nonimmediate_operand")
6788 (match_operand:SWI48 2 "<general_operand>")))
6789 (set (match_operand:SWI48 0 "register_operand")
6790 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6791 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6793 ;; Overflow setting add instructions
6795 (define_expand "addqi3_cconly_overflow"
6797 [(set (reg:CCC FLAGS_REG)
6800 (match_operand:QI 0 "nonimmediate_operand")
6801 (match_operand:QI 1 "general_operand"))
6803 (clobber (match_scratch:QI 2))])]
6804 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6806 (define_insn "*add<mode>3_cconly_overflow_1"
6807 [(set (reg:CCC FLAGS_REG)
6810 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6811 (match_operand:SWI 2 "<general_operand>" "<g>"))
6813 (clobber (match_scratch:SWI 0 "=<r>"))]
6814 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6816 [(set_attr "type" "alu")
6817 (set_attr "mode" "<MODE>")])
6819 (define_insn "*add<mode>3_cc_overflow_1"
6820 [(set (reg:CCC FLAGS_REG)
6823 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6824 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6827 (plus:SWI (match_dup 1) (match_dup 2)))]
6828 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6829 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "<MODE>")])
6833 (define_insn "*addsi3_zext_cc_overflow_1"
6834 [(set (reg:CCC FLAGS_REG)
6837 (match_operand:SI 1 "nonimmediate_operand" "%0")
6838 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6840 (set (match_operand:DI 0 "register_operand" "=r")
6841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6842 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6843 "add{l}\t{%2, %k0|%k0, %2}"
6844 [(set_attr "type" "alu")
6845 (set_attr "mode" "SI")])
6847 (define_insn "*add<mode>3_cconly_overflow_2"
6848 [(set (reg:CCC FLAGS_REG)
6851 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6852 (match_operand:SWI 2 "<general_operand>" "<g>"))
6854 (clobber (match_scratch:SWI 0 "=<r>"))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6857 [(set_attr "type" "alu")
6858 (set_attr "mode" "<MODE>")])
6860 (define_insn "*add<mode>3_cc_overflow_2"
6861 [(set (reg:CCC FLAGS_REG)
6864 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6865 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6867 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6868 (plus:SWI (match_dup 1) (match_dup 2)))]
6869 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6870 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6871 [(set_attr "type" "alu")
6872 (set_attr "mode" "<MODE>")])
6874 (define_insn "*addsi3_zext_cc_overflow_2"
6875 [(set (reg:CCC FLAGS_REG)
6878 (match_operand:SI 1 "nonimmediate_operand" "%0")
6879 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6881 (set (match_operand:DI 0 "register_operand" "=r")
6882 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6883 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6884 "add{l}\t{%2, %k0|%k0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "mode" "SI")])
6888 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
6889 ;; test, where the latter is preferrable if we have some carry consuming
6891 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
6893 (define_insn_and_split "*add<mode>3_eq"
6894 [(set (match_operand:SWI 0 "nonimmediate_operand")
6897 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
6898 (match_operand:SWI 1 "nonimmediate_operand"))
6899 (match_operand:SWI 2 "<general_operand>")))
6900 (clobber (reg:CC FLAGS_REG))]
6901 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6902 && ix86_pre_reload_split ()"
6905 [(set (reg:CC FLAGS_REG)
6906 (compare:CC (match_dup 3) (const_int 1)))
6907 (parallel [(set (match_dup 0)
6909 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
6912 (clobber (reg:CC FLAGS_REG))])])
6914 (define_insn_and_split "*add<mode>3_ne"
6915 [(set (match_operand:SWI 0 "nonimmediate_operand")
6918 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
6919 (match_operand:SWI 1 "nonimmediate_operand"))
6920 (match_operand:SWI 2 "<immediate_operand>")))
6921 (clobber (reg:CC FLAGS_REG))]
6922 "CONST_INT_P (operands[2])
6923 && (<MODE>mode != DImode
6924 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
6925 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6926 && ix86_pre_reload_split ()"
6929 [(set (reg:CC FLAGS_REG)
6930 (compare:CC (match_dup 3) (const_int 1)))
6931 (parallel [(set (match_dup 0)
6933 (minus:SWI (match_dup 1)
6934 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
6936 (clobber (reg:CC FLAGS_REG))])]
6938 operands[2] = gen_int_mode (~INTVAL (operands[2]),
6939 <MODE>mode == DImode ? SImode : <MODE>mode);
6942 (define_insn_and_split "*add<mode>3_eq_0"
6943 [(set (match_operand:SWI 0 "nonimmediate_operand")
6945 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
6946 (match_operand:SWI 1 "<general_operand>")))
6947 (clobber (reg:CC FLAGS_REG))]
6948 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
6949 && ix86_pre_reload_split ()"
6952 [(set (reg:CC FLAGS_REG)
6953 (compare:CC (match_dup 2) (const_int 1)))
6954 (parallel [(set (match_dup 0)
6955 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
6957 (clobber (reg:CC FLAGS_REG))])]
6959 if (!nonimmediate_operand (operands[1], <MODE>mode))
6960 operands[1] = force_reg (<MODE>mode, operands[1]);
6963 (define_insn_and_split "*add<mode>3_ne_0"
6964 [(set (match_operand:SWI 0 "nonimmediate_operand")
6966 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
6967 (match_operand:SWI 1 "<general_operand>")))
6968 (clobber (reg:CC FLAGS_REG))]
6969 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
6970 && ix86_pre_reload_split ()"
6973 [(set (reg:CC FLAGS_REG)
6974 (compare:CC (match_dup 2) (const_int 1)))
6975 (parallel [(set (match_dup 0)
6976 (minus:SWI (minus:SWI
6978 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
6980 (clobber (reg:CC FLAGS_REG))])]
6982 if (!nonimmediate_operand (operands[1], <MODE>mode))
6983 operands[1] = force_reg (<MODE>mode, operands[1]);
6986 (define_insn_and_split "*sub<mode>3_eq"
6987 [(set (match_operand:SWI 0 "nonimmediate_operand")
6990 (match_operand:SWI 1 "nonimmediate_operand")
6991 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
6993 (match_operand:SWI 2 "<general_operand>")))
6994 (clobber (reg:CC FLAGS_REG))]
6995 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6996 && ix86_pre_reload_split ()"
6999 [(set (reg:CC FLAGS_REG)
7000 (compare:CC (match_dup 3) (const_int 1)))
7001 (parallel [(set (match_dup 0)
7003 (minus:SWI (match_dup 1)
7004 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7006 (clobber (reg:CC FLAGS_REG))])])
7008 (define_insn_and_split "*sub<mode>3_ne"
7009 [(set (match_operand:SWI 0 "nonimmediate_operand")
7012 (match_operand:SWI 1 "nonimmediate_operand")
7013 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7015 (match_operand:SWI 2 "<immediate_operand>")))
7016 (clobber (reg:CC FLAGS_REG))]
7017 "CONST_INT_P (operands[2])
7018 && (<MODE>mode != DImode
7019 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7020 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7021 && ix86_pre_reload_split ()"
7024 [(set (reg:CC FLAGS_REG)
7025 (compare:CC (match_dup 3) (const_int 1)))
7026 (parallel [(set (match_dup 0)
7028 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7031 (clobber (reg:CC FLAGS_REG))])]
7033 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7034 <MODE>mode == DImode ? SImode : <MODE>mode);
7037 (define_insn_and_split "*sub<mode>3_eq_1"
7038 [(set (match_operand:SWI 0 "nonimmediate_operand")
7041 (match_operand:SWI 1 "nonimmediate_operand")
7042 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7044 (match_operand:SWI 2 "<immediate_operand>")))
7045 (clobber (reg:CC FLAGS_REG))]
7046 "CONST_INT_P (operands[2])
7047 && (<MODE>mode != DImode
7048 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7049 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7050 && ix86_pre_reload_split ()"
7053 [(set (reg:CC FLAGS_REG)
7054 (compare:CC (match_dup 3) (const_int 1)))
7055 (parallel [(set (match_dup 0)
7057 (minus:SWI (match_dup 1)
7058 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7060 (clobber (reg:CC FLAGS_REG))])]
7062 operands[2] = gen_int_mode (-INTVAL (operands[2]),
7063 <MODE>mode == DImode ? SImode : <MODE>mode);
7066 (define_insn_and_split "*sub<mode>3_eq_0"
7067 [(set (match_operand:SWI 0 "nonimmediate_operand")
7069 (match_operand:SWI 1 "<general_operand>")
7070 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7071 (clobber (reg:CC FLAGS_REG))]
7072 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7073 && ix86_pre_reload_split ()"
7076 [(set (reg:CC FLAGS_REG)
7077 (compare:CC (match_dup 2) (const_int 1)))
7078 (parallel [(set (match_dup 0)
7079 (minus:SWI (match_dup 1)
7080 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7081 (clobber (reg:CC FLAGS_REG))])]
7083 if (!nonimmediate_operand (operands[1], <MODE>mode))
7084 operands[1] = force_reg (<MODE>mode, operands[1]);
7087 (define_insn_and_split "*sub<mode>3_ne_0"
7088 [(set (match_operand:SWI 0 "nonimmediate_operand")
7090 (match_operand:SWI 1 "<general_operand>")
7091 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7094 && ix86_pre_reload_split ()"
7097 [(set (reg:CC FLAGS_REG)
7098 (compare:CC (match_dup 2) (const_int 1)))
7099 (parallel [(set (match_dup 0)
7101 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7104 (clobber (reg:CC FLAGS_REG))])]
7106 if (!nonimmediate_operand (operands[1], <MODE>mode))
7107 operands[1] = force_reg (<MODE>mode, operands[1]);
7110 ;; The patterns that match these are at the end of this file.
7112 (define_expand "<plusminus_insn>xf3"
7113 [(set (match_operand:XF 0 "register_operand")
7115 (match_operand:XF 1 "register_operand")
7116 (match_operand:XF 2 "register_operand")))]
7119 (define_expand "<plusminus_insn><mode>3"
7120 [(set (match_operand:MODEF 0 "register_operand")
7122 (match_operand:MODEF 1 "register_operand")
7123 (match_operand:MODEF 2 "nonimmediate_operand")))]
7124 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7125 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7127 ;; Multiply instructions
7129 (define_expand "mul<mode>3"
7130 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7132 (match_operand:SWIM248 1 "register_operand")
7133 (match_operand:SWIM248 2 "<general_operand>")))
7134 (clobber (reg:CC FLAGS_REG))])])
7136 (define_expand "mulqi3"
7137 [(parallel [(set (match_operand:QI 0 "register_operand")
7139 (match_operand:QI 1 "register_operand")
7140 (match_operand:QI 2 "nonimmediate_operand")))
7141 (clobber (reg:CC FLAGS_REG))])]
7142 "TARGET_QIMODE_MATH")
7145 ;; IMUL reg32/64, reg32/64, imm8 Direct
7146 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7147 ;; IMUL reg32/64, reg32/64, imm32 Direct
7148 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7149 ;; IMUL reg32/64, reg32/64 Direct
7150 ;; IMUL reg32/64, mem32/64 Direct
7152 ;; On BDVER1, all above IMULs use DirectPath
7155 ;; IMUL reg16, reg16, imm8 VectorPath
7156 ;; IMUL reg16, mem16, imm8 VectorPath
7157 ;; IMUL reg16, reg16, imm16 VectorPath
7158 ;; IMUL reg16, mem16, imm16 VectorPath
7159 ;; IMUL reg16, reg16 Direct
7160 ;; IMUL reg16, mem16 Direct
7162 ;; On BDVER1, all HI MULs use DoublePath
7164 (define_insn "*mul<mode>3_1"
7165 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7167 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7168 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7172 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7173 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7174 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7175 [(set_attr "type" "imul")
7176 (set_attr "prefix_0f" "0,0,1")
7177 (set (attr "athlon_decode")
7178 (cond [(eq_attr "cpu" "athlon")
7179 (const_string "vector")
7180 (eq_attr "alternative" "1")
7181 (const_string "vector")
7182 (and (eq_attr "alternative" "2")
7183 (ior (match_test "<MODE>mode == HImode")
7184 (match_operand 1 "memory_operand")))
7185 (const_string "vector")]
7186 (const_string "direct")))
7187 (set (attr "amdfam10_decode")
7188 (cond [(and (eq_attr "alternative" "0,1")
7189 (ior (match_test "<MODE>mode == HImode")
7190 (match_operand 1 "memory_operand")))
7191 (const_string "vector")]
7192 (const_string "direct")))
7193 (set (attr "bdver1_decode")
7195 (match_test "<MODE>mode == HImode")
7196 (const_string "double")
7197 (const_string "direct")))
7198 (set_attr "mode" "<MODE>")])
7200 (define_insn "*mulsi3_1_zext"
7201 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7203 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7204 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7205 (clobber (reg:CC FLAGS_REG))]
7207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7209 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7210 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7211 imul{l}\t{%2, %k0|%k0, %2}"
7212 [(set_attr "type" "imul")
7213 (set_attr "prefix_0f" "0,0,1")
7214 (set (attr "athlon_decode")
7215 (cond [(eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (eq_attr "alternative" "1")
7218 (const_string "vector")
7219 (and (eq_attr "alternative" "2")
7220 (match_operand 1 "memory_operand"))
7221 (const_string "vector")]
7222 (const_string "direct")))
7223 (set (attr "amdfam10_decode")
7224 (cond [(and (eq_attr "alternative" "0,1")
7225 (match_operand 1 "memory_operand"))
7226 (const_string "vector")]
7227 (const_string "direct")))
7228 (set_attr "bdver1_decode" "direct")
7229 (set_attr "mode" "SI")])
7231 ;;On AMDFAM10 and BDVER1
7235 (define_insn "*mulqi3_1"
7236 [(set (match_operand:QI 0 "register_operand" "=a")
7237 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7238 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7239 (clobber (reg:CC FLAGS_REG))]
7241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7243 [(set_attr "type" "imul")
7244 (set_attr "length_immediate" "0")
7245 (set (attr "athlon_decode")
7246 (if_then_else (eq_attr "cpu" "athlon")
7247 (const_string "vector")
7248 (const_string "direct")))
7249 (set_attr "amdfam10_decode" "direct")
7250 (set_attr "bdver1_decode" "direct")
7251 (set_attr "mode" "QI")])
7253 ;; Multiply with jump on overflow.
7254 (define_expand "mulv<mode>4"
7255 [(parallel [(set (reg:CCO FLAGS_REG)
7258 (match_operand:SWI248 1 "register_operand"))
7261 (mult:SWI248 (match_dup 1)
7262 (match_operand:SWI248 2
7263 "<general_operand>")))))
7264 (set (match_operand:SWI248 0 "register_operand")
7265 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7266 (set (pc) (if_then_else
7267 (eq (reg:CCO FLAGS_REG) (const_int 0))
7268 (label_ref (match_operand 3))
7272 if (CONST_INT_P (operands[2]))
7273 operands[4] = operands[2];
7275 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7278 (define_insn "*mulv<mode>4"
7279 [(set (reg:CCO FLAGS_REG)
7282 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7284 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7286 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7287 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7288 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7289 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7291 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7292 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7293 [(set_attr "type" "imul")
7294 (set_attr "prefix_0f" "0,1")
7295 (set (attr "athlon_decode")
7296 (cond [(eq_attr "cpu" "athlon")
7297 (const_string "vector")
7298 (eq_attr "alternative" "0")
7299 (const_string "vector")
7300 (and (eq_attr "alternative" "1")
7301 (match_operand 1 "memory_operand"))
7302 (const_string "vector")]
7303 (const_string "direct")))
7304 (set (attr "amdfam10_decode")
7305 (cond [(and (eq_attr "alternative" "1")
7306 (match_operand 1 "memory_operand"))
7307 (const_string "vector")]
7308 (const_string "direct")))
7309 (set_attr "bdver1_decode" "direct")
7310 (set_attr "mode" "<MODE>")])
7312 (define_insn "*mulvhi4"
7313 [(set (reg:CCO FLAGS_REG)
7316 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7318 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7320 (mult:HI (match_dup 1) (match_dup 2)))))
7321 (set (match_operand:HI 0 "register_operand" "=r")
7322 (mult:HI (match_dup 1) (match_dup 2)))]
7323 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7324 "imul{w}\t{%2, %0|%0, %2}"
7325 [(set_attr "type" "imul")
7326 (set_attr "prefix_0f" "1")
7327 (set_attr "athlon_decode" "vector")
7328 (set_attr "amdfam10_decode" "direct")
7329 (set_attr "bdver1_decode" "double")
7330 (set_attr "mode" "HI")])
7332 (define_insn "*mulv<mode>4_1"
7333 [(set (reg:CCO FLAGS_REG)
7336 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7337 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7339 (mult:SWI248 (match_dup 1)
7340 (match_operand:SWI248 2
7341 "<immediate_operand>" "K,<i>")))))
7342 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7343 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7344 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7345 && CONST_INT_P (operands[2])
7346 && INTVAL (operands[2]) == INTVAL (operands[3])"
7347 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7348 [(set_attr "type" "imul")
7349 (set (attr "prefix_0f")
7351 (match_test "<MODE>mode == HImode")
7353 (const_string "*")))
7354 (set (attr "athlon_decode")
7355 (cond [(eq_attr "cpu" "athlon")
7356 (const_string "vector")
7357 (eq_attr "alternative" "1")
7358 (const_string "vector")]
7359 (const_string "direct")))
7360 (set (attr "amdfam10_decode")
7361 (cond [(ior (match_test "<MODE>mode == HImode")
7362 (match_operand 1 "memory_operand"))
7363 (const_string "vector")]
7364 (const_string "direct")))
7365 (set (attr "bdver1_decode")
7367 (match_test "<MODE>mode == HImode")
7368 (const_string "double")
7369 (const_string "direct")))
7370 (set_attr "mode" "<MODE>")
7371 (set (attr "length_immediate")
7372 (cond [(eq_attr "alternative" "0")
7374 (match_test "<MODE_SIZE> == 8")
7376 (const_string "<MODE_SIZE>")))])
7378 (define_expand "umulv<mode>4"
7379 [(parallel [(set (reg:CCO FLAGS_REG)
7382 (match_operand:SWI248 1
7383 "nonimmediate_operand"))
7385 (match_operand:SWI248 2
7386 "nonimmediate_operand")))
7388 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7389 (set (match_operand:SWI248 0 "register_operand")
7390 (mult:SWI248 (match_dup 1) (match_dup 2)))
7391 (clobber (match_scratch:SWI248 4))])
7392 (set (pc) (if_then_else
7393 (eq (reg:CCO FLAGS_REG) (const_int 0))
7394 (label_ref (match_operand 3))
7398 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7399 operands[1] = force_reg (<MODE>mode, operands[1]);
7402 (define_insn "*umulv<mode>4"
7403 [(set (reg:CCO FLAGS_REG)
7406 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7408 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7410 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7411 (set (match_operand:SWI248 0 "register_operand" "=a")
7412 (mult:SWI248 (match_dup 1) (match_dup 2)))
7413 (clobber (match_scratch:SWI248 3 "=d"))]
7414 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7415 "mul{<imodesuffix>}\t%2"
7416 [(set_attr "type" "imul")
7417 (set_attr "length_immediate" "0")
7418 (set (attr "athlon_decode")
7419 (if_then_else (eq_attr "cpu" "athlon")
7420 (const_string "vector")
7421 (const_string "double")))
7422 (set_attr "amdfam10_decode" "double")
7423 (set_attr "bdver1_decode" "direct")
7424 (set_attr "mode" "<MODE>")])
7426 (define_expand "<u>mulvqi4"
7427 [(parallel [(set (reg:CCO FLAGS_REG)
7430 (match_operand:QI 1 "nonimmediate_operand"))
7432 (match_operand:QI 2 "nonimmediate_operand")))
7434 (mult:QI (match_dup 1) (match_dup 2)))))
7435 (set (match_operand:QI 0 "register_operand")
7436 (mult:QI (match_dup 1) (match_dup 2)))])
7437 (set (pc) (if_then_else
7438 (eq (reg:CCO FLAGS_REG) (const_int 0))
7439 (label_ref (match_operand 3))
7441 "TARGET_QIMODE_MATH"
7443 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7444 operands[1] = force_reg (QImode, operands[1]);
7447 (define_insn "*<u>mulvqi4"
7448 [(set (reg:CCO FLAGS_REG)
7451 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7453 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455 (mult:QI (match_dup 1) (match_dup 2)))))
7456 (set (match_operand:QI 0 "register_operand" "=a")
7457 (mult:QI (match_dup 1) (match_dup 2)))]
7459 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7460 "<sgnprefix>mul{b}\t%2"
7461 [(set_attr "type" "imul")
7462 (set_attr "length_immediate" "0")
7463 (set (attr "athlon_decode")
7464 (if_then_else (eq_attr "cpu" "athlon")
7465 (const_string "vector")
7466 (const_string "direct")))
7467 (set_attr "amdfam10_decode" "direct")
7468 (set_attr "bdver1_decode" "direct")
7469 (set_attr "mode" "QI")])
7471 (define_expand "<u>mul<mode><dwi>3"
7472 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7475 (match_operand:DWIH 1 "nonimmediate_operand"))
7477 (match_operand:DWIH 2 "register_operand"))))
7478 (clobber (reg:CC FLAGS_REG))])])
7480 (define_expand "<u>mulqihi3"
7481 [(parallel [(set (match_operand:HI 0 "register_operand")
7484 (match_operand:QI 1 "nonimmediate_operand"))
7486 (match_operand:QI 2 "register_operand"))))
7487 (clobber (reg:CC FLAGS_REG))])]
7488 "TARGET_QIMODE_MATH")
7490 (define_insn "*bmi2_umul<mode><dwi>3_1"
7491 [(set (match_operand:DWIH 0 "register_operand" "=r")
7493 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7494 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7495 (set (match_operand:DWIH 1 "register_operand" "=r")
7498 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7499 (zero_extend:<DWI> (match_dup 3)))
7500 (match_operand:QI 4 "const_int_operand" "n"))))]
7501 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7503 "mulx\t{%3, %0, %1|%1, %0, %3}"
7504 [(set_attr "type" "imulx")
7505 (set_attr "prefix" "vex")
7506 (set_attr "mode" "<MODE>")])
7508 (define_insn "*umul<mode><dwi>3_1"
7509 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7512 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7514 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7519 mul{<imodesuffix>}\t%2"
7520 [(set_attr "isa" "bmi2,*")
7521 (set_attr "type" "imulx,imul")
7522 (set_attr "length_immediate" "*,0")
7523 (set (attr "athlon_decode")
7524 (cond [(eq_attr "alternative" "1")
7525 (if_then_else (eq_attr "cpu" "athlon")
7526 (const_string "vector")
7527 (const_string "double"))]
7528 (const_string "*")))
7529 (set_attr "amdfam10_decode" "*,double")
7530 (set_attr "bdver1_decode" "*,direct")
7531 (set_attr "prefix" "vex,orig")
7532 (set_attr "mode" "<MODE>")])
7534 ;; Convert mul to the mulx pattern to avoid flags dependency.
7536 [(set (match_operand:<DWI> 0 "register_operand")
7539 (match_operand:DWIH 1 "register_operand"))
7541 (match_operand:DWIH 2 "nonimmediate_operand"))))
7542 (clobber (reg:CC FLAGS_REG))]
7543 "TARGET_BMI2 && reload_completed
7544 && REGNO (operands[1]) == DX_REG"
7545 [(parallel [(set (match_dup 3)
7546 (mult:DWIH (match_dup 1) (match_dup 2)))
7550 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7551 (zero_extend:<DWI> (match_dup 2)))
7554 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7556 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7559 (define_insn "*mul<mode><dwi>3_1"
7560 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7563 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7565 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7568 "imul{<imodesuffix>}\t%2"
7569 [(set_attr "type" "imul")
7570 (set_attr "length_immediate" "0")
7571 (set (attr "athlon_decode")
7572 (if_then_else (eq_attr "cpu" "athlon")
7573 (const_string "vector")
7574 (const_string "double")))
7575 (set_attr "amdfam10_decode" "double")
7576 (set_attr "bdver1_decode" "direct")
7577 (set_attr "mode" "<MODE>")])
7579 (define_insn "*<u>mulqihi3_1"
7580 [(set (match_operand:HI 0 "register_operand" "=a")
7583 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7585 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7586 (clobber (reg:CC FLAGS_REG))]
7588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7589 "<sgnprefix>mul{b}\t%2"
7590 [(set_attr "type" "imul")
7591 (set_attr "length_immediate" "0")
7592 (set (attr "athlon_decode")
7593 (if_then_else (eq_attr "cpu" "athlon")
7594 (const_string "vector")
7595 (const_string "direct")))
7596 (set_attr "amdfam10_decode" "direct")
7597 (set_attr "bdver1_decode" "direct")
7598 (set_attr "mode" "QI")])
7600 (define_expand "<s>mul<mode>3_highpart"
7601 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7606 (match_operand:DWIH 1 "nonimmediate_operand"))
7608 (match_operand:DWIH 2 "register_operand")))
7610 (clobber (match_scratch:DWIH 4))
7611 (clobber (reg:CC FLAGS_REG))])]
7613 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7615 (define_insn "*<s>muldi3_highpart_1"
7616 [(set (match_operand:DI 0 "register_operand" "=d")
7621 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7623 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7625 (clobber (match_scratch:DI 3 "=1"))
7626 (clobber (reg:CC FLAGS_REG))]
7628 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7629 "<sgnprefix>mul{q}\t%2"
7630 [(set_attr "type" "imul")
7631 (set_attr "length_immediate" "0")
7632 (set (attr "athlon_decode")
7633 (if_then_else (eq_attr "cpu" "athlon")
7634 (const_string "vector")
7635 (const_string "double")))
7636 (set_attr "amdfam10_decode" "double")
7637 (set_attr "bdver1_decode" "direct")
7638 (set_attr "mode" "DI")])
7640 (define_insn "*<s>mulsi3_highpart_zext"
7641 [(set (match_operand:DI 0 "register_operand" "=d")
7642 (zero_extend:DI (truncate:SI
7644 (mult:DI (any_extend:DI
7645 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7647 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7649 (clobber (match_scratch:SI 3 "=1"))
7650 (clobber (reg:CC FLAGS_REG))]
7652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7653 "<sgnprefix>mul{l}\t%2"
7654 [(set_attr "type" "imul")
7655 (set_attr "length_immediate" "0")
7656 (set (attr "athlon_decode")
7657 (if_then_else (eq_attr "cpu" "athlon")
7658 (const_string "vector")
7659 (const_string "double")))
7660 (set_attr "amdfam10_decode" "double")
7661 (set_attr "bdver1_decode" "direct")
7662 (set_attr "mode" "SI")])
7664 (define_insn "*<s>mulsi3_highpart_1"
7665 [(set (match_operand:SI 0 "register_operand" "=d")
7670 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7672 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7674 (clobber (match_scratch:SI 3 "=1"))
7675 (clobber (reg:CC FLAGS_REG))]
7676 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677 "<sgnprefix>mul{l}\t%2"
7678 [(set_attr "type" "imul")
7679 (set_attr "length_immediate" "0")
7680 (set (attr "athlon_decode")
7681 (if_then_else (eq_attr "cpu" "athlon")
7682 (const_string "vector")
7683 (const_string "double")))
7684 (set_attr "amdfam10_decode" "double")
7685 (set_attr "bdver1_decode" "direct")
7686 (set_attr "mode" "SI")])
7688 ;; The patterns that match these are at the end of this file.
7690 (define_expand "mulxf3"
7691 [(set (match_operand:XF 0 "register_operand")
7692 (mult:XF (match_operand:XF 1 "register_operand")
7693 (match_operand:XF 2 "register_operand")))]
7696 (define_expand "mul<mode>3"
7697 [(set (match_operand:MODEF 0 "register_operand")
7698 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7699 (match_operand:MODEF 2 "nonimmediate_operand")))]
7700 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7703 ;; Divide instructions
7705 ;; The patterns that match these are at the end of this file.
7707 (define_expand "divxf3"
7708 [(set (match_operand:XF 0 "register_operand")
7709 (div:XF (match_operand:XF 1 "register_operand")
7710 (match_operand:XF 2 "register_operand")))]
7713 (define_expand "div<mode>3"
7714 [(set (match_operand:MODEF 0 "register_operand")
7715 (div:MODEF (match_operand:MODEF 1 "register_operand")
7716 (match_operand:MODEF 2 "nonimmediate_operand")))]
7717 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7718 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7720 if (<MODE>mode == SFmode
7721 && TARGET_SSE && TARGET_SSE_MATH
7723 && optimize_insn_for_speed_p ()
7724 && flag_finite_math_only && !flag_trapping_math
7725 && flag_unsafe_math_optimizations)
7727 ix86_emit_swdivsf (operands[0], operands[1],
7728 operands[2], SFmode);
7733 ;; Divmod instructions.
7735 (define_code_iterator any_div [div udiv])
7736 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7738 (define_expand "<u>divmod<mode>4"
7739 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7741 (match_operand:SWIM248 1 "register_operand")
7742 (match_operand:SWIM248 2 "nonimmediate_operand")))
7743 (set (match_operand:SWIM248 3 "register_operand")
7744 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7745 (clobber (reg:CC FLAGS_REG))])])
7747 ;; Split with 8bit unsigned divide:
7748 ;; if (dividend an divisor are in [0-255])
7749 ;; use 8bit unsigned integer divide
7751 ;; use original integer divide
7753 [(set (match_operand:SWI48 0 "register_operand")
7754 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7755 (match_operand:SWI48 3 "nonimmediate_operand")))
7756 (set (match_operand:SWI48 1 "register_operand")
7757 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_USE_8BIT_IDIV
7760 && TARGET_QIMODE_MATH
7761 && can_create_pseudo_p ()
7762 && !optimize_insn_for_size_p ()"
7764 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7767 [(set (match_operand:DI 0 "register_operand")
7769 (any_div:SI (match_operand:SI 2 "register_operand")
7770 (match_operand:SI 3 "nonimmediate_operand"))))
7771 (set (match_operand:SI 1 "register_operand")
7772 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7773 (clobber (reg:CC FLAGS_REG))]
7775 && TARGET_USE_8BIT_IDIV
7776 && TARGET_QIMODE_MATH
7777 && can_create_pseudo_p ()
7778 && !optimize_insn_for_size_p ()"
7780 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7783 [(set (match_operand:DI 1 "register_operand")
7785 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7786 (match_operand:SI 3 "nonimmediate_operand"))))
7787 (set (match_operand:SI 0 "register_operand")
7788 (any_div:SI (match_dup 2) (match_dup 3)))
7789 (clobber (reg:CC FLAGS_REG))]
7791 && TARGET_USE_8BIT_IDIV
7792 && TARGET_QIMODE_MATH
7793 && can_create_pseudo_p ()
7794 && !optimize_insn_for_size_p ()"
7796 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7798 (define_insn_and_split "divmod<mode>4_1"
7799 [(set (match_operand:SWI48 0 "register_operand" "=a")
7800 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7801 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7802 (set (match_operand:SWI48 1 "register_operand" "=&d")
7803 (mod:SWI48 (match_dup 2) (match_dup 3)))
7804 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7805 (clobber (reg:CC FLAGS_REG))]
7809 [(parallel [(set (match_dup 1)
7810 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7811 (clobber (reg:CC FLAGS_REG))])
7812 (parallel [(set (match_dup 0)
7813 (div:SWI48 (match_dup 2) (match_dup 3)))
7815 (mod:SWI48 (match_dup 2) (match_dup 3)))
7817 (clobber (reg:CC FLAGS_REG))])]
7819 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7821 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7822 operands[4] = operands[2];
7825 /* Avoid use of cltd in favor of a mov+shift. */
7826 emit_move_insn (operands[1], operands[2]);
7827 operands[4] = operands[1];
7830 [(set_attr "type" "multi")
7831 (set_attr "mode" "<MODE>")])
7833 (define_insn_and_split "udivmod<mode>4_1"
7834 [(set (match_operand:SWI48 0 "register_operand" "=a")
7835 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7836 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7837 (set (match_operand:SWI48 1 "register_operand" "=&d")
7838 (umod:SWI48 (match_dup 2) (match_dup 3)))
7839 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7840 (clobber (reg:CC FLAGS_REG))]
7844 [(set (match_dup 1) (const_int 0))
7845 (parallel [(set (match_dup 0)
7846 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7848 (umod:SWI48 (match_dup 2) (match_dup 3)))
7850 (clobber (reg:CC FLAGS_REG))])]
7852 [(set_attr "type" "multi")
7853 (set_attr "mode" "<MODE>")])
7855 (define_insn_and_split "divmodsi4_zext_1"
7856 [(set (match_operand:DI 0 "register_operand" "=a")
7858 (div:SI (match_operand:SI 2 "register_operand" "0")
7859 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7860 (set (match_operand:SI 1 "register_operand" "=&d")
7861 (mod:SI (match_dup 2) (match_dup 3)))
7862 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7863 (clobber (reg:CC FLAGS_REG))]
7866 "&& reload_completed"
7867 [(parallel [(set (match_dup 1)
7868 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7869 (clobber (reg:CC FLAGS_REG))])
7870 (parallel [(set (match_dup 0)
7871 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7873 (mod:SI (match_dup 2) (match_dup 3)))
7875 (clobber (reg:CC FLAGS_REG))])]
7877 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7879 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7880 operands[4] = operands[2];
7883 /* Avoid use of cltd in favor of a mov+shift. */
7884 emit_move_insn (operands[1], operands[2]);
7885 operands[4] = operands[1];
7888 [(set_attr "type" "multi")
7889 (set_attr "mode" "SI")])
7891 (define_insn_and_split "udivmodsi4_zext_1"
7892 [(set (match_operand:DI 0 "register_operand" "=a")
7894 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7895 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7896 (set (match_operand:SI 1 "register_operand" "=&d")
7897 (umod:SI (match_dup 2) (match_dup 3)))
7898 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7899 (clobber (reg:CC FLAGS_REG))]
7902 "&& reload_completed"
7903 [(set (match_dup 1) (const_int 0))
7904 (parallel [(set (match_dup 0)
7905 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7907 (umod:SI (match_dup 2) (match_dup 3)))
7909 (clobber (reg:CC FLAGS_REG))])]
7911 [(set_attr "type" "multi")
7912 (set_attr "mode" "SI")])
7914 (define_insn_and_split "divmodsi4_zext_2"
7915 [(set (match_operand:DI 1 "register_operand" "=&d")
7917 (mod:SI (match_operand:SI 2 "register_operand" "0")
7918 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7919 (set (match_operand:SI 0 "register_operand" "=a")
7920 (div:SI (match_dup 2) (match_dup 3)))
7921 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7922 (clobber (reg:CC FLAGS_REG))]
7925 "&& reload_completed"
7926 [(parallel [(set (match_dup 6)
7927 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7928 (clobber (reg:CC FLAGS_REG))])
7929 (parallel [(set (match_dup 1)
7930 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7932 (div:SI (match_dup 2) (match_dup 3)))
7934 (clobber (reg:CC FLAGS_REG))])]
7936 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7937 operands[6] = gen_lowpart (SImode, operands[1]);
7939 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7940 operands[4] = operands[2];
7943 /* Avoid use of cltd in favor of a mov+shift. */
7944 emit_move_insn (operands[6], operands[2]);
7945 operands[4] = operands[6];
7948 [(set_attr "type" "multi")
7949 (set_attr "mode" "SI")])
7951 (define_insn_and_split "udivmodsi4_zext_2"
7952 [(set (match_operand:DI 1 "register_operand" "=&d")
7954 (umod:SI (match_operand:SI 2 "register_operand" "0")
7955 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7956 (set (match_operand:SI 0 "register_operand" "=a")
7957 (udiv:SI (match_dup 2) (match_dup 3)))
7958 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7959 (clobber (reg:CC FLAGS_REG))]
7962 "&& reload_completed"
7963 [(set (match_dup 4) (const_int 0))
7964 (parallel [(set (match_dup 1)
7965 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7967 (udiv:SI (match_dup 2) (match_dup 3)))
7969 (clobber (reg:CC FLAGS_REG))])]
7970 "operands[4] = gen_lowpart (SImode, operands[1]);"
7971 [(set_attr "type" "multi")
7972 (set_attr "mode" "SI")])
7974 (define_insn_and_split "*divmod<mode>4"
7975 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7976 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7977 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7978 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7979 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7980 (clobber (reg:CC FLAGS_REG))]
7984 [(parallel [(set (match_dup 1)
7985 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7986 (clobber (reg:CC FLAGS_REG))])
7987 (parallel [(set (match_dup 0)
7988 (div:SWIM248 (match_dup 2) (match_dup 3)))
7990 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7992 (clobber (reg:CC FLAGS_REG))])]
7994 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7996 if (<MODE>mode != HImode
7997 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7998 operands[4] = operands[2];
8001 /* Avoid use of cltd in favor of a mov+shift. */
8002 emit_move_insn (operands[1], operands[2]);
8003 operands[4] = operands[1];
8006 [(set_attr "type" "multi")
8007 (set_attr "mode" "<MODE>")])
8009 (define_insn_and_split "*udivmod<mode>4"
8010 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8011 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8012 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8013 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8014 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8015 (clobber (reg:CC FLAGS_REG))]
8019 [(set (match_dup 1) (const_int 0))
8020 (parallel [(set (match_dup 0)
8021 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8023 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8025 (clobber (reg:CC FLAGS_REG))])]
8027 [(set_attr "type" "multi")
8028 (set_attr "mode" "<MODE>")])
8030 ;; Optimize division or modulo by constant power of 2, if the constant
8031 ;; materializes only after expansion.
8032 (define_insn_and_split "*udivmod<mode>4_pow2"
8033 [(set (match_operand:SWI48 0 "register_operand" "=r")
8034 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8035 (match_operand:SWI48 3 "const_int_operand" "n")))
8036 (set (match_operand:SWI48 1 "register_operand" "=r")
8037 (umod:SWI48 (match_dup 2) (match_dup 3)))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8041 "&& reload_completed"
8042 [(set (match_dup 1) (match_dup 2))
8043 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8044 (clobber (reg:CC FLAGS_REG))])
8045 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8046 (clobber (reg:CC FLAGS_REG))])]
8048 int v = exact_log2 (UINTVAL (operands[3]));
8049 operands[4] = GEN_INT (v);
8050 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8052 [(set_attr "type" "multi")
8053 (set_attr "mode" "<MODE>")])
8055 (define_insn_and_split "*divmodsi4_zext_1"
8056 [(set (match_operand:DI 0 "register_operand" "=a")
8058 (div:SI (match_operand:SI 2 "register_operand" "0")
8059 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8060 (set (match_operand:SI 1 "register_operand" "=&d")
8061 (mod:SI (match_dup 2) (match_dup 3)))
8062 (clobber (reg:CC FLAGS_REG))]
8065 "&& reload_completed"
8066 [(parallel [(set (match_dup 1)
8067 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8068 (clobber (reg:CC FLAGS_REG))])
8069 (parallel [(set (match_dup 0)
8070 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8072 (mod:SI (match_dup 2) (match_dup 3)))
8074 (clobber (reg:CC FLAGS_REG))])]
8076 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8078 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8079 operands[4] = operands[2];
8082 /* Avoid use of cltd in favor of a mov+shift. */
8083 emit_move_insn (operands[1], operands[2]);
8084 operands[4] = operands[1];
8087 [(set_attr "type" "multi")
8088 (set_attr "mode" "SI")])
8090 (define_insn_and_split "*udivmodsi4_zext_1"
8091 [(set (match_operand:DI 0 "register_operand" "=a")
8093 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8094 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8095 (set (match_operand:SI 1 "register_operand" "=&d")
8096 (umod:SI (match_dup 2) (match_dup 3)))
8097 (clobber (reg:CC FLAGS_REG))]
8100 "&& reload_completed"
8101 [(set (match_dup 1) (const_int 0))
8102 (parallel [(set (match_dup 0)
8103 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8105 (umod:SI (match_dup 2) (match_dup 3)))
8107 (clobber (reg:CC FLAGS_REG))])]
8109 [(set_attr "type" "multi")
8110 (set_attr "mode" "SI")])
8112 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8113 [(set (match_operand:DI 0 "register_operand" "=r")
8115 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8116 (match_operand:SI 3 "const_int_operand" "n"))))
8117 (set (match_operand:SI 1 "register_operand" "=r")
8118 (umod:SI (match_dup 2) (match_dup 3)))
8119 (clobber (reg:CC FLAGS_REG))]
8121 && exact_log2 (UINTVAL (operands[3])) > 0"
8123 "&& reload_completed"
8124 [(set (match_dup 1) (match_dup 2))
8125 (parallel [(set (match_dup 0)
8126 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8127 (clobber (reg:CC FLAGS_REG))])
8128 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8129 (clobber (reg:CC FLAGS_REG))])]
8131 int v = exact_log2 (UINTVAL (operands[3]));
8132 operands[4] = GEN_INT (v);
8133 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8135 [(set_attr "type" "multi")
8136 (set_attr "mode" "SI")])
8138 (define_insn_and_split "*divmodsi4_zext_2"
8139 [(set (match_operand:DI 1 "register_operand" "=&d")
8141 (mod:SI (match_operand:SI 2 "register_operand" "0")
8142 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8143 (set (match_operand:SI 0 "register_operand" "=a")
8144 (div:SI (match_dup 2) (match_dup 3)))
8145 (clobber (reg:CC FLAGS_REG))]
8148 "&& reload_completed"
8149 [(parallel [(set (match_dup 6)
8150 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8151 (clobber (reg:CC FLAGS_REG))])
8152 (parallel [(set (match_dup 1)
8153 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8155 (div:SI (match_dup 2) (match_dup 3)))
8157 (clobber (reg:CC FLAGS_REG))])]
8159 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8160 operands[6] = gen_lowpart (SImode, operands[1]);
8162 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8163 operands[4] = operands[2];
8166 /* Avoid use of cltd in favor of a mov+shift. */
8167 emit_move_insn (operands[6], operands[2]);
8168 operands[4] = operands[6];
8171 [(set_attr "type" "multi")
8172 (set_attr "mode" "SI")])
8174 (define_insn_and_split "*udivmodsi4_zext_2"
8175 [(set (match_operand:DI 1 "register_operand" "=&d")
8177 (umod:SI (match_operand:SI 2 "register_operand" "0")
8178 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8179 (set (match_operand:SI 0 "register_operand" "=a")
8180 (udiv:SI (match_dup 2) (match_dup 3)))
8181 (clobber (reg:CC FLAGS_REG))]
8184 "&& reload_completed"
8185 [(set (match_dup 4) (const_int 0))
8186 (parallel [(set (match_dup 1)
8187 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8189 (udiv:SI (match_dup 2) (match_dup 3)))
8191 (clobber (reg:CC FLAGS_REG))])]
8192 "operands[4] = gen_lowpart (SImode, operands[1]);"
8193 [(set_attr "type" "multi")
8194 (set_attr "mode" "SI")])
8196 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8197 [(set (match_operand:DI 1 "register_operand" "=r")
8199 (umod:SI (match_operand:SI 2 "register_operand" "0")
8200 (match_operand:SI 3 "const_int_operand" "n"))))
8201 (set (match_operand:SI 0 "register_operand" "=r")
8202 (umod:SI (match_dup 2) (match_dup 3)))
8203 (clobber (reg:CC FLAGS_REG))]
8205 && exact_log2 (UINTVAL (operands[3])) > 0"
8207 "&& reload_completed"
8208 [(set (match_dup 1) (match_dup 2))
8209 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8210 (clobber (reg:CC FLAGS_REG))])
8211 (parallel [(set (match_dup 1)
8212 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8213 (clobber (reg:CC FLAGS_REG))])]
8215 int v = exact_log2 (UINTVAL (operands[3]));
8216 operands[4] = GEN_INT (v);
8217 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8219 [(set_attr "type" "multi")
8220 (set_attr "mode" "SI")])
8222 (define_insn "*<u>divmod<mode>4_noext"
8223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8225 (match_operand:SWIM248 2 "register_operand" "0")
8226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8227 (set (match_operand:SWIM248 1 "register_operand" "=d")
8228 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8229 (use (match_operand:SWIM248 4 "register_operand" "1"))
8230 (clobber (reg:CC FLAGS_REG))]
8232 "<sgnprefix>div{<imodesuffix>}\t%3"
8233 [(set_attr "type" "idiv")
8234 (set_attr "mode" "<MODE>")])
8236 (define_insn "*<u>divmodsi4_noext_zext_1"
8237 [(set (match_operand:DI 0 "register_operand" "=a")
8239 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8240 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8241 (set (match_operand:SI 1 "register_operand" "=d")
8242 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8243 (use (match_operand:SI 4 "register_operand" "1"))
8244 (clobber (reg:CC FLAGS_REG))]
8246 "<sgnprefix>div{l}\t%3"
8247 [(set_attr "type" "idiv")
8248 (set_attr "mode" "SI")])
8250 (define_insn "*<u>divmodsi4_noext_zext_2"
8251 [(set (match_operand:DI 1 "register_operand" "=d")
8253 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8254 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8255 (set (match_operand:SI 0 "register_operand" "=a")
8256 (any_div:SI (match_dup 2) (match_dup 3)))
8257 (use (match_operand:SI 4 "register_operand" "1"))
8258 (clobber (reg:CC FLAGS_REG))]
8260 "<sgnprefix>div{l}\t%3"
8261 [(set_attr "type" "idiv")
8262 (set_attr "mode" "SI")])
8264 (define_expand "divmodqi4"
8265 [(parallel [(set (match_operand:QI 0 "register_operand")
8267 (match_operand:QI 1 "register_operand")
8268 (match_operand:QI 2 "nonimmediate_operand")))
8269 (set (match_operand:QI 3 "register_operand")
8270 (mod:QI (match_dup 1) (match_dup 2)))
8271 (clobber (reg:CC FLAGS_REG))])]
8272 "TARGET_QIMODE_MATH"
8277 tmp0 = gen_reg_rtx (HImode);
8278 tmp1 = gen_reg_rtx (HImode);
8280 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8281 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8282 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8284 /* Extract remainder from AH. */
8285 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8286 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8287 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8289 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8290 set_unique_reg_note (insn, REG_EQUAL, mod);
8292 /* Extract quotient from AL. */
8293 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8295 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8296 set_unique_reg_note (insn, REG_EQUAL, div);
8301 (define_expand "udivmodqi4"
8302 [(parallel [(set (match_operand:QI 0 "register_operand")
8304 (match_operand:QI 1 "register_operand")
8305 (match_operand:QI 2 "nonimmediate_operand")))
8306 (set (match_operand:QI 3 "register_operand")
8307 (umod:QI (match_dup 1) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))])]
8309 "TARGET_QIMODE_MATH"
8314 tmp0 = gen_reg_rtx (HImode);
8315 tmp1 = gen_reg_rtx (HImode);
8317 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8318 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8319 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8321 /* Extract remainder from AH. */
8322 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8323 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8324 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8326 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8327 set_unique_reg_note (insn, REG_EQUAL, mod);
8329 /* Extract quotient from AL. */
8330 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8332 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8333 set_unique_reg_note (insn, REG_EQUAL, div);
8338 ;; Divide AX by r/m8, with result stored in
8341 ;; Change div/mod to HImode and extend the second argument to HImode
8342 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8343 ;; combine may fail.
8344 (define_insn "<u>divmodhiqi3"
8345 [(set (match_operand:HI 0 "register_operand" "=a")
8350 (mod:HI (match_operand:HI 1 "register_operand" "0")
8352 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8356 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8357 (clobber (reg:CC FLAGS_REG))]
8358 "TARGET_QIMODE_MATH"
8359 "<sgnprefix>div{b}\t%2"
8360 [(set_attr "type" "idiv")
8361 (set_attr "mode" "QI")])
8363 ;; We cannot use div/idiv for double division, because it causes
8364 ;; "division by zero" on the overflow and that's not what we expect
8365 ;; from truncate. Because true (non truncating) double division is
8366 ;; never generated, we can't create this insn anyway.
8369 ; [(set (match_operand:SI 0 "register_operand" "=a")
8371 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8373 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8374 ; (set (match_operand:SI 3 "register_operand" "=d")
8376 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8377 ; (clobber (reg:CC FLAGS_REG))]
8379 ; "div{l}\t{%2, %0|%0, %2}"
8380 ; [(set_attr "type" "idiv")])
8382 ;;- Logical AND instructions
8384 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8385 ;; Note that this excludes ah.
8387 (define_expand "@test<mode>_ccno_1"
8388 [(set (reg:CCNO FLAGS_REG)
8391 (match_operand:SWI48 0 "nonimmediate_operand")
8392 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8395 (define_expand "testqi_ccz_1"
8396 [(set (reg:CCZ FLAGS_REG)
8399 (match_operand:QI 0 "nonimmediate_operand")
8400 (match_operand:QI 1 "nonmemory_operand"))
8403 (define_insn "*testdi_1"
8404 [(set (reg FLAGS_REG)
8407 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8408 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8411 && ix86_match_ccmode
8413 /* If we are going to emit testl instead of testq, and the operands[1]
8414 constant might have the SImode sign bit set, make sure the sign
8415 flag isn't tested, because the instruction will set the sign flag
8416 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8417 conservatively assume it might have bit 31 set. */
8418 (satisfies_constraint_Z (operands[1])
8419 && (!CONST_INT_P (operands[1])
8420 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8421 ? CCZmode : CCNOmode)"
8423 test{l}\t{%k1, %k0|%k0, %k1}
8424 test{q}\t{%1, %0|%0, %1}"
8425 [(set_attr "type" "test")
8426 (set_attr "mode" "SI,DI")])
8428 (define_insn "*testqi_1_maybe_si"
8429 [(set (reg FLAGS_REG)
8432 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8433 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8435 "ix86_match_ccmode (insn,
8436 CONST_INT_P (operands[1])
8437 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8439 if (which_alternative == 3)
8441 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8442 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8443 return "test{l}\t{%1, %k0|%k0, %1}";
8445 return "test{b}\t{%1, %0|%0, %1}";
8447 [(set_attr "type" "test")
8448 (set_attr "mode" "QI,QI,QI,SI")
8449 (set_attr "pent_pair" "uv,uv,np,np")])
8451 (define_insn "*test<mode>_1"
8452 [(set (reg FLAGS_REG)
8455 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8456 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8458 "ix86_match_ccmode (insn, CCNOmode)"
8459 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8460 [(set_attr "type" "test")
8461 (set_attr "mode" "<MODE>")
8462 (set_attr "pent_pair" "uv,uv,np")])
8464 (define_expand "testqi_ext_1_ccno"
8465 [(set (reg:CCNO FLAGS_REG)
8469 (zero_extract:SI (match_operand 0 "ext_register_operand")
8472 (match_operand 1 "const_int_operand"))
8475 (define_insn "*testqi_ext_1"
8476 [(set (reg FLAGS_REG)
8480 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8483 (match_operand:QI 1 "general_operand" "QnBc,m"))
8485 "ix86_match_ccmode (insn, CCNOmode)"
8486 "test{b}\t{%1, %h0|%h0, %1}"
8487 [(set_attr "isa" "*,nox64")
8488 (set_attr "type" "test")
8489 (set_attr "mode" "QI")])
8491 (define_insn "*testqi_ext_2"
8492 [(set (reg FLAGS_REG)
8496 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8500 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8504 "ix86_match_ccmode (insn, CCNOmode)"
8505 "test{b}\t{%h1, %h0|%h0, %h1}"
8506 [(set_attr "type" "test")
8507 (set_attr "mode" "QI")])
8509 ;; Combine likes to form bit extractions for some tests. Humor it.
8510 (define_insn_and_split "*testqi_ext_3"
8511 [(set (match_operand 0 "flags_reg_operand")
8512 (match_operator 1 "compare_operator"
8513 [(zero_extract:SWI248
8514 (match_operand 2 "nonimmediate_operand" "rm")
8515 (match_operand 3 "const_int_operand" "n")
8516 (match_operand 4 "const_int_operand" "n"))
8518 "ix86_match_ccmode (insn, CCNOmode)
8519 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8520 || GET_MODE (operands[2]) == SImode
8521 || GET_MODE (operands[2]) == HImode
8522 || GET_MODE (operands[2]) == QImode)
8523 /* Ensure that resulting mask is zero or sign extended operand. */
8524 && INTVAL (operands[4]) >= 0
8525 && ((INTVAL (operands[3]) > 0
8526 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8527 || (<MODE>mode == DImode
8528 && INTVAL (operands[3]) > 32
8529 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8532 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8534 rtx val = operands[2];
8535 HOST_WIDE_INT len = INTVAL (operands[3]);
8536 HOST_WIDE_INT pos = INTVAL (operands[4]);
8537 machine_mode mode = GET_MODE (val);
8541 machine_mode submode = GET_MODE (SUBREG_REG (val));
8543 /* Narrow paradoxical subregs to prevent partial register stalls. */
8544 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8545 && GET_MODE_CLASS (submode) == MODE_INT)
8547 val = SUBREG_REG (val);
8552 /* Small HImode tests can be converted to QImode. */
8553 if (register_operand (val, HImode) && pos + len <= 8)
8555 val = gen_lowpart (QImode, val);
8559 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8562 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8564 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8567 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8568 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8569 ;; this is relatively important trick.
8570 ;; Do the conversion only post-reload to avoid limiting of the register class
8573 [(set (match_operand 0 "flags_reg_operand")
8574 (match_operator 1 "compare_operator"
8575 [(and (match_operand 2 "QIreg_operand")
8576 (match_operand 3 "const_int_operand"))
8579 && GET_MODE (operands[2]) != QImode
8580 && ((ix86_match_ccmode (insn, CCZmode)
8581 && !(INTVAL (operands[3]) & ~(255 << 8)))
8582 || (ix86_match_ccmode (insn, CCNOmode)
8583 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8588 (zero_extract:SI (match_dup 2)
8594 operands[2] = gen_lowpart (SImode, operands[2]);
8595 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8599 [(set (match_operand 0 "flags_reg_operand")
8600 (match_operator 1 "compare_operator"
8601 [(and (match_operand 2 "nonimmediate_operand")
8602 (match_operand 3 "const_int_operand"))
8605 && GET_MODE (operands[2]) != QImode
8606 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8607 && ((ix86_match_ccmode (insn, CCZmode)
8608 && !(INTVAL (operands[3]) & ~255))
8609 || (ix86_match_ccmode (insn, CCNOmode)
8610 && !(INTVAL (operands[3]) & ~127)))"
8612 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8615 operands[2] = gen_lowpart (QImode, operands[2]);
8616 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8619 ;; %%% This used to optimize known byte-wide and operations to memory,
8620 ;; and sometimes to QImode registers. If this is considered useful,
8621 ;; it should be done with splitters.
8623 (define_expand "and<mode>3"
8624 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8625 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8626 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
8629 machine_mode mode = <MODE>mode;
8631 if (<MODE>mode == DImode && !TARGET_64BIT)
8633 else if (const_int_operand (operands[2], <MODE>mode)
8634 && register_operand (operands[0], <MODE>mode)
8635 && !(TARGET_ZERO_EXTEND_WITH_AND
8636 && optimize_function_for_speed_p (cfun)))
8638 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8640 if (ival == GET_MODE_MASK (SImode))
8642 else if (ival == GET_MODE_MASK (HImode))
8644 else if (ival == GET_MODE_MASK (QImode))
8648 if (mode != <MODE>mode)
8649 emit_insn (gen_extend_insn
8650 (operands[0], gen_lowpart (mode, operands[1]),
8651 <MODE>mode, mode, 1));
8653 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8658 (define_insn_and_split "*anddi3_doubleword"
8659 [(set (match_operand:DI 0 "nonimmediate_operand")
8661 (match_operand:DI 1 "nonimmediate_operand")
8662 (match_operand:DI 2 "x86_64_szext_general_operand")))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8665 && ix86_binary_operator_ok (AND, DImode, operands)
8666 && ix86_pre_reload_split ()"
8671 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8673 if (operands[2] == const0_rtx)
8674 emit_move_insn (operands[0], const0_rtx);
8675 else if (operands[2] == constm1_rtx)
8676 emit_move_insn (operands[0], operands[1]);
8678 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
8680 if (operands[5] == const0_rtx)
8681 emit_move_insn (operands[3], const0_rtx);
8682 else if (operands[5] == constm1_rtx)
8683 emit_move_insn (operands[3], operands[4]);
8685 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
8690 (define_insn "*anddi_1"
8691 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8693 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8694 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L")))
8695 (clobber (reg:CC FLAGS_REG))]
8696 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8698 and{l}\t{%k2, %k0|%k0, %k2}
8699 and{q}\t{%2, %0|%0, %2}
8700 and{q}\t{%2, %0|%0, %2}
8702 [(set_attr "type" "alu,alu,alu,imovx")
8703 (set_attr "length_immediate" "*,*,*,0")
8704 (set (attr "prefix_rex")
8706 (and (eq_attr "type" "imovx")
8707 (and (match_test "INTVAL (operands[2]) == 0xff")
8708 (match_operand 1 "ext_QIreg_operand")))
8710 (const_string "*")))
8711 (set_attr "mode" "SI,DI,DI,SI")])
8713 (define_insn_and_split "*anddi_1_btr"
8714 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8716 (match_operand:DI 1 "nonimmediate_operand" "%0")
8717 (match_operand:DI 2 "const_int_operand" "n")))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "TARGET_64BIT && TARGET_USE_BT
8720 && ix86_binary_operator_ok (AND, DImode, operands)
8721 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8723 "&& reload_completed"
8724 [(parallel [(set (zero_extract:DI (match_dup 0)
8728 (clobber (reg:CC FLAGS_REG))])]
8729 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8730 [(set_attr "type" "alu1")
8731 (set_attr "prefix_0f" "1")
8732 (set_attr "znver1_decode" "double")
8733 (set_attr "mode" "DI")])
8735 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8737 [(set (match_operand:DI 0 "register_operand")
8738 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8739 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8740 (clobber (reg:CC FLAGS_REG))]
8742 [(parallel [(set (match_dup 0)
8743 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8744 (clobber (reg:CC FLAGS_REG))])]
8746 if (GET_CODE (operands[2]) == SYMBOL_REF
8747 || GET_CODE (operands[2]) == LABEL_REF)
8749 operands[2] = shallow_copy_rtx (operands[2]);
8750 PUT_MODE (operands[2], SImode);
8752 else if (GET_CODE (operands[2]) == CONST)
8754 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8755 operands[2] = copy_rtx (operands[2]);
8756 PUT_MODE (operands[2], SImode);
8757 PUT_MODE (XEXP (operands[2], 0), SImode);
8758 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8761 operands[2] = gen_lowpart (SImode, operands[2]);
8764 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8765 (define_insn "*andsi_1_zext"
8766 [(set (match_operand:DI 0 "register_operand" "=r")
8768 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8769 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8770 (clobber (reg:CC FLAGS_REG))]
8771 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8772 "and{l}\t{%2, %k0|%k0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "SI")])
8776 (define_insn "*and<mode>_1"
8777 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8778 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8779 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L")))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8783 and{<imodesuffix>}\t{%2, %0|%0, %2}
8784 and{<imodesuffix>}\t{%2, %0|%0, %2}
8786 [(set_attr "type" "alu,alu,imovx")
8787 (set_attr "length_immediate" "*,*,0")
8788 (set (attr "prefix_rex")
8790 (and (eq_attr "type" "imovx")
8791 (and (match_test "INTVAL (operands[2]) == 0xff")
8792 (match_operand 1 "ext_QIreg_operand")))
8794 (const_string "*")))
8795 (set_attr "mode" "<MODE>,<MODE>,SI")])
8797 (define_insn "*andqi_1"
8798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8799 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8800 (match_operand:QI 2 "general_operand" "qn,m,rn")))
8801 (clobber (reg:CC FLAGS_REG))]
8802 "ix86_binary_operator_ok (AND, QImode, operands)"
8804 and{b}\t{%2, %0|%0, %2}
8805 and{b}\t{%2, %0|%0, %2}
8806 and{l}\t{%k2, %k0|%k0, %k2}"
8807 [(set_attr "type" "alu")
8808 (set_attr "mode" "QI,QI,SI")
8809 ;; Potential partial reg stall on alternative 2.
8810 (set (attr "preferred_for_speed")
8811 (cond [(eq_attr "alternative" "2")
8812 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8813 (symbol_ref "true")))])
8815 (define_insn "*and<mode>_1_slp"
8816 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
8817 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
8818 (match_operand:SWI12 2 "general_operand" "<r>mn")))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8821 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8822 && (rtx_equal_p (operands[0], operands[1])
8823 || rtx_equal_p (operands[0], operands[2]))"
8824 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8825 [(set_attr "type" "alu")
8826 (set_attr "mode" "<MODE>")])
8829 [(set (match_operand:SWI248 0 "register_operand")
8830 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8831 (match_operand:SWI248 2 "const_int_operand")))
8832 (clobber (reg:CC FLAGS_REG))]
8834 && (!REG_P (operands[1])
8835 || REGNO (operands[0]) != REGNO (operands[1]))"
8838 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8841 if (ival == GET_MODE_MASK (SImode))
8843 else if (ival == GET_MODE_MASK (HImode))
8845 else if (ival == GET_MODE_MASK (QImode))
8850 /* Zero extend to SImode to avoid partial register stalls. */
8851 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
8852 operands[0] = gen_lowpart (SImode, operands[0]);
8854 emit_insn (gen_extend_insn
8855 (operands[0], gen_lowpart (mode, operands[1]),
8856 GET_MODE (operands[0]), mode, 1));
8861 [(set (match_operand:SWI48 0 "register_operand")
8862 (and:SWI48 (match_dup 0)
8863 (const_int -65536)))
8864 (clobber (reg:CC FLAGS_REG))]
8865 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8866 || optimize_function_for_size_p (cfun)"
8867 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8868 "operands[1] = gen_lowpart (HImode, operands[0]);")
8871 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8872 (and:SWI248 (match_dup 0)
8874 (clobber (reg:CC FLAGS_REG))]
8875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876 && reload_completed"
8877 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8878 "operands[1] = gen_lowpart (QImode, operands[0]);")
8881 [(set (match_operand:SWI248 0 "QIreg_operand")
8882 (and:SWI248 (match_dup 0)
8883 (const_int -65281)))
8884 (clobber (reg:CC FLAGS_REG))]
8885 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8886 && reload_completed"
8888 [(set (zero_extract:SI (match_dup 0)
8894 (zero_extract:SI (match_dup 0)
8898 (zero_extract:SI (match_dup 0)
8900 (const_int 8)) 0)) 0))
8901 (clobber (reg:CC FLAGS_REG))])]
8902 "operands[0] = gen_lowpart (SImode, operands[0]);")
8904 (define_insn "*anddi_2"
8905 [(set (reg FLAGS_REG)
8908 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8909 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
8911 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8912 (and:DI (match_dup 1) (match_dup 2)))]
8914 && ix86_match_ccmode
8916 /* If we are going to emit andl instead of andq, and the operands[2]
8917 constant might have the SImode sign bit set, make sure the sign
8918 flag isn't tested, because the instruction will set the sign flag
8919 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8920 conservatively assume it might have bit 31 set. */
8921 (satisfies_constraint_Z (operands[2])
8922 && (!CONST_INT_P (operands[2])
8923 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8924 ? CCZmode : CCNOmode)
8925 && ix86_binary_operator_ok (AND, DImode, operands)"
8927 and{l}\t{%k2, %k0|%k0, %k2}
8928 and{q}\t{%2, %0|%0, %2}
8929 and{q}\t{%2, %0|%0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI,DI,DI")])
8933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8934 (define_insn "*andsi_2_zext"
8935 [(set (reg FLAGS_REG)
8937 (match_operand:SI 1 "nonimmediate_operand" "%0")
8938 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8940 (set (match_operand:DI 0 "register_operand" "=r")
8941 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8942 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8943 && ix86_binary_operator_ok (AND, SImode, operands)"
8944 "and{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8948 (define_insn "*andqi_2_maybe_si"
8949 [(set (reg FLAGS_REG)
8951 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8952 (match_operand:QI 2 "general_operand" "qn,m,n"))
8954 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8955 (and:QI (match_dup 1) (match_dup 2)))]
8956 "ix86_binary_operator_ok (AND, QImode, operands)
8957 && ix86_match_ccmode (insn,
8958 CONST_INT_P (operands[2])
8959 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8961 if (which_alternative == 2)
8963 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8965 return "and{l}\t{%2, %k0|%k0, %2}";
8967 return "and{b}\t{%2, %0|%0, %2}";
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "QI,QI,SI")
8971 ;; Potential partial reg stall on alternative 2.
8972 (set (attr "preferred_for_speed")
8973 (cond [(eq_attr "alternative" "2")
8974 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8975 (symbol_ref "true")))])
8977 (define_insn "*and<mode>_2"
8978 [(set (reg FLAGS_REG)
8979 (compare (and:SWI124
8980 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8981 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
8983 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
8984 (and:SWI124 (match_dup 1) (match_dup 2)))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8987 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "<MODE>")])
8991 (define_insn "andqi_ext_1"
8992 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8998 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9001 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9004 rtx_equal_p (operands[0], operands[1])"
9005 "and{b}\t{%2, %h0|%h0, %2}"
9006 [(set_attr "isa" "*,nox64")
9007 (set_attr "type" "alu")
9008 (set_attr "mode" "QI")])
9010 ;; Generated by peephole translating test to and. This shows up
9011 ;; often in fp comparisons.
9012 (define_insn "*andqi_ext_1_cc"
9013 [(set (reg FLAGS_REG)
9017 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9020 (match_operand:QI 2 "general_operand" "QnBc,m"))
9022 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9028 (zero_extract:SI (match_dup 1)
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9034 && rtx_equal_p (operands[0], operands[1])"
9035 "and{b}\t{%2, %h0|%h0, %2}"
9036 [(set_attr "isa" "*,nox64")
9037 (set_attr "type" "alu")
9038 (set_attr "mode" "QI")])
9040 (define_insn "*andqi_ext_2"
9041 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9047 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9051 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9053 (const_int 8)) 0)) 0))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9056 rtx_equal_p (operands[0], operands[1])
9057 || rtx_equal_p (operands[0], operands[2])"
9058 "and{b}\t{%h2, %h0|%h0, %h2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "QI")])
9062 ;; Convert wide AND instructions with immediate operand to shorter QImode
9063 ;; equivalents when possible.
9064 ;; Don't do the splitting with memory operands, since it introduces risk
9065 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9066 ;; for size, but that can (should?) be handled by generic code instead.
9068 [(set (match_operand:SWI248 0 "QIreg_operand")
9069 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9070 (match_operand:SWI248 2 "const_int_operand")))
9071 (clobber (reg:CC FLAGS_REG))]
9073 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9074 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9076 [(set (zero_extract:SI (match_dup 0)
9082 (zero_extract:SI (match_dup 1)
9086 (clobber (reg:CC FLAGS_REG))])]
9088 operands[0] = gen_lowpart (SImode, operands[0]);
9089 operands[1] = gen_lowpart (SImode, operands[1]);
9090 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9093 ;; Since AND can be encoded with sign extended immediate, this is only
9094 ;; profitable when 7th bit is not set.
9096 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9097 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9098 (match_operand:SWI248 2 "const_int_operand")))
9099 (clobber (reg:CC FLAGS_REG))]
9101 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9102 && !(~INTVAL (operands[2]) & ~255)
9103 && !(INTVAL (operands[2]) & 128)"
9104 [(parallel [(set (strict_low_part (match_dup 0))
9105 (and:QI (match_dup 1)
9107 (clobber (reg:CC FLAGS_REG))])]
9109 operands[0] = gen_lowpart (QImode, operands[0]);
9110 operands[1] = gen_lowpart (QImode, operands[1]);
9111 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9114 (define_insn "*andndi3_doubleword"
9115 [(set (match_operand:DI 0 "register_operand")
9117 (not:DI (match_operand:DI 1 "register_operand"))
9118 (match_operand:DI 2 "nonimmediate_operand")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9121 && ix86_pre_reload_split ()"
9125 [(set (match_operand:DI 0 "register_operand")
9127 (not:DI (match_operand:DI 1 "register_operand"))
9128 (match_operand:DI 2 "nonimmediate_operand")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9131 && can_create_pseudo_p ()"
9132 [(parallel [(set (match_dup 0)
9133 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9134 (clobber (reg:CC FLAGS_REG))])
9135 (parallel [(set (match_dup 3)
9136 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9137 (clobber (reg:CC FLAGS_REG))])]
9138 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9141 [(set (match_operand:DI 0 "register_operand")
9143 (not:DI (match_operand:DI 1 "register_operand"))
9144 (match_operand:DI 2 "nonimmediate_operand")))
9145 (clobber (reg:CC FLAGS_REG))]
9146 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9147 && can_create_pseudo_p ()"
9148 [(set (match_dup 6) (not:SI (match_dup 1)))
9149 (parallel [(set (match_dup 0)
9150 (and:SI (match_dup 6) (match_dup 2)))
9151 (clobber (reg:CC FLAGS_REG))])
9152 (set (match_dup 7) (not:SI (match_dup 4)))
9153 (parallel [(set (match_dup 3)
9154 (and:SI (match_dup 7) (match_dup 5)))
9155 (clobber (reg:CC FLAGS_REG))])]
9157 operands[6] = gen_reg_rtx (SImode);
9158 operands[7] = gen_reg_rtx (SImode);
9160 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9163 (define_insn "*andn<mode>_1"
9164 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9166 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9167 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9168 (clobber (reg:CC FLAGS_REG))]
9170 "andn\t{%2, %1, %0|%0, %1, %2}"
9171 [(set_attr "type" "bitmanip")
9172 (set_attr "btver2_decode" "direct, double")
9173 (set_attr "mode" "<MODE>")])
9175 (define_insn "*andn<mode>_1"
9176 [(set (match_operand:SWI12 0 "register_operand" "=r")
9178 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9179 (match_operand:SWI12 2 "register_operand" "r")))
9180 (clobber (reg:CC FLAGS_REG))]
9182 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9183 [(set_attr "type" "bitmanip")
9184 (set_attr "btver2_decode" "direct")
9185 (set_attr "mode" "SI")])
9187 (define_insn "*andn_<mode>_ccno"
9188 [(set (reg FLAGS_REG)
9191 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9192 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9194 (clobber (match_scratch:SWI48 0 "=r,r"))]
9195 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9196 "andn\t{%2, %1, %0|%0, %1, %2}"
9197 [(set_attr "type" "bitmanip")
9198 (set_attr "btver2_decode" "direct, double")
9199 (set_attr "mode" "<MODE>")])
9201 ;; Logical inclusive and exclusive OR instructions
9203 ;; %%% This used to optimize known byte-wide and operations to memory.
9204 ;; If this is considered useful, it should be done with splitters.
9206 (define_expand "<code><mode>3"
9207 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9208 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9209 (match_operand:SWIM1248s 2 "<general_operand>")))]
9211 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9213 (define_insn_and_split "*<code>di3_doubleword"
9214 [(set (match_operand:DI 0 "nonimmediate_operand")
9216 (match_operand:DI 1 "nonimmediate_operand")
9217 (match_operand:DI 2 "x86_64_szext_general_operand")))
9218 (clobber (reg:CC FLAGS_REG))]
9219 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9220 && ix86_binary_operator_ok (<CODE>, DImode, operands)
9221 && ix86_pre_reload_split ()"
9226 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9228 if (operands[2] == const0_rtx)
9229 emit_move_insn (operands[0], operands[1]);
9230 else if (operands[2] == constm1_rtx)
9233 emit_move_insn (operands[0], constm1_rtx);
9235 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9238 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9240 if (operands[5] == const0_rtx)
9241 emit_move_insn (operands[3], operands[4]);
9242 else if (operands[5] == constm1_rtx)
9245 emit_move_insn (operands[3], constm1_rtx);
9247 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9250 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9255 (define_insn "*<code><mode>_1"
9256 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r")
9258 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9259 (match_operand:SWI248 2 "<general_operand>" "r<i>,m")))
9260 (clobber (reg:CC FLAGS_REG))]
9261 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9262 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9263 [(set_attr "type" "alu")
9264 (set_attr "mode" "<MODE>")])
9266 (define_insn_and_split "*iordi_1_bts"
9267 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9269 (match_operand:DI 1 "nonimmediate_operand" "%0")
9270 (match_operand:DI 2 "const_int_operand" "n")))
9271 (clobber (reg:CC FLAGS_REG))]
9272 "TARGET_64BIT && TARGET_USE_BT
9273 && ix86_binary_operator_ok (IOR, DImode, operands)
9274 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9276 "&& reload_completed"
9277 [(parallel [(set (zero_extract:DI (match_dup 0)
9281 (clobber (reg:CC FLAGS_REG))])]
9282 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9283 [(set_attr "type" "alu1")
9284 (set_attr "prefix_0f" "1")
9285 (set_attr "znver1_decode" "double")
9286 (set_attr "mode" "DI")])
9288 (define_insn_and_split "*xordi_1_btc"
9289 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9291 (match_operand:DI 1 "nonimmediate_operand" "%0")
9292 (match_operand:DI 2 "const_int_operand" "n")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "TARGET_64BIT && TARGET_USE_BT
9295 && ix86_binary_operator_ok (XOR, DImode, operands)
9296 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9298 "&& reload_completed"
9299 [(parallel [(set (zero_extract:DI (match_dup 0)
9302 (not:DI (zero_extract:DI (match_dup 0)
9305 (clobber (reg:CC FLAGS_REG))])]
9306 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9307 [(set_attr "type" "alu1")
9308 (set_attr "prefix_0f" "1")
9309 (set_attr "znver1_decode" "double")
9310 (set_attr "mode" "DI")])
9312 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9313 (define_insn "*<code>si_1_zext"
9314 [(set (match_operand:DI 0 "register_operand" "=r")
9316 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9317 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9318 (clobber (reg:CC FLAGS_REG))]
9319 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9320 "<logic>{l}\t{%2, %k0|%k0, %2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "SI")])
9324 (define_insn "*<code>si_1_zext_imm"
9325 [(set (match_operand:DI 0 "register_operand" "=r")
9327 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9328 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9331 "<logic>{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9335 (define_insn "*<code>qi_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9337 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9338 (match_operand:QI 2 "general_operand" "qn,m,rn")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9342 <logic>{b}\t{%2, %0|%0, %2}
9343 <logic>{b}\t{%2, %0|%0, %2}
9344 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "QI,QI,SI")
9347 ;; Potential partial reg stall on alternative 2.
9348 (set (attr "preferred_for_speed")
9349 (cond [(eq_attr "alternative" "2")
9350 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9351 (symbol_ref "true")))])
9353 (define_insn "*<code><mode>_1_slp"
9354 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9355 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9356 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9357 (clobber (reg:CC FLAGS_REG))]
9358 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9359 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9360 && (rtx_equal_p (operands[0], operands[1])
9361 || rtx_equal_p (operands[0], operands[2]))"
9362 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9363 [(set_attr "type" "alu")
9364 (set_attr "mode" "<MODE>")])
9366 (define_insn "*<code><mode>_2"
9367 [(set (reg FLAGS_REG)
9368 (compare (any_or:SWI
9369 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9370 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9372 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9373 (any_or:SWI (match_dup 1) (match_dup 2)))]
9374 "ix86_match_ccmode (insn, CCNOmode)
9375 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9376 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9377 [(set_attr "type" "alu")
9378 (set_attr "mode" "<MODE>")])
9380 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9381 ;; ??? Special case for immediate operand is missing - it is tricky.
9382 (define_insn "*<code>si_2_zext"
9383 [(set (reg FLAGS_REG)
9384 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9385 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9387 (set (match_operand:DI 0 "register_operand" "=r")
9388 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9389 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9390 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9391 "<logic>{l}\t{%2, %k0|%k0, %2}"
9392 [(set_attr "type" "alu")
9393 (set_attr "mode" "SI")])
9395 (define_insn "*<code>si_2_zext_imm"
9396 [(set (reg FLAGS_REG)
9398 (match_operand:SI 1 "nonimmediate_operand" "%0")
9399 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9401 (set (match_operand:DI 0 "register_operand" "=r")
9402 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9403 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9404 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9405 "<logic>{l}\t{%2, %k0|%k0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "SI")])
9409 (define_insn "*<code><mode>_3"
9410 [(set (reg FLAGS_REG)
9411 (compare (any_or:SWI
9412 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9413 (match_operand:SWI 2 "<general_operand>" "<g>"))
9415 (clobber (match_scratch:SWI 0 "=<r>"))]
9416 "ix86_match_ccmode (insn, CCNOmode)
9417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9418 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9419 [(set_attr "type" "alu")
9420 (set_attr "mode" "<MODE>")])
9422 (define_insn "*<code>qi_ext_1"
9423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9429 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9432 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9435 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9436 && rtx_equal_p (operands[0], operands[1])"
9437 "<logic>{b}\t{%2, %h0|%h0, %2}"
9438 [(set_attr "isa" "*,nox64")
9439 (set_attr "type" "alu")
9440 (set_attr "mode" "QI")])
9442 (define_insn "*<code>qi_ext_2"
9443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9449 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9453 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9455 (const_int 8)) 0)) 0))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9458 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9459 && (rtx_equal_p (operands[0], operands[1])
9460 || rtx_equal_p (operands[0], operands[2]))"
9461 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "mode" "QI")])
9465 ;; Convert wide OR instructions with immediate operand to shorter QImode
9466 ;; equivalents when possible.
9467 ;; Don't do the splitting with memory operands, since it introduces risk
9468 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9469 ;; for size, but that can (should?) be handled by generic code instead.
9471 [(set (match_operand:SWI248 0 "QIreg_operand")
9472 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9473 (match_operand:SWI248 2 "const_int_operand")))
9474 (clobber (reg:CC FLAGS_REG))]
9476 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9477 && !(INTVAL (operands[2]) & ~(255 << 8))"
9479 [(set (zero_extract:SI (match_dup 0)
9485 (zero_extract:SI (match_dup 1)
9489 (clobber (reg:CC FLAGS_REG))])]
9491 operands[0] = gen_lowpart (SImode, operands[0]);
9492 operands[1] = gen_lowpart (SImode, operands[1]);
9493 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9496 ;; Since OR can be encoded with sign extended immediate, this is only
9497 ;; profitable when 7th bit is set.
9499 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9500 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9501 (match_operand:SWI248 2 "const_int_operand")))
9502 (clobber (reg:CC FLAGS_REG))]
9504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9505 && !(INTVAL (operands[2]) & ~255)
9506 && (INTVAL (operands[2]) & 128)"
9507 [(parallel [(set (strict_low_part (match_dup 0))
9508 (any_or:QI (match_dup 1)
9510 (clobber (reg:CC FLAGS_REG))])]
9512 operands[0] = gen_lowpart (QImode, operands[0]);
9513 operands[1] = gen_lowpart (QImode, operands[1]);
9514 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9517 (define_expand "xorqi_ext_1_cc"
9519 (set (reg:CCNO FLAGS_REG)
9523 (zero_extract:SI (match_operand 1 "ext_register_operand")
9526 (match_operand 2 "const_int_operand"))
9528 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9534 (zero_extract:SI (match_dup 1)
9537 (match_dup 2)) 0))])])
9539 (define_insn "*xorqi_ext_1_cc"
9540 [(set (reg FLAGS_REG)
9544 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9547 (match_operand:QI 2 "general_operand" "QnBc,m"))
9549 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9555 (zero_extract:SI (match_dup 1)
9559 "ix86_match_ccmode (insn, CCNOmode)
9560 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9561 && rtx_equal_p (operands[0], operands[1])"
9562 "xor{b}\t{%2, %h0|%h0, %2}"
9563 [(set_attr "isa" "*,nox64")
9564 (set_attr "type" "alu")
9565 (set_attr "mode" "QI")])
9567 ;; Negation instructions
9569 (define_expand "neg<mode>2"
9570 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9571 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9573 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9575 (define_insn_and_split "*neg<dwi>2_doubleword"
9576 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9577 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9583 [(set (reg:CCZ FLAGS_REG)
9584 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9585 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9588 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9591 (clobber (reg:CC FLAGS_REG))])
9594 (neg:DWIH (match_dup 2)))
9595 (clobber (reg:CC FLAGS_REG))])]
9596 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9598 (define_insn "*neg<mode>2_1"
9599 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9600 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9603 "neg{<imodesuffix>}\t%0"
9604 [(set_attr "type" "negnot")
9605 (set_attr "mode" "<MODE>")])
9607 (define_insn "*negsi2_1_zext"
9608 [(set (match_operand:DI 0 "register_operand" "=r")
9610 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
9611 (clobber (reg:CC FLAGS_REG))]
9612 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9614 [(set_attr "type" "negnot")
9615 (set_attr "mode" "SI")])
9617 ;; The problem with neg is that it does not perform (compare x 0),
9618 ;; it really performs (compare 0 x), which leaves us with the zero
9619 ;; flag being the only useful item.
9621 (define_insn "*neg<mode>2_cmpz"
9622 [(set (reg:CCZ FLAGS_REG)
9624 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9626 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9627 (neg:SWI (match_dup 1)))]
9628 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9629 "neg{<imodesuffix>}\t%0"
9630 [(set_attr "type" "negnot")
9631 (set_attr "mode" "<MODE>")])
9633 (define_insn "*negsi2_cmpz_zext"
9634 [(set (reg:CCZ FLAGS_REG)
9636 (neg:SI (match_operand:SI 1 "register_operand" "0"))
9638 (set (match_operand:DI 0 "register_operand" "=r")
9640 (neg:SI (match_dup 1))))]
9641 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9643 [(set_attr "type" "negnot")
9644 (set_attr "mode" "SI")])
9646 ;; Negate with jump on overflow.
9647 (define_expand "negv<mode>3"
9648 [(parallel [(set (reg:CCO FLAGS_REG)
9649 (ne:CCO (match_operand:SWI 1 "register_operand")
9651 (set (match_operand:SWI 0 "register_operand")
9652 (neg:SWI (match_dup 1)))])
9653 (set (pc) (if_then_else
9654 (eq (reg:CCO FLAGS_REG) (const_int 0))
9655 (label_ref (match_operand 2))
9660 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9664 (define_insn "*negv<mode>3"
9665 [(set (reg:CCO FLAGS_REG)
9666 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9667 (match_operand:SWI 2 "const_int_operand")))
9668 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9669 (neg:SWI (match_dup 1)))]
9670 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9671 && mode_signbit_p (<MODE>mode, operands[2])"
9672 "neg{<imodesuffix>}\t%0"
9673 [(set_attr "type" "negnot")
9674 (set_attr "mode" "<MODE>")])
9676 (define_expand "<code>tf2"
9677 [(set (match_operand:TF 0 "register_operand")
9678 (absneg:TF (match_operand:TF 1 "register_operand")))]
9680 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9682 (define_insn "*<code>tf2_1"
9683 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9685 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
9686 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))
9687 (clobber (reg:CC FLAGS_REG))]
9690 [(set_attr "isa" "noavx,noavx,avx,avx")])
9692 (define_insn "*nabstf2_1"
9693 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9696 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
9697 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
9700 [(set_attr "isa" "noavx,noavx,avx,avx")])
9702 ;; Special expand pattern to handle integer mode abs
9704 (define_expand "abs<mode>2"
9705 [(set (match_operand:SWI48x 0 "register_operand")
9707 (match_operand:SWI48x 1 "register_operand")))]
9710 machine_mode mode = <MODE>mode;
9712 /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) -
9713 ((signed) x >> (W-1)) */
9714 rtx shift_amount = gen_int_shift_amount (mode,
9715 GET_MODE_PRECISION (mode)
9717 shift_amount = convert_modes (E_QImode, GET_MODE (shift_amount),
9719 rtx shift_dst = gen_reg_rtx (mode);
9720 rtx shift_op = gen_rtx_SET (shift_dst,
9721 gen_rtx_fmt_ee (ASHIFTRT, mode,
9722 operands[1], shift_amount));
9723 rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode,
9725 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, shift_op,
9728 rtx xor_op = gen_rtx_SET (operands[0],
9729 gen_rtx_fmt_ee (XOR, mode, shift_dst,
9731 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, xor_op, clobber)));
9733 rtx minus_op = gen_rtx_SET (operands[0],
9734 gen_rtx_fmt_ee (MINUS, mode,
9735 operands[0], shift_dst));
9736 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, minus_op,
9741 (define_expand "<code><mode>2"
9742 [(set (match_operand:X87MODEF 0 "register_operand")
9743 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9744 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9745 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9747 ;; Changing of sign for FP values is doable using integer unit too.
9748 (define_insn "*<code><mode>2_i387_1"
9749 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9751 (match_operand:X87MODEF 1 "register_operand" "0,0")))
9752 (clobber (reg:CC FLAGS_REG))]
9757 [(set (match_operand:X87MODEF 0 "fp_register_operand")
9758 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_80387 && reload_completed"
9761 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
9764 [(set (match_operand:X87MODEF 0 "general_reg_operand")
9765 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "TARGET_80387 && reload_completed"
9769 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9771 (define_insn "*<code><mode>2_1"
9772 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
9774 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
9775 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9779 [(set_attr "isa" "noavx,noavx,avx,*,*")
9780 (set (attr "enabled")
9782 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9784 (eq_attr "alternative" "3,4")
9785 (symbol_ref "TARGET_MIX_SSE_I387")
9788 (eq_attr "alternative" "3,4")
9790 (symbol_ref "false"))))])
9793 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9795 (match_operand:SSEMODEF 1 "vector_operand")))
9796 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9799 || (TARGET_SSE && (<MODE>mode == TFmode)))
9800 && reload_completed"
9801 [(set (match_dup 0) (match_dup 3))]
9803 machine_mode mode = <MODE>mode;
9804 machine_mode vmode = <ssevecmodef>mode;
9805 enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR;
9807 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9808 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9812 if (MEM_P (operands[1]))
9813 std::swap (operands[1], operands[2]);
9817 if (operands_match_p (operands[0], operands[2]))
9818 std::swap (operands[1], operands[2]);
9822 = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]);
9826 [(set (match_operand:MODEF 0 "fp_register_operand")
9827 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
9828 (use (match_operand 2))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_80387 && reload_completed"
9831 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
9834 [(set (match_operand:MODEF 0 "general_reg_operand")
9835 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
9836 (use (match_operand 2))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_80387 && reload_completed"
9840 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9842 (define_insn "*nabs<mode>2_1"
9843 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
9846 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
9847 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
9848 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9850 [(set_attr "isa" "noavx,noavx,avx")])
9853 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9856 (match_operand:SSEMODEF 1 "vector_operand"))))
9857 (use (match_operand:<ssevecmodef> 2 "vector_operand"))]
9858 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9859 || (TARGET_SSE && (<MODE>mode == TFmode)))
9860 && reload_completed"
9861 [(set (match_dup 0) (match_dup 3))]
9863 machine_mode mode = <MODE>mode;
9864 machine_mode vmode = <ssevecmodef>mode;
9866 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9867 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9871 if (MEM_P (operands[1]))
9872 std::swap (operands[1], operands[2]);
9876 if (operands_match_p (operands[0], operands[2]))
9877 std::swap (operands[1], operands[2]);
9881 = gen_rtx_fmt_ee (IOR, vmode, operands[1], operands[2]);
9884 ;; Conditionalize these after reload. If they match before reload, we
9885 ;; lose the clobber and ability to use integer instructions.
9887 (define_insn "*<code><mode>2_i387"
9888 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9889 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9890 "TARGET_80387 && reload_completed"
9892 [(set_attr "type" "fsgn")
9893 (set_attr "mode" "<MODE>")])
9895 ;; Copysign instructions
9897 (define_expand "copysign<mode>3"
9898 [(match_operand:SSEMODEF 0 "register_operand")
9899 (match_operand:SSEMODEF 1 "nonmemory_operand")
9900 (match_operand:SSEMODEF 2 "register_operand")]
9901 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9902 || (TARGET_SSE && (<MODE>mode == TFmode))"
9903 "ix86_expand_copysign (operands); DONE;")
9905 (define_insn_and_split "@copysign<mode>3_const"
9906 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
9908 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
9909 (match_operand:SSEMODEF 2 "register_operand" "0")
9910 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
9912 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9913 || (TARGET_SSE && (<MODE>mode == TFmode))"
9915 "&& reload_completed"
9917 "ix86_split_copysign_const (operands); DONE;")
9919 (define_insn "@copysign<mode>3_var"
9920 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9922 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
9923 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
9924 (match_operand:<ssevecmodef> 4
9925 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9926 (match_operand:<ssevecmodef> 5
9927 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9929 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9930 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9931 || (TARGET_SSE && (<MODE>mode == TFmode))"
9935 [(set (match_operand:SSEMODEF 0 "register_operand")
9937 [(match_operand:SSEMODEF 2 "register_operand")
9938 (match_operand:SSEMODEF 3 "register_operand")
9939 (match_operand:<ssevecmodef> 4)
9940 (match_operand:<ssevecmodef> 5)]
9942 (clobber (match_scratch:<ssevecmodef> 1))]
9943 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9944 || (TARGET_SSE && (<MODE>mode == TFmode)))
9945 && reload_completed"
9947 "ix86_split_copysign_var (operands); DONE;")
9949 (define_expand "xorsign<mode>3"
9950 [(match_operand:MODEF 0 "register_operand")
9951 (match_operand:MODEF 1 "register_operand")
9952 (match_operand:MODEF 2 "register_operand")]
9953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9954 "ix86_expand_xorsign (operands); DONE;")
9956 (define_insn_and_split "@xorsign<mode>3_1"
9957 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9959 [(match_operand:MODEF 1 "register_operand" "Yv")
9960 (match_operand:MODEF 2 "register_operand" "0")
9961 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9963 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9965 "&& reload_completed"
9967 "ix86_split_xorsign (operands); DONE;")
9969 ;; One complement instructions
9971 (define_expand "one_cmpl<mode>2"
9972 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9973 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
9975 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9977 (define_insn_and_split "*one_cmpldi2_doubleword"
9978 [(set (match_operand:DI 0 "nonimmediate_operand")
9979 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
9980 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9981 && ix86_unary_operator_ok (NOT, DImode, operands)
9982 && ix86_pre_reload_split ()"
9986 (not:SI (match_dup 1)))
9988 (not:SI (match_dup 3)))]
9989 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9991 (define_insn "*one_cmpl<mode>2_1"
9992 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9993 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9994 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9995 "not{<imodesuffix>}\t%0"
9996 [(set_attr "type" "negnot")
9997 (set_attr "mode" "<MODE>")])
9999 (define_insn "*one_cmplsi2_1_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=r")
10002 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10003 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10005 [(set_attr "type" "negnot")
10006 (set_attr "mode" "SI")])
10008 (define_insn "*one_cmplqi2_1"
10009 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10010 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10011 "ix86_unary_operator_ok (NOT, QImode, operands)"
10015 [(set_attr "type" "negnot")
10016 (set_attr "mode" "QI,SI")
10017 ;; Potential partial reg stall on alternative 1.
10018 (set (attr "preferred_for_speed")
10019 (cond [(eq_attr "alternative" "1")
10020 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10021 (symbol_ref "true")))])
10023 (define_insn "*one_cmpl<mode>2_2"
10024 [(set (reg FLAGS_REG)
10025 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10027 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10028 (not:SWI (match_dup 1)))]
10029 "ix86_match_ccmode (insn, CCNOmode)
10030 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10032 [(set_attr "type" "alu1")
10033 (set_attr "mode" "<MODE>")])
10036 [(set (match_operand 0 "flags_reg_operand")
10037 (match_operator 2 "compare_operator"
10038 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10040 (set (match_operand:SWI 1 "nonimmediate_operand")
10041 (not:SWI (match_dup 3)))]
10042 "ix86_match_ccmode (insn, CCNOmode)"
10043 [(parallel [(set (match_dup 0)
10044 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10047 (xor:SWI (match_dup 3) (const_int -1)))])])
10049 (define_insn "*one_cmplsi2_2_zext"
10050 [(set (reg FLAGS_REG)
10051 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10053 (set (match_operand:DI 0 "register_operand" "=r")
10054 (zero_extend:DI (not:SI (match_dup 1))))]
10055 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10056 && ix86_unary_operator_ok (NOT, SImode, operands)"
10058 [(set_attr "type" "alu1")
10059 (set_attr "mode" "SI")])
10062 [(set (match_operand 0 "flags_reg_operand")
10063 (match_operator 2 "compare_operator"
10064 [(not:SI (match_operand:SI 3 "register_operand"))
10066 (set (match_operand:DI 1 "register_operand")
10067 (zero_extend:DI (not:SI (match_dup 3))))]
10068 "ix86_match_ccmode (insn, CCNOmode)"
10069 [(parallel [(set (match_dup 0)
10070 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10073 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10075 ;; Shift instructions
10077 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10078 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10079 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10080 ;; from the assembler input.
10082 ;; This instruction shifts the target reg/mem as usual, but instead of
10083 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10084 ;; is a left shift double, bits are taken from the high order bits of
10085 ;; reg, else if the insn is a shift right double, bits are taken from the
10086 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10087 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10089 ;; Since sh[lr]d does not change the `reg' operand, that is done
10090 ;; separately, making all shifts emit pairs of shift double and normal
10091 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10092 ;; support a 63 bit shift, each shift where the count is in a reg expands
10093 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10095 ;; If the shift count is a constant, we need never emit more than one
10096 ;; shift pair, instead using moves and sign extension for counts greater
10099 (define_expand "ashl<mode>3"
10100 [(set (match_operand:SDWIM 0 "<shift_operand>")
10101 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10102 (match_operand:QI 2 "nonmemory_operand")))]
10104 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10106 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10107 [(set (match_operand:<DWI> 0 "register_operand")
10109 (match_operand:<DWI> 1 "register_operand")
10112 (match_operand:SI 2 "register_operand" "c")
10113 (match_operand:SI 3 "const_int_operand")) 0)))
10114 (clobber (reg:CC FLAGS_REG))]
10115 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10116 && ix86_pre_reload_split ()"
10120 [(set (match_dup 6)
10121 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10122 (lshiftrt:DWIH (match_dup 5)
10123 (minus:QI (match_dup 8) (match_dup 2)))))
10124 (clobber (reg:CC FLAGS_REG))])
10126 [(set (match_dup 4)
10127 (ashift:DWIH (match_dup 5) (match_dup 2)))
10128 (clobber (reg:CC FLAGS_REG))])]
10130 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10132 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10134 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10135 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10137 rtx tem = gen_reg_rtx (SImode);
10138 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10142 operands[2] = gen_lowpart (QImode, operands[2]);
10144 if (!rtx_equal_p (operands[6], operands[7]))
10145 emit_move_insn (operands[6], operands[7]);
10148 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10149 [(set (match_operand:<DWI> 0 "register_operand")
10151 (match_operand:<DWI> 1 "register_operand")
10153 (match_operand:QI 2 "register_operand" "c")
10154 (match_operand:QI 3 "const_int_operand"))))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10157 && ix86_pre_reload_split ()"
10161 [(set (match_dup 6)
10162 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10163 (lshiftrt:DWIH (match_dup 5)
10164 (minus:QI (match_dup 8) (match_dup 2)))))
10165 (clobber (reg:CC FLAGS_REG))])
10167 [(set (match_dup 4)
10168 (ashift:DWIH (match_dup 5) (match_dup 2)))
10169 (clobber (reg:CC FLAGS_REG))])]
10171 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10173 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10175 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10176 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10178 rtx tem = gen_reg_rtx (QImode);
10179 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10183 if (!rtx_equal_p (operands[6], operands[7]))
10184 emit_move_insn (operands[6], operands[7]);
10187 (define_insn "*ashl<mode>3_doubleword"
10188 [(set (match_operand:DWI 0 "register_operand" "=&r")
10189 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10190 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10191 (clobber (reg:CC FLAGS_REG))]
10194 [(set_attr "type" "multi")])
10197 [(set (match_operand:DWI 0 "register_operand")
10198 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10199 (match_operand:QI 2 "nonmemory_operand")))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10203 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10205 ;; By default we don't ask for a scratch register, because when DWImode
10206 ;; values are manipulated, registers are already at a premium. But if
10207 ;; we have one handy, we won't turn it away.
10210 [(match_scratch:DWIH 3 "r")
10211 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10213 (match_operand:<DWI> 1 "nonmemory_operand")
10214 (match_operand:QI 2 "nonmemory_operand")))
10215 (clobber (reg:CC FLAGS_REG))])
10219 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10221 (define_insn "x86_64_shld"
10222 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10223 (ior:DI (ashift:DI (match_dup 0)
10224 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10225 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10226 (minus:QI (const_int 64) (match_dup 2)))))
10227 (clobber (reg:CC FLAGS_REG))]
10229 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10230 [(set_attr "type" "ishift")
10231 (set_attr "prefix_0f" "1")
10232 (set_attr "mode" "DI")
10233 (set_attr "athlon_decode" "vector")
10234 (set_attr "amdfam10_decode" "vector")
10235 (set_attr "bdver1_decode" "vector")])
10237 (define_insn "x86_shld"
10238 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10239 (ior:SI (ashift:SI (match_dup 0)
10240 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10241 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10242 (minus:QI (const_int 32) (match_dup 2)))))
10243 (clobber (reg:CC FLAGS_REG))]
10245 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10246 [(set_attr "type" "ishift")
10247 (set_attr "prefix_0f" "1")
10248 (set_attr "mode" "SI")
10249 (set_attr "pent_pair" "np")
10250 (set_attr "athlon_decode" "vector")
10251 (set_attr "amdfam10_decode" "vector")
10252 (set_attr "bdver1_decode" "vector")])
10254 (define_expand "@x86_shift<mode>_adj_1"
10255 [(set (reg:CCZ FLAGS_REG)
10256 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10259 (set (match_operand:SWI48 0 "register_operand")
10260 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10261 (match_operand:SWI48 1 "register_operand")
10264 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10265 (match_operand:SWI48 3 "register_operand")
10268 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10270 (define_expand "@x86_shift<mode>_adj_2"
10271 [(use (match_operand:SWI48 0 "register_operand"))
10272 (use (match_operand:SWI48 1 "register_operand"))
10273 (use (match_operand:QI 2 "register_operand"))]
10276 rtx_code_label *label = gen_label_rtx ();
10279 emit_insn (gen_testqi_ccz_1 (operands[2],
10280 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10282 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10283 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10284 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10285 gen_rtx_LABEL_REF (VOIDmode, label),
10287 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10288 JUMP_LABEL (tmp) = label;
10290 emit_move_insn (operands[0], operands[1]);
10291 ix86_expand_clear (operands[1]);
10293 emit_label (label);
10294 LABEL_NUSES (label) = 1;
10299 ;; Avoid useless masking of count operand.
10300 (define_insn_and_split "*ashl<mode>3_mask"
10301 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10303 (match_operand:SWI48 1 "nonimmediate_operand")
10306 (match_operand:SI 2 "register_operand" "c,r")
10307 (match_operand:SI 3 "const_int_operand")) 0)))
10308 (clobber (reg:CC FLAGS_REG))]
10309 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10310 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10311 == GET_MODE_BITSIZE (<MODE>mode)-1
10312 && ix86_pre_reload_split ()"
10316 [(set (match_dup 0)
10317 (ashift:SWI48 (match_dup 1)
10319 (clobber (reg:CC FLAGS_REG))])]
10320 "operands[2] = gen_lowpart (QImode, operands[2]);"
10321 [(set_attr "isa" "*,bmi2")])
10323 (define_insn_and_split "*ashl<mode>3_mask_1"
10324 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10326 (match_operand:SWI48 1 "nonimmediate_operand")
10328 (match_operand:QI 2 "register_operand" "c,r")
10329 (match_operand:QI 3 "const_int_operand"))))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10332 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10333 == GET_MODE_BITSIZE (<MODE>mode)-1
10334 && ix86_pre_reload_split ()"
10338 [(set (match_dup 0)
10339 (ashift:SWI48 (match_dup 1)
10341 (clobber (reg:CC FLAGS_REG))])]
10343 [(set_attr "isa" "*,bmi2")])
10345 (define_insn "*bmi2_ashl<mode>3_1"
10346 [(set (match_operand:SWI48 0 "register_operand" "=r")
10347 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10348 (match_operand:SWI48 2 "register_operand" "r")))]
10350 "shlx\t{%2, %1, %0|%0, %1, %2}"
10351 [(set_attr "type" "ishiftx")
10352 (set_attr "mode" "<MODE>")])
10354 (define_insn "*ashl<mode>3_1"
10355 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10356 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10357 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10361 switch (get_attr_type (insn))
10368 gcc_assert (operands[2] == const1_rtx);
10369 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10370 return "add{<imodesuffix>}\t%0, %0";
10373 if (operands[2] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "sal{<imodesuffix>}\t%0";
10377 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10380 [(set_attr "isa" "*,*,bmi2")
10382 (cond [(eq_attr "alternative" "1")
10383 (const_string "lea")
10384 (eq_attr "alternative" "2")
10385 (const_string "ishiftx")
10386 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10387 (match_operand 0 "register_operand"))
10388 (match_operand 2 "const1_operand"))
10389 (const_string "alu")
10391 (const_string "ishift")))
10392 (set (attr "length_immediate")
10394 (ior (eq_attr "type" "alu")
10395 (and (eq_attr "type" "ishift")
10396 (and (match_operand 2 "const1_operand")
10397 (ior (match_test "TARGET_SHIFT1")
10398 (match_test "optimize_function_for_size_p (cfun)")))))
10400 (const_string "*")))
10401 (set_attr "mode" "<MODE>")])
10403 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10405 [(set (match_operand:SWI48 0 "register_operand")
10406 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10407 (match_operand:QI 2 "register_operand")))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_BMI2 && reload_completed"
10410 [(set (match_dup 0)
10411 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10412 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10414 (define_insn "*bmi2_ashlsi3_1_zext"
10415 [(set (match_operand:DI 0 "register_operand" "=r")
10417 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10418 (match_operand:SI 2 "register_operand" "r"))))]
10419 "TARGET_64BIT && TARGET_BMI2"
10420 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10421 [(set_attr "type" "ishiftx")
10422 (set_attr "mode" "SI")])
10424 (define_insn "*ashlsi3_1_zext"
10425 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10427 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10428 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10429 (clobber (reg:CC FLAGS_REG))]
10430 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10432 switch (get_attr_type (insn))
10439 gcc_assert (operands[2] == const1_rtx);
10440 return "add{l}\t%k0, %k0";
10443 if (operands[2] == const1_rtx
10444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445 return "sal{l}\t%k0";
10447 return "sal{l}\t{%2, %k0|%k0, %2}";
10450 [(set_attr "isa" "*,*,bmi2")
10452 (cond [(eq_attr "alternative" "1")
10453 (const_string "lea")
10454 (eq_attr "alternative" "2")
10455 (const_string "ishiftx")
10456 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10457 (match_operand 2 "const1_operand"))
10458 (const_string "alu")
10460 (const_string "ishift")))
10461 (set (attr "length_immediate")
10463 (ior (eq_attr "type" "alu")
10464 (and (eq_attr "type" "ishift")
10465 (and (match_operand 2 "const1_operand")
10466 (ior (match_test "TARGET_SHIFT1")
10467 (match_test "optimize_function_for_size_p (cfun)")))))
10469 (const_string "*")))
10470 (set_attr "mode" "SI")])
10472 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10474 [(set (match_operand:DI 0 "register_operand")
10476 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10477 (match_operand:QI 2 "register_operand"))))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10480 [(set (match_dup 0)
10481 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10482 "operands[2] = gen_lowpart (SImode, operands[2]);")
10484 (define_insn "*ashlhi3_1"
10485 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10486 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10487 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10488 (clobber (reg:CC FLAGS_REG))]
10489 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10491 switch (get_attr_type (insn))
10497 gcc_assert (operands[2] == const1_rtx);
10498 return "add{w}\t%0, %0";
10501 if (operands[2] == const1_rtx
10502 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10503 return "sal{w}\t%0";
10505 return "sal{w}\t{%2, %0|%0, %2}";
10508 [(set (attr "type")
10509 (cond [(eq_attr "alternative" "1")
10510 (const_string "lea")
10511 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10512 (match_operand 0 "register_operand"))
10513 (match_operand 2 "const1_operand"))
10514 (const_string "alu")
10516 (const_string "ishift")))
10517 (set (attr "length_immediate")
10519 (ior (eq_attr "type" "alu")
10520 (and (eq_attr "type" "ishift")
10521 (and (match_operand 2 "const1_operand")
10522 (ior (match_test "TARGET_SHIFT1")
10523 (match_test "optimize_function_for_size_p (cfun)")))))
10525 (const_string "*")))
10526 (set_attr "mode" "HI,SI")])
10528 (define_insn "*ashlqi3_1"
10529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10530 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10531 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10535 switch (get_attr_type (insn))
10541 gcc_assert (operands[2] == const1_rtx);
10542 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10543 return "add{l}\t%k0, %k0";
10545 return "add{b}\t%0, %0";
10548 if (operands[2] == const1_rtx
10549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10551 if (get_attr_mode (insn) == MODE_SI)
10552 return "sal{l}\t%k0";
10554 return "sal{b}\t%0";
10558 if (get_attr_mode (insn) == MODE_SI)
10559 return "sal{l}\t{%2, %k0|%k0, %2}";
10561 return "sal{b}\t{%2, %0|%0, %2}";
10565 [(set (attr "type")
10566 (cond [(eq_attr "alternative" "2")
10567 (const_string "lea")
10568 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10569 (match_operand 0 "register_operand"))
10570 (match_operand 2 "const1_operand"))
10571 (const_string "alu")
10573 (const_string "ishift")))
10574 (set (attr "length_immediate")
10576 (ior (eq_attr "type" "alu")
10577 (and (eq_attr "type" "ishift")
10578 (and (match_operand 2 "const1_operand")
10579 (ior (match_test "TARGET_SHIFT1")
10580 (match_test "optimize_function_for_size_p (cfun)")))))
10582 (const_string "*")))
10583 (set_attr "mode" "QI,SI,SI")
10584 ;; Potential partial reg stall on alternative 1.
10585 (set (attr "preferred_for_speed")
10586 (cond [(eq_attr "alternative" "1")
10587 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10588 (symbol_ref "true")))])
10590 (define_insn "*ashl<mode>3_1_slp"
10591 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
10592 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
10593 (match_operand:QI 2 "nonmemory_operand" "cI")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10596 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
10597 && rtx_equal_p (operands[0], operands[1])"
10599 switch (get_attr_type (insn))
10602 gcc_assert (operands[2] == const1_rtx);
10603 return "add{<imodesuffix>}\t%0, %0";
10606 if (operands[2] == const1_rtx
10607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10608 return "sal{<imodesuffix>}\t%0";
10610 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10613 [(set (attr "type")
10614 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10615 (match_operand 2 "const1_operand"))
10616 (const_string "alu")
10618 (const_string "ishift")))
10619 (set (attr "length_immediate")
10621 (ior (eq_attr "type" "alu")
10622 (and (eq_attr "type" "ishift")
10623 (and (match_operand 2 "const1_operand")
10624 (ior (match_test "TARGET_SHIFT1")
10625 (match_test "optimize_function_for_size_p (cfun)")))))
10627 (const_string "*")))
10628 (set_attr "mode" "<MODE>")])
10630 ;; Convert ashift to the lea pattern to avoid flags dependency.
10632 [(set (match_operand:SWI 0 "register_operand")
10633 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10634 (match_operand 2 "const_0_to_3_operand")))
10635 (clobber (reg:CC FLAGS_REG))]
10637 && REGNO (operands[0]) != REGNO (operands[1])"
10638 [(set (match_dup 0)
10639 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10641 if (<MODE>mode != <LEAMODE>mode)
10643 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10644 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10646 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10649 ;; Convert ashift to the lea pattern to avoid flags dependency.
10651 [(set (match_operand:DI 0 "register_operand")
10653 (ashift:SI (match_operand:SI 1 "index_register_operand")
10654 (match_operand 2 "const_0_to_3_operand"))))
10655 (clobber (reg:CC FLAGS_REG))]
10656 "TARGET_64BIT && reload_completed
10657 && REGNO (operands[0]) != REGNO (operands[1])"
10658 [(set (match_dup 0)
10659 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10661 operands[1] = gen_lowpart (SImode, operands[1]);
10662 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10665 ;; This pattern can't accept a variable shift count, since shifts by
10666 ;; zero don't affect the flags. We assume that shifts by constant
10667 ;; zero are optimized away.
10668 (define_insn "*ashl<mode>3_cmp"
10669 [(set (reg FLAGS_REG)
10671 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10672 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10675 (ashift:SWI (match_dup 1) (match_dup 2)))]
10676 "(optimize_function_for_size_p (cfun)
10677 || !TARGET_PARTIAL_FLAG_REG_STALL
10678 || (operands[2] == const1_rtx
10680 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10681 && ix86_match_ccmode (insn, CCGOCmode)
10682 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 return "add{<imodesuffix>}\t%0, %0";
10691 if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10693 return "sal{<imodesuffix>}\t%0";
10695 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10698 [(set (attr "type")
10699 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10700 (match_operand 0 "register_operand"))
10701 (match_operand 2 "const1_operand"))
10702 (const_string "alu")
10704 (const_string "ishift")))
10705 (set (attr "length_immediate")
10707 (ior (eq_attr "type" "alu")
10708 (and (eq_attr "type" "ishift")
10709 (and (match_operand 2 "const1_operand")
10710 (ior (match_test "TARGET_SHIFT1")
10711 (match_test "optimize_function_for_size_p (cfun)")))))
10713 (const_string "*")))
10714 (set_attr "mode" "<MODE>")])
10716 (define_insn "*ashlsi3_cmp_zext"
10717 [(set (reg FLAGS_REG)
10719 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10720 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10722 (set (match_operand:DI 0 "register_operand" "=r")
10723 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10725 && (optimize_function_for_size_p (cfun)
10726 || !TARGET_PARTIAL_FLAG_REG_STALL
10727 || (operands[2] == const1_rtx
10729 || TARGET_DOUBLE_WITH_ADD)))
10730 && ix86_match_ccmode (insn, CCGOCmode)
10731 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10733 switch (get_attr_type (insn))
10736 gcc_assert (operands[2] == const1_rtx);
10737 return "add{l}\t%k0, %k0";
10740 if (operands[2] == const1_rtx
10741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742 return "sal{l}\t%k0";
10744 return "sal{l}\t{%2, %k0|%k0, %2}";
10747 [(set (attr "type")
10748 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10749 (match_operand 2 "const1_operand"))
10750 (const_string "alu")
10752 (const_string "ishift")))
10753 (set (attr "length_immediate")
10755 (ior (eq_attr "type" "alu")
10756 (and (eq_attr "type" "ishift")
10757 (and (match_operand 2 "const1_operand")
10758 (ior (match_test "TARGET_SHIFT1")
10759 (match_test "optimize_function_for_size_p (cfun)")))))
10761 (const_string "*")))
10762 (set_attr "mode" "SI")])
10764 (define_insn "*ashl<mode>3_cconly"
10765 [(set (reg FLAGS_REG)
10767 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10768 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10770 (clobber (match_scratch:SWI 0 "=<r>"))]
10771 "(optimize_function_for_size_p (cfun)
10772 || !TARGET_PARTIAL_FLAG_REG_STALL
10773 || (operands[2] == const1_rtx
10775 || TARGET_DOUBLE_WITH_ADD)))
10776 && ix86_match_ccmode (insn, CCGOCmode)"
10778 switch (get_attr_type (insn))
10781 gcc_assert (operands[2] == const1_rtx);
10782 return "add{<imodesuffix>}\t%0, %0";
10785 if (operands[2] == const1_rtx
10786 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10787 return "sal{<imodesuffix>}\t%0";
10789 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10792 [(set (attr "type")
10793 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10794 (match_operand 0 "register_operand"))
10795 (match_operand 2 "const1_operand"))
10796 (const_string "alu")
10798 (const_string "ishift")))
10799 (set (attr "length_immediate")
10801 (ior (eq_attr "type" "alu")
10802 (and (eq_attr "type" "ishift")
10803 (and (match_operand 2 "const1_operand")
10804 (ior (match_test "TARGET_SHIFT1")
10805 (match_test "optimize_function_for_size_p (cfun)")))))
10807 (const_string "*")))
10808 (set_attr "mode" "<MODE>")])
10810 ;; See comment above `ashl<mode>3' about how this works.
10812 (define_expand "<shift_insn><mode>3"
10813 [(set (match_operand:SDWIM 0 "<shift_operand>")
10814 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10815 (match_operand:QI 2 "nonmemory_operand")))]
10817 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10819 ;; Avoid useless masking of count operand.
10820 (define_insn_and_split "*<shift_insn><mode>3_mask"
10821 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10823 (match_operand:SWI48 1 "nonimmediate_operand")
10826 (match_operand:SI 2 "register_operand" "c,r")
10827 (match_operand:SI 3 "const_int_operand")) 0)))
10828 (clobber (reg:CC FLAGS_REG))]
10829 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10830 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10831 == GET_MODE_BITSIZE (<MODE>mode)-1
10832 && ix86_pre_reload_split ()"
10836 [(set (match_dup 0)
10837 (any_shiftrt:SWI48 (match_dup 1)
10839 (clobber (reg:CC FLAGS_REG))])]
10840 "operands[2] = gen_lowpart (QImode, operands[2]);"
10841 [(set_attr "isa" "*,bmi2")])
10843 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10844 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10846 (match_operand:SWI48 1 "nonimmediate_operand")
10848 (match_operand:QI 2 "register_operand" "c,r")
10849 (match_operand:QI 3 "const_int_operand"))))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10852 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10853 == GET_MODE_BITSIZE (<MODE>mode)-1
10854 && ix86_pre_reload_split ()"
10858 [(set (match_dup 0)
10859 (any_shiftrt:SWI48 (match_dup 1)
10861 (clobber (reg:CC FLAGS_REG))])]
10863 [(set_attr "isa" "*,bmi2")])
10865 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10866 [(set (match_operand:<DWI> 0 "register_operand")
10868 (match_operand:<DWI> 1 "register_operand")
10871 (match_operand:SI 2 "register_operand" "c")
10872 (match_operand:SI 3 "const_int_operand")) 0)))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10875 && ix86_pre_reload_split ()"
10879 [(set (match_dup 4)
10880 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10881 (ashift:DWIH (match_dup 7)
10882 (minus:QI (match_dup 8) (match_dup 2)))))
10883 (clobber (reg:CC FLAGS_REG))])
10885 [(set (match_dup 6)
10886 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10887 (clobber (reg:CC FLAGS_REG))])]
10889 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10891 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10893 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10894 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10896 rtx tem = gen_reg_rtx (SImode);
10897 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10901 operands[2] = gen_lowpart (QImode, operands[2]);
10903 if (!rtx_equal_p (operands[4], operands[5]))
10904 emit_move_insn (operands[4], operands[5]);
10907 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10908 [(set (match_operand:<DWI> 0 "register_operand")
10910 (match_operand:<DWI> 1 "register_operand")
10912 (match_operand:QI 2 "register_operand" "c")
10913 (match_operand:QI 3 "const_int_operand"))))
10914 (clobber (reg:CC FLAGS_REG))]
10915 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10916 && ix86_pre_reload_split ()"
10920 [(set (match_dup 4)
10921 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10922 (ashift:DWIH (match_dup 7)
10923 (minus:QI (match_dup 8) (match_dup 2)))))
10924 (clobber (reg:CC FLAGS_REG))])
10926 [(set (match_dup 6)
10927 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10928 (clobber (reg:CC FLAGS_REG))])]
10930 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10932 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10934 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10935 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10937 rtx tem = gen_reg_rtx (QImode);
10938 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10942 if (!rtx_equal_p (operands[4], operands[5]))
10943 emit_move_insn (operands[4], operands[5]);
10946 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10947 [(set (match_operand:DWI 0 "register_operand" "=&r")
10948 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10949 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10950 (clobber (reg:CC FLAGS_REG))]
10953 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10955 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10956 [(set_attr "type" "multi")])
10958 ;; By default we don't ask for a scratch register, because when DWImode
10959 ;; values are manipulated, registers are already at a premium. But if
10960 ;; we have one handy, we won't turn it away.
10963 [(match_scratch:DWIH 3 "r")
10964 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10966 (match_operand:<DWI> 1 "register_operand")
10967 (match_operand:QI 2 "nonmemory_operand")))
10968 (clobber (reg:CC FLAGS_REG))])
10972 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10974 (define_insn "x86_64_shrd"
10975 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10976 (ior:DI (lshiftrt:DI (match_dup 0)
10977 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10978 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10979 (minus:QI (const_int 64) (match_dup 2)))))
10980 (clobber (reg:CC FLAGS_REG))]
10982 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10983 [(set_attr "type" "ishift")
10984 (set_attr "prefix_0f" "1")
10985 (set_attr "mode" "DI")
10986 (set_attr "athlon_decode" "vector")
10987 (set_attr "amdfam10_decode" "vector")
10988 (set_attr "bdver1_decode" "vector")])
10990 (define_insn "x86_shrd"
10991 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10992 (ior:SI (lshiftrt:SI (match_dup 0)
10993 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10994 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10995 (minus:QI (const_int 32) (match_dup 2)))))
10996 (clobber (reg:CC FLAGS_REG))]
10998 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10999 [(set_attr "type" "ishift")
11000 (set_attr "prefix_0f" "1")
11001 (set_attr "mode" "SI")
11002 (set_attr "pent_pair" "np")
11003 (set_attr "athlon_decode" "vector")
11004 (set_attr "amdfam10_decode" "vector")
11005 (set_attr "bdver1_decode" "vector")])
11007 ;; Base name for insn mnemonic.
11008 (define_mode_attr cvt_mnemonic
11009 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11011 (define_insn "ashr<mode>3_cvt"
11012 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11014 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11015 (match_operand:QI 2 "const_int_operand")))
11016 (clobber (reg:CC FLAGS_REG))]
11017 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11018 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11019 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11022 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11023 [(set_attr "type" "imovx,ishift")
11024 (set_attr "prefix_0f" "0,*")
11025 (set_attr "length_immediate" "0,*")
11026 (set_attr "modrm" "0,1")
11027 (set_attr "mode" "<MODE>")])
11029 (define_insn "*ashrsi3_cvt_zext"
11030 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11032 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11033 (match_operand:QI 2 "const_int_operand"))))
11034 (clobber (reg:CC FLAGS_REG))]
11035 "TARGET_64BIT && INTVAL (operands[2]) == 31
11036 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11037 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11040 sar{l}\t{%2, %k0|%k0, %2}"
11041 [(set_attr "type" "imovx,ishift")
11042 (set_attr "prefix_0f" "0,*")
11043 (set_attr "length_immediate" "0,*")
11044 (set_attr "modrm" "0,1")
11045 (set_attr "mode" "SI")])
11047 (define_expand "@x86_shift<mode>_adj_3"
11048 [(use (match_operand:SWI48 0 "register_operand"))
11049 (use (match_operand:SWI48 1 "register_operand"))
11050 (use (match_operand:QI 2 "register_operand"))]
11053 rtx_code_label *label = gen_label_rtx ();
11056 emit_insn (gen_testqi_ccz_1 (operands[2],
11057 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11059 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11060 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11061 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11062 gen_rtx_LABEL_REF (VOIDmode, label),
11064 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11065 JUMP_LABEL (tmp) = label;
11067 emit_move_insn (operands[0], operands[1]);
11068 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11069 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11070 emit_label (label);
11071 LABEL_NUSES (label) = 1;
11076 (define_insn "*bmi2_<shift_insn><mode>3_1"
11077 [(set (match_operand:SWI48 0 "register_operand" "=r")
11078 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11079 (match_operand:SWI48 2 "register_operand" "r")))]
11081 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11082 [(set_attr "type" "ishiftx")
11083 (set_attr "mode" "<MODE>")])
11085 (define_insn "*<shift_insn><mode>3_1"
11086 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11088 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11089 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11090 (clobber (reg:CC FLAGS_REG))]
11091 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11093 switch (get_attr_type (insn))
11099 if (operands[2] == const1_rtx
11100 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11101 return "<shift>{<imodesuffix>}\t%0";
11103 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11106 [(set_attr "isa" "*,bmi2")
11107 (set_attr "type" "ishift,ishiftx")
11108 (set (attr "length_immediate")
11110 (and (match_operand 2 "const1_operand")
11111 (ior (match_test "TARGET_SHIFT1")
11112 (match_test "optimize_function_for_size_p (cfun)")))
11114 (const_string "*")))
11115 (set_attr "mode" "<MODE>")])
11117 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11119 [(set (match_operand:SWI48 0 "register_operand")
11120 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11121 (match_operand:QI 2 "register_operand")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "TARGET_BMI2 && reload_completed"
11124 [(set (match_dup 0)
11125 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11126 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11128 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11129 [(set (match_operand:DI 0 "register_operand" "=r")
11131 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11132 (match_operand:SI 2 "register_operand" "r"))))]
11133 "TARGET_64BIT && TARGET_BMI2"
11134 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11135 [(set_attr "type" "ishiftx")
11136 (set_attr "mode" "SI")])
11138 (define_insn "*<shift_insn>si3_1_zext"
11139 [(set (match_operand:DI 0 "register_operand" "=r,r")
11141 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11142 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11146 switch (get_attr_type (insn))
11152 if (operands[2] == const1_rtx
11153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11154 return "<shift>{l}\t%k0";
11156 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11159 [(set_attr "isa" "*,bmi2")
11160 (set_attr "type" "ishift,ishiftx")
11161 (set (attr "length_immediate")
11163 (and (match_operand 2 "const1_operand")
11164 (ior (match_test "TARGET_SHIFT1")
11165 (match_test "optimize_function_for_size_p (cfun)")))
11167 (const_string "*")))
11168 (set_attr "mode" "SI")])
11170 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11172 [(set (match_operand:DI 0 "register_operand")
11174 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11175 (match_operand:QI 2 "register_operand"))))
11176 (clobber (reg:CC FLAGS_REG))]
11177 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11178 [(set (match_dup 0)
11179 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11180 "operands[2] = gen_lowpart (SImode, operands[2]);")
11182 (define_insn "*<shift_insn><mode>3_1"
11183 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11185 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11186 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11187 (clobber (reg:CC FLAGS_REG))]
11188 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11190 if (operands[2] == const1_rtx
11191 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11192 return "<shift>{<imodesuffix>}\t%0";
11194 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11196 [(set_attr "type" "ishift")
11197 (set (attr "length_immediate")
11199 (and (match_operand 2 "const1_operand")
11200 (ior (match_test "TARGET_SHIFT1")
11201 (match_test "optimize_function_for_size_p (cfun)")))
11203 (const_string "*")))
11204 (set_attr "mode" "<MODE>")])
11206 (define_insn "*<shift_insn><mode>3_1_slp"
11207 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11208 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11209 (match_operand:QI 2 "nonmemory_operand" "cI")))
11210 (clobber (reg:CC FLAGS_REG))]
11211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11212 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11213 && rtx_equal_p (operands[0], operands[1])"
11215 if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11217 return "<shift>{<imodesuffix>}\t%0";
11219 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11221 [(set_attr "type" "ishift")
11222 (set (attr "length_immediate")
11224 (and (match_operand 2 "const1_operand")
11225 (ior (match_test "TARGET_SHIFT1")
11226 (match_test "optimize_function_for_size_p (cfun)")))
11228 (const_string "*")))
11229 (set_attr "mode" "<MODE>")])
11231 ;; This pattern can't accept a variable shift count, since shifts by
11232 ;; zero don't affect the flags. We assume that shifts by constant
11233 ;; zero are optimized away.
11234 (define_insn "*<shift_insn><mode>3_cmp"
11235 [(set (reg FLAGS_REG)
11238 (match_operand:SWI 1 "nonimmediate_operand" "0")
11239 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11241 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11242 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11243 "(optimize_function_for_size_p (cfun)
11244 || !TARGET_PARTIAL_FLAG_REG_STALL
11245 || (operands[2] == const1_rtx
11247 && ix86_match_ccmode (insn, CCGOCmode)
11248 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11250 if (operands[2] == const1_rtx
11251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11252 return "<shift>{<imodesuffix>}\t%0";
11254 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11256 [(set_attr "type" "ishift")
11257 (set (attr "length_immediate")
11259 (and (match_operand 2 "const1_operand")
11260 (ior (match_test "TARGET_SHIFT1")
11261 (match_test "optimize_function_for_size_p (cfun)")))
11263 (const_string "*")))
11264 (set_attr "mode" "<MODE>")])
11266 (define_insn "*<shift_insn>si3_cmp_zext"
11267 [(set (reg FLAGS_REG)
11269 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11270 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11272 (set (match_operand:DI 0 "register_operand" "=r")
11273 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11275 && (optimize_function_for_size_p (cfun)
11276 || !TARGET_PARTIAL_FLAG_REG_STALL
11277 || (operands[2] == const1_rtx
11279 && ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11282 if (operands[2] == const1_rtx
11283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11284 return "<shift>{l}\t%k0";
11286 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11288 [(set_attr "type" "ishift")
11289 (set (attr "length_immediate")
11291 (and (match_operand 2 "const1_operand")
11292 (ior (match_test "TARGET_SHIFT1")
11293 (match_test "optimize_function_for_size_p (cfun)")))
11295 (const_string "*")))
11296 (set_attr "mode" "SI")])
11298 (define_insn "*<shift_insn><mode>3_cconly"
11299 [(set (reg FLAGS_REG)
11302 (match_operand:SWI 1 "register_operand" "0")
11303 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11305 (clobber (match_scratch:SWI 0 "=<r>"))]
11306 "(optimize_function_for_size_p (cfun)
11307 || !TARGET_PARTIAL_FLAG_REG_STALL
11308 || (operands[2] == const1_rtx
11310 && ix86_match_ccmode (insn, CCGOCmode)"
11312 if (operands[2] == const1_rtx
11313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11314 return "<shift>{<imodesuffix>}\t%0";
11316 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11318 [(set_attr "type" "ishift")
11319 (set (attr "length_immediate")
11321 (and (match_operand 2 "const1_operand")
11322 (ior (match_test "TARGET_SHIFT1")
11323 (match_test "optimize_function_for_size_p (cfun)")))
11325 (const_string "*")))
11326 (set_attr "mode" "<MODE>")])
11328 ;; Rotate instructions
11330 (define_expand "<rotate_insn>ti3"
11331 [(set (match_operand:TI 0 "register_operand")
11332 (any_rotate:TI (match_operand:TI 1 "register_operand")
11333 (match_operand:QI 2 "nonmemory_operand")))]
11336 if (const_1_to_63_operand (operands[2], VOIDmode))
11337 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11338 (operands[0], operands[1], operands[2]));
11345 (define_expand "<rotate_insn>di3"
11346 [(set (match_operand:DI 0 "shiftdi_operand")
11347 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11348 (match_operand:QI 2 "nonmemory_operand")))]
11352 ix86_expand_binary_operator (<CODE>, DImode, operands);
11353 else if (const_1_to_31_operand (operands[2], VOIDmode))
11354 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11355 (operands[0], operands[1], operands[2]));
11362 (define_expand "<rotate_insn><mode>3"
11363 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11364 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11365 (match_operand:QI 2 "nonmemory_operand")))]
11367 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11369 ;; Avoid useless masking of count operand.
11370 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11371 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11373 (match_operand:SWI48 1 "nonimmediate_operand")
11376 (match_operand:SI 2 "register_operand" "c")
11377 (match_operand:SI 3 "const_int_operand")) 0)))
11378 (clobber (reg:CC FLAGS_REG))]
11379 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11380 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11381 == GET_MODE_BITSIZE (<MODE>mode)-1
11382 && ix86_pre_reload_split ()"
11386 [(set (match_dup 0)
11387 (any_rotate:SWI48 (match_dup 1)
11389 (clobber (reg:CC FLAGS_REG))])]
11390 "operands[2] = gen_lowpart (QImode, operands[2]);")
11392 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11393 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11395 (match_operand:SWI48 1 "nonimmediate_operand")
11397 (match_operand:QI 2 "register_operand" "c")
11398 (match_operand:QI 3 "const_int_operand"))))
11399 (clobber (reg:CC FLAGS_REG))]
11400 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11401 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11402 == GET_MODE_BITSIZE (<MODE>mode)-1
11403 && ix86_pre_reload_split ()"
11407 [(set (match_dup 0)
11408 (any_rotate:SWI48 (match_dup 1)
11410 (clobber (reg:CC FLAGS_REG))])])
11412 ;; Implement rotation using two double-precision
11413 ;; shift instructions and a scratch register.
11415 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11416 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11417 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11418 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11419 (clobber (reg:CC FLAGS_REG))
11420 (clobber (match_scratch:DWIH 3 "=&r"))]
11424 [(set (match_dup 3) (match_dup 4))
11426 [(set (match_dup 4)
11427 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11428 (lshiftrt:DWIH (match_dup 5)
11429 (minus:QI (match_dup 6) (match_dup 2)))))
11430 (clobber (reg:CC FLAGS_REG))])
11432 [(set (match_dup 5)
11433 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11434 (lshiftrt:DWIH (match_dup 3)
11435 (minus:QI (match_dup 6) (match_dup 2)))))
11436 (clobber (reg:CC FLAGS_REG))])]
11438 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11440 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11443 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11444 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11445 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11446 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11447 (clobber (reg:CC FLAGS_REG))
11448 (clobber (match_scratch:DWIH 3 "=&r"))]
11452 [(set (match_dup 3) (match_dup 4))
11454 [(set (match_dup 4)
11455 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11456 (ashift:DWIH (match_dup 5)
11457 (minus:QI (match_dup 6) (match_dup 2)))))
11458 (clobber (reg:CC FLAGS_REG))])
11460 [(set (match_dup 5)
11461 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11462 (ashift:DWIH (match_dup 3)
11463 (minus:QI (match_dup 6) (match_dup 2)))))
11464 (clobber (reg:CC FLAGS_REG))])]
11466 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11468 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11471 (define_mode_attr rorx_immediate_operand
11472 [(SI "const_0_to_31_operand")
11473 (DI "const_0_to_63_operand")])
11475 (define_insn "*bmi2_rorx<mode>3_1"
11476 [(set (match_operand:SWI48 0 "register_operand" "=r")
11478 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11479 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11481 "rorx\t{%2, %1, %0|%0, %1, %2}"
11482 [(set_attr "type" "rotatex")
11483 (set_attr "mode" "<MODE>")])
11485 (define_insn "*<rotate_insn><mode>3_1"
11486 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11488 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11489 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11490 (clobber (reg:CC FLAGS_REG))]
11491 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11493 switch (get_attr_type (insn))
11499 if (operands[2] == const1_rtx
11500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11501 return "<rotate>{<imodesuffix>}\t%0";
11503 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11506 [(set_attr "isa" "*,bmi2")
11507 (set_attr "type" "rotate,rotatex")
11508 (set (attr "length_immediate")
11510 (and (eq_attr "type" "rotate")
11511 (and (match_operand 2 "const1_operand")
11512 (ior (match_test "TARGET_SHIFT1")
11513 (match_test "optimize_function_for_size_p (cfun)"))))
11515 (const_string "*")))
11516 (set_attr "mode" "<MODE>")])
11518 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11520 [(set (match_operand:SWI48 0 "register_operand")
11521 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11522 (match_operand:QI 2 "const_int_operand")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "TARGET_BMI2 && reload_completed"
11525 [(set (match_dup 0)
11526 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11528 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11530 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11534 [(set (match_operand:SWI48 0 "register_operand")
11535 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11536 (match_operand:QI 2 "const_int_operand")))
11537 (clobber (reg:CC FLAGS_REG))]
11538 "TARGET_BMI2 && reload_completed"
11539 [(set (match_dup 0)
11540 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11542 (define_insn "*bmi2_rorxsi3_1_zext"
11543 [(set (match_operand:DI 0 "register_operand" "=r")
11545 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11546 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11547 "TARGET_64BIT && TARGET_BMI2"
11548 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11549 [(set_attr "type" "rotatex")
11550 (set_attr "mode" "SI")])
11552 (define_insn "*<rotate_insn>si3_1_zext"
11553 [(set (match_operand:DI 0 "register_operand" "=r,r")
11555 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11556 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11557 (clobber (reg:CC FLAGS_REG))]
11558 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11560 switch (get_attr_type (insn))
11566 if (operands[2] == const1_rtx
11567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11568 return "<rotate>{l}\t%k0";
11570 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11573 [(set_attr "isa" "*,bmi2")
11574 (set_attr "type" "rotate,rotatex")
11575 (set (attr "length_immediate")
11577 (and (eq_attr "type" "rotate")
11578 (and (match_operand 2 "const1_operand")
11579 (ior (match_test "TARGET_SHIFT1")
11580 (match_test "optimize_function_for_size_p (cfun)"))))
11582 (const_string "*")))
11583 (set_attr "mode" "SI")])
11585 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11587 [(set (match_operand:DI 0 "register_operand")
11589 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11590 (match_operand:QI 2 "const_int_operand"))))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11593 [(set (match_dup 0)
11594 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11596 int bitsize = GET_MODE_BITSIZE (SImode);
11598 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11602 [(set (match_operand:DI 0 "register_operand")
11604 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11605 (match_operand:QI 2 "const_int_operand"))))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11608 [(set (match_dup 0)
11609 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11611 (define_insn "*<rotate_insn><mode>3_1"
11612 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11613 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11614 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11615 (clobber (reg:CC FLAGS_REG))]
11616 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11618 if (operands[2] == const1_rtx
11619 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11620 return "<rotate>{<imodesuffix>}\t%0";
11622 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11624 [(set_attr "type" "rotate")
11625 (set (attr "length_immediate")
11627 (and (match_operand 2 "const1_operand")
11628 (ior (match_test "TARGET_SHIFT1")
11629 (match_test "optimize_function_for_size_p (cfun)")))
11631 (const_string "*")))
11632 (set_attr "mode" "<MODE>")])
11634 (define_insn "*<rotate_insn><mode>3_1_slp"
11635 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11636 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11637 (match_operand:QI 2 "nonmemory_operand" "cI")))
11638 (clobber (reg:CC FLAGS_REG))]
11639 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11640 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11641 && rtx_equal_p (operands[0], operands[1])"
11643 if (operands[2] == const1_rtx
11644 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11645 return "<rotate>{<imodesuffix>}\t%0";
11647 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11649 [(set_attr "type" "rotate")
11650 (set (attr "length_immediate")
11652 (and (match_operand 2 "const1_operand")
11653 (ior (match_test "TARGET_SHIFT1")
11654 (match_test "optimize_function_for_size_p (cfun)")))
11656 (const_string "*")))
11657 (set_attr "mode" "<MODE>")])
11660 [(set (match_operand:HI 0 "QIreg_operand")
11661 (any_rotate:HI (match_dup 0) (const_int 8)))
11662 (clobber (reg:CC FLAGS_REG))]
11664 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11665 [(parallel [(set (strict_low_part (match_dup 0))
11666 (bswap:HI (match_dup 0)))
11667 (clobber (reg:CC FLAGS_REG))])])
11669 ;; Bit set / bit test instructions
11671 ;; %%% bts, btr, btc
11673 ;; These instructions are *slow* when applied to memory.
11675 (define_code_attr btsc [(ior "bts") (xor "btc")])
11677 (define_insn "*<btsc><mode>"
11678 [(set (match_operand:SWI48 0 "register_operand" "=r")
11680 (ashift:SWI48 (const_int 1)
11681 (match_operand:QI 2 "register_operand" "r"))
11682 (match_operand:SWI48 1 "register_operand" "0")))
11683 (clobber (reg:CC FLAGS_REG))]
11685 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11686 [(set_attr "type" "alu1")
11687 (set_attr "prefix_0f" "1")
11688 (set_attr "znver1_decode" "double")
11689 (set_attr "mode" "<MODE>")])
11691 ;; Avoid useless masking of count operand.
11692 (define_insn_and_split "*<btsc><mode>_mask"
11693 [(set (match_operand:SWI48 0 "register_operand")
11699 (match_operand:SI 1 "register_operand")
11700 (match_operand:SI 2 "const_int_operand")) 0))
11701 (match_operand:SWI48 3 "register_operand")))
11702 (clobber (reg:CC FLAGS_REG))]
11704 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11705 == GET_MODE_BITSIZE (<MODE>mode)-1
11706 && ix86_pre_reload_split ()"
11710 [(set (match_dup 0)
11712 (ashift:SWI48 (const_int 1)
11715 (clobber (reg:CC FLAGS_REG))])]
11716 "operands[1] = gen_lowpart (QImode, operands[1]);")
11718 (define_insn_and_split "*<btsc><mode>_mask_1"
11719 [(set (match_operand:SWI48 0 "register_operand")
11724 (match_operand:QI 1 "register_operand")
11725 (match_operand:QI 2 "const_int_operand")))
11726 (match_operand:SWI48 3 "register_operand")))
11727 (clobber (reg:CC FLAGS_REG))]
11729 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11730 == GET_MODE_BITSIZE (<MODE>mode)-1
11731 && ix86_pre_reload_split ()"
11735 [(set (match_dup 0)
11737 (ashift:SWI48 (const_int 1)
11740 (clobber (reg:CC FLAGS_REG))])])
11742 (define_insn "*btr<mode>"
11743 [(set (match_operand:SWI48 0 "register_operand" "=r")
11745 (rotate:SWI48 (const_int -2)
11746 (match_operand:QI 2 "register_operand" "r"))
11747 (match_operand:SWI48 1 "register_operand" "0")))
11748 (clobber (reg:CC FLAGS_REG))]
11750 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11751 [(set_attr "type" "alu1")
11752 (set_attr "prefix_0f" "1")
11753 (set_attr "znver1_decode" "double")
11754 (set_attr "mode" "<MODE>")])
11756 ;; Avoid useless masking of count operand.
11757 (define_insn_and_split "*btr<mode>_mask"
11758 [(set (match_operand:SWI48 0 "register_operand")
11764 (match_operand:SI 1 "register_operand")
11765 (match_operand:SI 2 "const_int_operand")) 0))
11766 (match_operand:SWI48 3 "register_operand")))
11767 (clobber (reg:CC FLAGS_REG))]
11769 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11770 == GET_MODE_BITSIZE (<MODE>mode)-1
11771 && ix86_pre_reload_split ()"
11775 [(set (match_dup 0)
11777 (rotate:SWI48 (const_int -2)
11780 (clobber (reg:CC FLAGS_REG))])]
11781 "operands[1] = gen_lowpart (QImode, operands[1]);")
11783 (define_insn_and_split "*btr<mode>_mask_1"
11784 [(set (match_operand:SWI48 0 "register_operand")
11789 (match_operand:QI 1 "register_operand")
11790 (match_operand:QI 2 "const_int_operand")))
11791 (match_operand:SWI48 3 "register_operand")))
11792 (clobber (reg:CC FLAGS_REG))]
11794 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11795 == GET_MODE_BITSIZE (<MODE>mode)-1
11796 && ix86_pre_reload_split ()"
11800 [(set (match_dup 0)
11802 (rotate:SWI48 (const_int -2)
11805 (clobber (reg:CC FLAGS_REG))])])
11807 ;; These instructions are never faster than the corresponding
11808 ;; and/ior/xor operations when using immediate operand, so with
11809 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11810 ;; relevant immediates within the instruction itself, so operating
11811 ;; on bits in the high 32-bits of a register becomes easier.
11813 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11814 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11815 ;; negdf respectively, so they can never be disabled entirely.
11817 (define_insn "*btsq_imm"
11818 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11820 (match_operand 1 "const_0_to_63_operand" "J"))
11822 (clobber (reg:CC FLAGS_REG))]
11823 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11824 "bts{q}\t{%1, %0|%0, %1}"
11825 [(set_attr "type" "alu1")
11826 (set_attr "prefix_0f" "1")
11827 (set_attr "znver1_decode" "double")
11828 (set_attr "mode" "DI")])
11830 (define_insn "*btrq_imm"
11831 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11833 (match_operand 1 "const_0_to_63_operand" "J"))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11837 "btr{q}\t{%1, %0|%0, %1}"
11838 [(set_attr "type" "alu1")
11839 (set_attr "prefix_0f" "1")
11840 (set_attr "znver1_decode" "double")
11841 (set_attr "mode" "DI")])
11843 (define_insn "*btcq_imm"
11844 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11846 (match_operand 1 "const_0_to_63_operand" "J"))
11847 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11850 "btc{q}\t{%1, %0|%0, %1}"
11851 [(set_attr "type" "alu1")
11852 (set_attr "prefix_0f" "1")
11853 (set_attr "znver1_decode" "double")
11854 (set_attr "mode" "DI")])
11856 ;; Allow Nocona to avoid these instructions if a register is available.
11859 [(match_scratch:DI 2 "r")
11860 (parallel [(set (zero_extract:DI
11861 (match_operand:DI 0 "nonimmediate_operand")
11863 (match_operand 1 "const_0_to_63_operand"))
11865 (clobber (reg:CC FLAGS_REG))])]
11866 "TARGET_64BIT && !TARGET_USE_BT"
11867 [(parallel [(set (match_dup 0)
11868 (ior:DI (match_dup 0) (match_dup 3)))
11869 (clobber (reg:CC FLAGS_REG))])]
11871 int i = INTVAL (operands[1]);
11873 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11875 if (!x86_64_immediate_operand (operands[3], DImode))
11877 emit_move_insn (operands[2], operands[3]);
11878 operands[3] = operands[2];
11883 [(match_scratch:DI 2 "r")
11884 (parallel [(set (zero_extract:DI
11885 (match_operand:DI 0 "nonimmediate_operand")
11887 (match_operand 1 "const_0_to_63_operand"))
11889 (clobber (reg:CC FLAGS_REG))])]
11890 "TARGET_64BIT && !TARGET_USE_BT"
11891 [(parallel [(set (match_dup 0)
11892 (and:DI (match_dup 0) (match_dup 3)))
11893 (clobber (reg:CC FLAGS_REG))])]
11895 int i = INTVAL (operands[1]);
11897 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11899 if (!x86_64_immediate_operand (operands[3], DImode))
11901 emit_move_insn (operands[2], operands[3]);
11902 operands[3] = operands[2];
11907 [(match_scratch:DI 2 "r")
11908 (parallel [(set (zero_extract:DI
11909 (match_operand:DI 0 "nonimmediate_operand")
11911 (match_operand 1 "const_0_to_63_operand"))
11912 (not:DI (zero_extract:DI
11913 (match_dup 0) (const_int 1) (match_dup 1))))
11914 (clobber (reg:CC FLAGS_REG))])]
11915 "TARGET_64BIT && !TARGET_USE_BT"
11916 [(parallel [(set (match_dup 0)
11917 (xor:DI (match_dup 0) (match_dup 3)))
11918 (clobber (reg:CC FLAGS_REG))])]
11920 int i = INTVAL (operands[1]);
11922 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11924 if (!x86_64_immediate_operand (operands[3], DImode))
11926 emit_move_insn (operands[2], operands[3]);
11927 operands[3] = operands[2];
11933 (define_insn "*bt<mode>"
11934 [(set (reg:CCC FLAGS_REG)
11936 (zero_extract:SWI48
11937 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11939 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11943 switch (get_attr_mode (insn))
11946 return "bt{l}\t{%1, %k0|%k0, %1}";
11949 return "bt{q}\t{%q1, %0|%0, %q1}";
11952 gcc_unreachable ();
11955 [(set_attr "type" "alu1")
11956 (set_attr "prefix_0f" "1")
11959 (and (match_test "CONST_INT_P (operands[1])")
11960 (match_test "INTVAL (operands[1]) < 32"))
11961 (const_string "SI")
11962 (const_string "<MODE>")))])
11964 (define_insn_and_split "*jcc_bt<mode>"
11966 (if_then_else (match_operator 0 "bt_comparison_operator"
11967 [(zero_extract:SWI48
11968 (match_operand:SWI48 1 "nonimmediate_operand")
11970 (match_operand:SI 2 "nonmemory_operand"))
11972 (label_ref (match_operand 3))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11976 && (CONST_INT_P (operands[2])
11977 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11978 && INTVAL (operands[2])
11979 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11980 : !memory_operand (operands[1], <MODE>mode))
11981 && ix86_pre_reload_split ()"
11984 [(set (reg:CCC FLAGS_REG)
11986 (zero_extract:SWI48
11992 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11993 (label_ref (match_dup 3))
11996 operands[0] = shallow_copy_rtx (operands[0]);
11997 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12000 (define_insn_and_split "*jcc_bt<mode>_1"
12002 (if_then_else (match_operator 0 "bt_comparison_operator"
12003 [(zero_extract:SWI48
12004 (match_operand:SWI48 1 "register_operand")
12007 (match_operand:QI 2 "register_operand")))
12009 (label_ref (match_operand 3))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12013 && ix86_pre_reload_split ()"
12016 [(set (reg:CCC FLAGS_REG)
12018 (zero_extract:SWI48
12024 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12025 (label_ref (match_dup 3))
12028 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12029 operands[0] = shallow_copy_rtx (operands[0]);
12030 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12033 ;; Avoid useless masking of bit offset operand.
12034 (define_insn_and_split "*jcc_bt<mode>_mask"
12036 (if_then_else (match_operator 0 "bt_comparison_operator"
12037 [(zero_extract:SWI48
12038 (match_operand:SWI48 1 "register_operand")
12041 (match_operand:SI 2 "register_operand")
12042 (match_operand 3 "const_int_operand")))])
12043 (label_ref (match_operand 4))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12047 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12048 == GET_MODE_BITSIZE (<MODE>mode)-1
12049 && ix86_pre_reload_split ()"
12052 [(set (reg:CCC FLAGS_REG)
12054 (zero_extract:SWI48
12060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12061 (label_ref (match_dup 4))
12064 operands[0] = shallow_copy_rtx (operands[0]);
12065 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12068 ;; Store-flag instructions.
12070 ;; For all sCOND expanders, also expand the compare or test insn that
12071 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12073 (define_insn_and_split "*setcc_di_1"
12074 [(set (match_operand:DI 0 "register_operand" "=q")
12075 (match_operator:DI 1 "ix86_comparison_operator"
12076 [(reg FLAGS_REG) (const_int 0)]))]
12077 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12079 "&& reload_completed"
12080 [(set (match_dup 2) (match_dup 1))
12081 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12083 operands[1] = shallow_copy_rtx (operands[1]);
12084 PUT_MODE (operands[1], QImode);
12085 operands[2] = gen_lowpart (QImode, operands[0]);
12088 (define_insn_and_split "*setcc_si_1_and"
12089 [(set (match_operand:SI 0 "register_operand" "=q")
12090 (match_operator:SI 1 "ix86_comparison_operator"
12091 [(reg FLAGS_REG) (const_int 0)]))
12092 (clobber (reg:CC FLAGS_REG))]
12093 "!TARGET_PARTIAL_REG_STALL
12094 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12096 "&& reload_completed"
12097 [(set (match_dup 2) (match_dup 1))
12098 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12099 (clobber (reg:CC FLAGS_REG))])]
12101 operands[1] = shallow_copy_rtx (operands[1]);
12102 PUT_MODE (operands[1], QImode);
12103 operands[2] = gen_lowpart (QImode, operands[0]);
12106 (define_insn_and_split "*setcc_si_1_movzbl"
12107 [(set (match_operand:SI 0 "register_operand" "=q")
12108 (match_operator:SI 1 "ix86_comparison_operator"
12109 [(reg FLAGS_REG) (const_int 0)]))]
12110 "!TARGET_PARTIAL_REG_STALL
12111 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12113 "&& reload_completed"
12114 [(set (match_dup 2) (match_dup 1))
12115 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12117 operands[1] = shallow_copy_rtx (operands[1]);
12118 PUT_MODE (operands[1], QImode);
12119 operands[2] = gen_lowpart (QImode, operands[0]);
12122 (define_insn "*setcc_qi"
12123 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12124 (match_operator:QI 1 "ix86_comparison_operator"
12125 [(reg FLAGS_REG) (const_int 0)]))]
12128 [(set_attr "type" "setcc")
12129 (set_attr "mode" "QI")])
12131 (define_insn "*setcc_qi_slp"
12132 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12133 (match_operator:QI 1 "ix86_comparison_operator"
12134 [(reg FLAGS_REG) (const_int 0)]))]
12137 [(set_attr "type" "setcc")
12138 (set_attr "mode" "QI")])
12140 ;; In general it is not safe to assume too much about CCmode registers,
12141 ;; so simplify-rtx stops when it sees a second one. Under certain
12142 ;; conditions this is safe on x86, so help combine not create
12149 [(set (match_operand:QI 0 "nonimmediate_operand")
12150 (ne:QI (match_operator 1 "ix86_comparison_operator"
12151 [(reg FLAGS_REG) (const_int 0)])
12154 [(set (match_dup 0) (match_dup 1))]
12156 operands[1] = shallow_copy_rtx (operands[1]);
12157 PUT_MODE (operands[1], QImode);
12161 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12162 (ne:QI (match_operator 1 "ix86_comparison_operator"
12163 [(reg FLAGS_REG) (const_int 0)])
12166 [(set (match_dup 0) (match_dup 1))]
12168 operands[1] = shallow_copy_rtx (operands[1]);
12169 PUT_MODE (operands[1], QImode);
12173 [(set (match_operand:QI 0 "nonimmediate_operand")
12174 (eq:QI (match_operator 1 "ix86_comparison_operator"
12175 [(reg FLAGS_REG) (const_int 0)])
12178 [(set (match_dup 0) (match_dup 1))]
12180 operands[1] = shallow_copy_rtx (operands[1]);
12181 PUT_MODE (operands[1], QImode);
12182 PUT_CODE (operands[1],
12183 ix86_reverse_condition (GET_CODE (operands[1]),
12184 GET_MODE (XEXP (operands[1], 0))));
12186 /* Make sure that (a) the CCmode we have for the flags is strong
12187 enough for the reversed compare or (b) we have a valid FP compare. */
12188 if (! ix86_comparison_operator (operands[1], VOIDmode))
12193 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12194 (eq:QI (match_operator 1 "ix86_comparison_operator"
12195 [(reg FLAGS_REG) (const_int 0)])
12198 [(set (match_dup 0) (match_dup 1))]
12200 operands[1] = shallow_copy_rtx (operands[1]);
12201 PUT_MODE (operands[1], QImode);
12202 PUT_CODE (operands[1],
12203 ix86_reverse_condition (GET_CODE (operands[1]),
12204 GET_MODE (XEXP (operands[1], 0))));
12206 /* Make sure that (a) the CCmode we have for the flags is strong
12207 enough for the reversed compare or (b) we have a valid FP compare. */
12208 if (! ix86_comparison_operator (operands[1], VOIDmode))
12212 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12213 ;; subsequent logical operations are used to imitate conditional moves.
12214 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12217 (define_insn "setcc_<mode>_sse"
12218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12219 (match_operator:MODEF 3 "sse_comparison_operator"
12220 [(match_operand:MODEF 1 "register_operand" "0,x")
12221 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12222 "SSE_FLOAT_MODE_P (<MODE>mode)"
12224 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12225 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12226 [(set_attr "isa" "noavx,avx")
12227 (set_attr "type" "ssecmp")
12228 (set_attr "length_immediate" "1")
12229 (set_attr "prefix" "orig,vex")
12230 (set_attr "mode" "<MODE>")])
12232 ;; Basic conditional jump instructions.
12233 ;; We ignore the overflow flag for signed branch instructions.
12235 (define_insn "*jcc"
12237 (if_then_else (match_operator 1 "ix86_comparison_operator"
12238 [(reg FLAGS_REG) (const_int 0)])
12239 (label_ref (match_operand 0))
12243 [(set_attr "type" "ibr")
12244 (set_attr "modrm" "0")
12245 (set (attr "length")
12247 (and (ge (minus (match_dup 0) (pc))
12249 (lt (minus (match_dup 0) (pc))
12254 ;; In general it is not safe to assume too much about CCmode registers,
12255 ;; so simplify-rtx stops when it sees a second one. Under certain
12256 ;; conditions this is safe on x86, so help combine not create
12264 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12265 [(reg FLAGS_REG) (const_int 0)])
12267 (label_ref (match_operand 1))
12271 (if_then_else (match_dup 0)
12272 (label_ref (match_dup 1))
12275 operands[0] = shallow_copy_rtx (operands[0]);
12276 PUT_MODE (operands[0], VOIDmode);
12281 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12282 [(reg FLAGS_REG) (const_int 0)])
12284 (label_ref (match_operand 1))
12288 (if_then_else (match_dup 0)
12289 (label_ref (match_dup 1))
12292 operands[0] = shallow_copy_rtx (operands[0]);
12293 PUT_MODE (operands[0], VOIDmode);
12294 PUT_CODE (operands[0],
12295 ix86_reverse_condition (GET_CODE (operands[0]),
12296 GET_MODE (XEXP (operands[0], 0))));
12298 /* Make sure that (a) the CCmode we have for the flags is strong
12299 enough for the reversed compare or (b) we have a valid FP compare. */
12300 if (! ix86_comparison_operator (operands[0], VOIDmode))
12304 ;; Unconditional and other jump instructions
12306 (define_insn "jump"
12308 (label_ref (match_operand 0)))]
12311 [(set_attr "type" "ibr")
12312 (set_attr "modrm" "0")
12313 (set (attr "length")
12315 (and (ge (minus (match_dup 0) (pc))
12317 (lt (minus (match_dup 0) (pc))
12322 (define_expand "indirect_jump"
12323 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12326 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12327 operands[0] = convert_memory_address (word_mode, operands[0]);
12328 cfun->machine->has_local_indirect_jump = true;
12331 (define_insn "*indirect_jump"
12332 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12334 "* return ix86_output_indirect_jmp (operands[0]);"
12335 [(set (attr "type")
12336 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12337 != indirect_branch_keep)")
12338 (const_string "multi")
12339 (const_string "ibr")))
12340 (set_attr "length_immediate" "0")])
12342 (define_expand "tablejump"
12343 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12344 (use (label_ref (match_operand 1)))])]
12347 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12348 relative. Convert the relative address to an absolute address. */
12352 enum rtx_code code;
12354 /* We can't use @GOTOFF for text labels on VxWorks;
12355 see gotoff_operand. */
12356 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12360 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12362 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12366 op1 = pic_offset_table_rtx;
12371 op0 = pic_offset_table_rtx;
12375 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12379 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12380 operands[0] = convert_memory_address (word_mode, operands[0]);
12381 cfun->machine->has_local_indirect_jump = true;
12384 (define_insn "*tablejump_1"
12385 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12386 (use (label_ref (match_operand 1)))]
12388 "* return ix86_output_indirect_jmp (operands[0]);"
12389 [(set (attr "type")
12390 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12391 != indirect_branch_keep)")
12392 (const_string "multi")
12393 (const_string "ibr")))
12394 (set_attr "length_immediate" "0")])
12396 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12399 [(set (reg FLAGS_REG) (match_operand 0))
12400 (set (match_operand:QI 1 "register_operand")
12401 (match_operator:QI 2 "ix86_comparison_operator"
12402 [(reg FLAGS_REG) (const_int 0)]))
12403 (set (match_operand 3 "any_QIreg_operand")
12404 (zero_extend (match_dup 1)))]
12405 "(peep2_reg_dead_p (3, operands[1])
12406 || operands_match_p (operands[1], operands[3]))
12407 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12408 && peep2_regno_dead_p (0, FLAGS_REG)"
12409 [(set (match_dup 4) (match_dup 0))
12410 (set (strict_low_part (match_dup 5))
12413 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12414 operands[5] = gen_lowpart (QImode, operands[3]);
12415 ix86_expand_clear (operands[3]);
12419 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12420 (match_operand 4)])
12421 (set (match_operand:QI 1 "register_operand")
12422 (match_operator:QI 2 "ix86_comparison_operator"
12423 [(reg FLAGS_REG) (const_int 0)]))
12424 (set (match_operand 3 "any_QIreg_operand")
12425 (zero_extend (match_dup 1)))]
12426 "(peep2_reg_dead_p (3, operands[1])
12427 || operands_match_p (operands[1], operands[3]))
12428 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12429 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12430 && ! reg_set_p (operands[3], operands[4])
12431 && peep2_regno_dead_p (0, FLAGS_REG)"
12432 [(parallel [(set (match_dup 5) (match_dup 0))
12434 (set (strict_low_part (match_dup 6))
12437 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12438 operands[6] = gen_lowpart (QImode, operands[3]);
12439 ix86_expand_clear (operands[3]);
12443 [(set (reg FLAGS_REG) (match_operand 0))
12444 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12445 (match_operand 5)])
12446 (set (match_operand:QI 2 "register_operand")
12447 (match_operator:QI 3 "ix86_comparison_operator"
12448 [(reg FLAGS_REG) (const_int 0)]))
12449 (set (match_operand 4 "any_QIreg_operand")
12450 (zero_extend (match_dup 2)))]
12451 "(peep2_reg_dead_p (4, operands[2])
12452 || operands_match_p (operands[2], operands[4]))
12453 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12454 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12455 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12456 && ! reg_set_p (operands[4], operands[5])
12457 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12458 && peep2_regno_dead_p (0, FLAGS_REG)"
12459 [(set (match_dup 6) (match_dup 0))
12460 (parallel [(set (match_dup 7) (match_dup 1))
12462 (set (strict_low_part (match_dup 8))
12465 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12466 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12467 operands[8] = gen_lowpart (QImode, operands[4]);
12468 ix86_expand_clear (operands[4]);
12471 ;; Similar, but match zero extend with andsi3.
12474 [(set (reg FLAGS_REG) (match_operand 0))
12475 (set (match_operand:QI 1 "register_operand")
12476 (match_operator:QI 2 "ix86_comparison_operator"
12477 [(reg FLAGS_REG) (const_int 0)]))
12478 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12479 (and:SI (match_dup 3) (const_int 255)))
12480 (clobber (reg:CC FLAGS_REG))])]
12481 "REGNO (operands[1]) == REGNO (operands[3])
12482 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12483 && peep2_regno_dead_p (0, FLAGS_REG)"
12484 [(set (match_dup 4) (match_dup 0))
12485 (set (strict_low_part (match_dup 5))
12488 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12489 operands[5] = gen_lowpart (QImode, operands[3]);
12490 ix86_expand_clear (operands[3]);
12494 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12495 (match_operand 4)])
12496 (set (match_operand:QI 1 "register_operand")
12497 (match_operator:QI 2 "ix86_comparison_operator"
12498 [(reg FLAGS_REG) (const_int 0)]))
12499 (parallel [(set (match_operand 3 "any_QIreg_operand")
12500 (zero_extend (match_dup 1)))
12501 (clobber (reg:CC FLAGS_REG))])]
12502 "(peep2_reg_dead_p (3, operands[1])
12503 || operands_match_p (operands[1], operands[3]))
12504 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12505 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12506 && ! reg_set_p (operands[3], operands[4])
12507 && peep2_regno_dead_p (0, FLAGS_REG)"
12508 [(parallel [(set (match_dup 5) (match_dup 0))
12510 (set (strict_low_part (match_dup 6))
12513 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12514 operands[6] = gen_lowpart (QImode, operands[3]);
12515 ix86_expand_clear (operands[3]);
12519 [(set (reg FLAGS_REG) (match_operand 0))
12520 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12521 (match_operand 5)])
12522 (set (match_operand:QI 2 "register_operand")
12523 (match_operator:QI 3 "ix86_comparison_operator"
12524 [(reg FLAGS_REG) (const_int 0)]))
12525 (parallel [(set (match_operand 4 "any_QIreg_operand")
12526 (zero_extend (match_dup 2)))
12527 (clobber (reg:CC FLAGS_REG))])]
12528 "(peep2_reg_dead_p (4, operands[2])
12529 || operands_match_p (operands[2], operands[4]))
12530 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12531 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12532 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12533 && ! reg_set_p (operands[4], operands[5])
12534 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12535 && peep2_regno_dead_p (0, FLAGS_REG)"
12536 [(set (match_dup 6) (match_dup 0))
12537 (parallel [(set (match_dup 7) (match_dup 1))
12539 (set (strict_low_part (match_dup 8))
12542 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12543 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12544 operands[8] = gen_lowpart (QImode, operands[4]);
12545 ix86_expand_clear (operands[4]);
12548 ;; Call instructions.
12550 ;; The predicates normally associated with named expanders are not properly
12551 ;; checked for calls. This is a bug in the generic code, but it isn't that
12552 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12554 ;; P6 processors will jump to the address after the decrement when %esp
12555 ;; is used as a call operand, so they will execute return address as a code.
12556 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12558 ;; Register constraint for call instruction.
12559 (define_mode_attr c [(SI "l") (DI "r")])
12561 ;; Call subroutine returning no value.
12563 (define_expand "call"
12564 [(call (match_operand:QI 0)
12566 (use (match_operand 2))]
12569 ix86_expand_call (NULL, operands[0], operands[1],
12570 operands[2], NULL, false);
12574 (define_expand "sibcall"
12575 [(call (match_operand:QI 0)
12577 (use (match_operand 2))]
12580 ix86_expand_call (NULL, operands[0], operands[1],
12581 operands[2], NULL, true);
12585 (define_insn "*call"
12586 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12587 (match_operand 1))]
12588 "!SIBLING_CALL_P (insn)"
12589 "* return ix86_output_call_insn (insn, operands[0]);"
12590 [(set_attr "type" "call")])
12592 ;; This covers both call and sibcall since only GOT slot is allowed.
12593 (define_insn "*call_got_x32"
12594 [(call (mem:QI (zero_extend:DI
12595 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12596 (match_operand 1))]
12599 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12600 return ix86_output_call_insn (insn, fnaddr);
12602 [(set_attr "type" "call")])
12604 ;; Since sibcall never returns, we can only use call-clobbered register
12606 (define_insn "*sibcall_GOT_32"
12609 (match_operand:SI 0 "register_no_elim_operand" "U")
12610 (match_operand:SI 1 "GOT32_symbol_operand"))))
12611 (match_operand 2))]
12614 && !TARGET_INDIRECT_BRANCH_REGISTER
12615 && SIBLING_CALL_P (insn)"
12617 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12618 fnaddr = gen_const_mem (SImode, fnaddr);
12619 return ix86_output_call_insn (insn, fnaddr);
12621 [(set_attr "type" "call")])
12623 (define_insn "*sibcall"
12624 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12625 (match_operand 1))]
12626 "SIBLING_CALL_P (insn)"
12627 "* return ix86_output_call_insn (insn, operands[0]);"
12628 [(set_attr "type" "call")])
12630 (define_insn "*sibcall_memory"
12631 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12634 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12635 "* return ix86_output_call_insn (insn, operands[0]);"
12636 [(set_attr "type" "call")])
12639 [(set (match_operand:W 0 "register_operand")
12640 (match_operand:W 1 "memory_operand"))
12641 (call (mem:QI (match_dup 0))
12642 (match_operand 3))]
12644 && !TARGET_INDIRECT_BRANCH_REGISTER
12645 && SIBLING_CALL_P (peep2_next_insn (1))
12646 && !reg_mentioned_p (operands[0],
12647 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12648 [(parallel [(call (mem:QI (match_dup 1))
12650 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12653 [(set (match_operand:W 0 "register_operand")
12654 (match_operand:W 1 "memory_operand"))
12655 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12656 (call (mem:QI (match_dup 0))
12657 (match_operand 3))]
12659 && !TARGET_INDIRECT_BRANCH_REGISTER
12660 && SIBLING_CALL_P (peep2_next_insn (2))
12661 && !reg_mentioned_p (operands[0],
12662 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12664 (parallel [(call (mem:QI (match_dup 1))
12666 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12668 (define_expand "call_pop"
12669 [(parallel [(call (match_operand:QI 0)
12670 (match_operand:SI 1))
12671 (set (reg:SI SP_REG)
12672 (plus:SI (reg:SI SP_REG)
12673 (match_operand:SI 3)))])]
12676 ix86_expand_call (NULL, operands[0], operands[1],
12677 operands[2], operands[3], false);
12681 (define_insn "*call_pop"
12682 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12684 (set (reg:SI SP_REG)
12685 (plus:SI (reg:SI SP_REG)
12686 (match_operand:SI 2 "immediate_operand" "i")))]
12687 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12688 "* return ix86_output_call_insn (insn, operands[0]);"
12689 [(set_attr "type" "call")])
12691 (define_insn "*sibcall_pop"
12692 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12694 (set (reg:SI SP_REG)
12695 (plus:SI (reg:SI SP_REG)
12696 (match_operand:SI 2 "immediate_operand" "i")))]
12697 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12698 "* return ix86_output_call_insn (insn, operands[0]);"
12699 [(set_attr "type" "call")])
12701 (define_insn "*sibcall_pop_memory"
12702 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12704 (set (reg:SI SP_REG)
12705 (plus:SI (reg:SI SP_REG)
12706 (match_operand:SI 2 "immediate_operand" "i")))
12707 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12709 "* return ix86_output_call_insn (insn, operands[0]);"
12710 [(set_attr "type" "call")])
12713 [(set (match_operand:SI 0 "register_operand")
12714 (match_operand:SI 1 "memory_operand"))
12715 (parallel [(call (mem:QI (match_dup 0))
12717 (set (reg:SI SP_REG)
12718 (plus:SI (reg:SI SP_REG)
12719 (match_operand:SI 4 "immediate_operand")))])]
12720 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12721 && !reg_mentioned_p (operands[0],
12722 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12723 [(parallel [(call (mem:QI (match_dup 1))
12725 (set (reg:SI SP_REG)
12726 (plus:SI (reg:SI SP_REG)
12728 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12731 [(set (match_operand:SI 0 "register_operand")
12732 (match_operand:SI 1 "memory_operand"))
12733 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12734 (parallel [(call (mem:QI (match_dup 0))
12736 (set (reg:SI SP_REG)
12737 (plus:SI (reg:SI SP_REG)
12738 (match_operand:SI 4 "immediate_operand")))])]
12739 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12740 && !reg_mentioned_p (operands[0],
12741 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12742 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12743 (parallel [(call (mem:QI (match_dup 1))
12745 (set (reg:SI SP_REG)
12746 (plus:SI (reg:SI SP_REG)
12748 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12750 ;; Combining simple memory jump instruction
12753 [(set (match_operand:W 0 "register_operand")
12754 (match_operand:W 1 "memory_operand"))
12755 (set (pc) (match_dup 0))]
12757 && !TARGET_INDIRECT_BRANCH_REGISTER
12758 && peep2_reg_dead_p (2, operands[0])"
12759 [(set (pc) (match_dup 1))])
12761 ;; Call subroutine, returning value in operand 0
12763 (define_expand "call_value"
12764 [(set (match_operand 0)
12765 (call (match_operand:QI 1)
12766 (match_operand 2)))
12767 (use (match_operand 3))]
12770 ix86_expand_call (operands[0], operands[1], operands[2],
12771 operands[3], NULL, false);
12775 (define_expand "sibcall_value"
12776 [(set (match_operand 0)
12777 (call (match_operand:QI 1)
12778 (match_operand 2)))
12779 (use (match_operand 3))]
12782 ix86_expand_call (operands[0], operands[1], operands[2],
12783 operands[3], NULL, true);
12787 (define_insn "*call_value"
12788 [(set (match_operand 0)
12789 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12790 (match_operand 2)))]
12791 "!SIBLING_CALL_P (insn)"
12792 "* return ix86_output_call_insn (insn, operands[1]);"
12793 [(set_attr "type" "callv")])
12795 ;; This covers both call and sibcall since only GOT slot is allowed.
12796 (define_insn "*call_value_got_x32"
12797 [(set (match_operand 0)
12800 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12801 (match_operand 2)))]
12804 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12805 return ix86_output_call_insn (insn, fnaddr);
12807 [(set_attr "type" "callv")])
12809 ;; Since sibcall never returns, we can only use call-clobbered register
12811 (define_insn "*sibcall_value_GOT_32"
12812 [(set (match_operand 0)
12815 (match_operand:SI 1 "register_no_elim_operand" "U")
12816 (match_operand:SI 2 "GOT32_symbol_operand"))))
12817 (match_operand 3)))]
12820 && !TARGET_INDIRECT_BRANCH_REGISTER
12821 && SIBLING_CALL_P (insn)"
12823 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12824 fnaddr = gen_const_mem (SImode, fnaddr);
12825 return ix86_output_call_insn (insn, fnaddr);
12827 [(set_attr "type" "callv")])
12829 (define_insn "*sibcall_value"
12830 [(set (match_operand 0)
12831 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12832 (match_operand 2)))]
12833 "SIBLING_CALL_P (insn)"
12834 "* return ix86_output_call_insn (insn, operands[1]);"
12835 [(set_attr "type" "callv")])
12837 (define_insn "*sibcall_value_memory"
12838 [(set (match_operand 0)
12839 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12840 (match_operand 2)))
12841 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12842 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12843 "* return ix86_output_call_insn (insn, operands[1]);"
12844 [(set_attr "type" "callv")])
12847 [(set (match_operand:W 0 "register_operand")
12848 (match_operand:W 1 "memory_operand"))
12849 (set (match_operand 2)
12850 (call (mem:QI (match_dup 0))
12851 (match_operand 3)))]
12853 && !TARGET_INDIRECT_BRANCH_REGISTER
12854 && SIBLING_CALL_P (peep2_next_insn (1))
12855 && !reg_mentioned_p (operands[0],
12856 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12857 [(parallel [(set (match_dup 2)
12858 (call (mem:QI (match_dup 1))
12860 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12863 [(set (match_operand:W 0 "register_operand")
12864 (match_operand:W 1 "memory_operand"))
12865 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12866 (set (match_operand 2)
12867 (call (mem:QI (match_dup 0))
12868 (match_operand 3)))]
12870 && !TARGET_INDIRECT_BRANCH_REGISTER
12871 && SIBLING_CALL_P (peep2_next_insn (2))
12872 && !reg_mentioned_p (operands[0],
12873 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12874 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12875 (parallel [(set (match_dup 2)
12876 (call (mem:QI (match_dup 1))
12878 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12880 (define_expand "call_value_pop"
12881 [(parallel [(set (match_operand 0)
12882 (call (match_operand:QI 1)
12883 (match_operand:SI 2)))
12884 (set (reg:SI SP_REG)
12885 (plus:SI (reg:SI SP_REG)
12886 (match_operand:SI 4)))])]
12889 ix86_expand_call (operands[0], operands[1], operands[2],
12890 operands[3], operands[4], false);
12894 (define_insn "*call_value_pop"
12895 [(set (match_operand 0)
12896 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12897 (match_operand 2)))
12898 (set (reg:SI SP_REG)
12899 (plus:SI (reg:SI SP_REG)
12900 (match_operand:SI 3 "immediate_operand" "i")))]
12901 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12902 "* return ix86_output_call_insn (insn, operands[1]);"
12903 [(set_attr "type" "callv")])
12905 (define_insn "*sibcall_value_pop"
12906 [(set (match_operand 0)
12907 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12908 (match_operand 2)))
12909 (set (reg:SI SP_REG)
12910 (plus:SI (reg:SI SP_REG)
12911 (match_operand:SI 3 "immediate_operand" "i")))]
12912 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12913 "* return ix86_output_call_insn (insn, operands[1]);"
12914 [(set_attr "type" "callv")])
12916 (define_insn "*sibcall_value_pop_memory"
12917 [(set (match_operand 0)
12918 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12919 (match_operand 2)))
12920 (set (reg:SI SP_REG)
12921 (plus:SI (reg:SI SP_REG)
12922 (match_operand:SI 3 "immediate_operand" "i")))
12923 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12925 "* return ix86_output_call_insn (insn, operands[1]);"
12926 [(set_attr "type" "callv")])
12929 [(set (match_operand:SI 0 "register_operand")
12930 (match_operand:SI 1 "memory_operand"))
12931 (parallel [(set (match_operand 2)
12932 (call (mem:QI (match_dup 0))
12933 (match_operand 3)))
12934 (set (reg:SI SP_REG)
12935 (plus:SI (reg:SI SP_REG)
12936 (match_operand:SI 4 "immediate_operand")))])]
12937 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12938 && !reg_mentioned_p (operands[0],
12939 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12940 [(parallel [(set (match_dup 2)
12941 (call (mem:QI (match_dup 1))
12943 (set (reg:SI SP_REG)
12944 (plus:SI (reg:SI SP_REG)
12946 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12949 [(set (match_operand:SI 0 "register_operand")
12950 (match_operand:SI 1 "memory_operand"))
12951 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12952 (parallel [(set (match_operand 2)
12953 (call (mem:QI (match_dup 0))
12954 (match_operand 3)))
12955 (set (reg:SI SP_REG)
12956 (plus:SI (reg:SI SP_REG)
12957 (match_operand:SI 4 "immediate_operand")))])]
12958 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12959 && !reg_mentioned_p (operands[0],
12960 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12961 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12962 (parallel [(set (match_dup 2)
12963 (call (mem:QI (match_dup 1))
12965 (set (reg:SI SP_REG)
12966 (plus:SI (reg:SI SP_REG)
12968 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12970 ;; Call subroutine returning any type.
12972 (define_expand "untyped_call"
12973 [(parallel [(call (match_operand 0)
12976 (match_operand 2)])]
12981 /* In order to give reg-stack an easier job in validating two
12982 coprocessor registers as containing a possible return value,
12983 simply pretend the untyped call returns a complex long double
12986 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12987 and should have the default ABI. */
12989 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12990 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12991 operands[0], const0_rtx,
12992 GEN_INT ((TARGET_64BIT
12993 ? (ix86_abi == SYSV_ABI
12994 ? X86_64_SSE_REGPARM_MAX
12995 : X86_64_MS_SSE_REGPARM_MAX)
12996 : X86_32_SSE_REGPARM_MAX)
13000 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13002 rtx set = XVECEXP (operands[2], 0, i);
13003 emit_move_insn (SET_DEST (set), SET_SRC (set));
13006 /* The optimizer does not know that the call sets the function value
13007 registers we stored in the result block. We avoid problems by
13008 claiming that all hard registers are used and clobbered at this
13010 emit_insn (gen_blockage ());
13015 ;; Prologue and epilogue instructions
13017 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13018 ;; all of memory. This blocks insns from being moved across this point.
13020 (define_insn "blockage"
13021 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13024 [(set_attr "length" "0")])
13026 ;; Do not schedule instructions accessing memory across this point.
13028 (define_expand "memory_blockage"
13029 [(set (match_dup 0)
13030 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13033 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13034 MEM_VOLATILE_P (operands[0]) = 1;
13037 (define_insn "*memory_blockage"
13038 [(set (match_operand:BLK 0)
13039 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13042 [(set_attr "length" "0")])
13044 ;; As USE insns aren't meaningful after reload, this is used instead
13045 ;; to prevent deleting instructions setting registers for PIC code
13046 (define_insn "prologue_use"
13047 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13050 [(set_attr "length" "0")])
13052 ;; Insn emitted into the body of a function to return from a function.
13053 ;; This is only done if the function's epilogue is known to be simple.
13054 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13056 (define_expand "return"
13058 "ix86_can_use_return_insn_p ()"
13060 if (crtl->args.pops_args)
13062 rtx popc = GEN_INT (crtl->args.pops_args);
13063 emit_jump_insn (gen_simple_return_pop_internal (popc));
13068 ;; We need to disable this for TARGET_SEH, as otherwise
13069 ;; shrink-wrapped prologue gets enabled too. This might exceed
13070 ;; the maximum size of prologue in unwind information.
13071 ;; Also disallow shrink-wrapping if using stack slot to pass the
13072 ;; static chain pointer - the first instruction has to be pushl %esi
13073 ;; and it can't be moved around, as we use alternate entry points
13076 (define_expand "simple_return"
13078 "!TARGET_SEH && !ix86_static_chain_on_stack"
13080 if (crtl->args.pops_args)
13082 rtx popc = GEN_INT (crtl->args.pops_args);
13083 emit_jump_insn (gen_simple_return_pop_internal (popc));
13088 (define_insn "simple_return_internal"
13091 "* return ix86_output_function_return (false);"
13092 [(set_attr "length" "1")
13093 (set_attr "atom_unit" "jeu")
13094 (set_attr "length_immediate" "0")
13095 (set_attr "modrm" "0")])
13097 (define_insn "interrupt_return"
13099 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13102 return TARGET_64BIT ? "iretq" : "iret";
13105 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13106 ;; instruction Athlon and K8 have.
13108 (define_insn "simple_return_internal_long"
13110 (unspec [(const_int 0)] UNSPEC_REP)]
13112 "* return ix86_output_function_return (true);"
13113 [(set_attr "length" "2")
13114 (set_attr "atom_unit" "jeu")
13115 (set_attr "length_immediate" "0")
13116 (set_attr "prefix_rep" "1")
13117 (set_attr "modrm" "0")])
13119 (define_insn_and_split "simple_return_pop_internal"
13121 (use (match_operand:SI 0 "const_int_operand"))]
13124 "&& cfun->machine->function_return_type != indirect_branch_keep"
13126 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13127 [(set_attr "length" "3")
13128 (set_attr "atom_unit" "jeu")
13129 (set_attr "length_immediate" "2")
13130 (set_attr "modrm" "0")])
13132 (define_expand "simple_return_indirect_internal"
13135 (use (match_operand 0 "register_operand"))])])
13137 (define_insn "*simple_return_indirect_internal<mode>"
13139 (use (match_operand:W 0 "register_operand" "r"))]
13141 "* return ix86_output_indirect_function_return (operands[0]);"
13142 [(set (attr "type")
13143 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13144 != indirect_branch_keep)")
13145 (const_string "multi")
13146 (const_string "ibr")))
13147 (set_attr "length_immediate" "0")])
13153 [(set_attr "length" "1")
13154 (set_attr "length_immediate" "0")
13155 (set_attr "modrm" "0")])
13157 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13158 (define_insn "nops"
13159 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13163 int num = INTVAL (operands[0]);
13165 gcc_assert (IN_RANGE (num, 1, 8));
13168 fputs ("\tnop\n", asm_out_file);
13172 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13173 (set_attr "length_immediate" "0")
13174 (set_attr "modrm" "0")])
13176 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13177 ;; branch prediction penalty for the third jump in a 16-byte
13181 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13184 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13185 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13187 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13188 The align insn is used to avoid 3 jump instructions in the row to improve
13189 branch prediction and the benefits hardly outweigh the cost of extra 8
13190 nops on the average inserted by full alignment pseudo operation. */
13194 [(set_attr "length" "16")])
13196 (define_expand "prologue"
13199 "ix86_expand_prologue (); DONE;")
13201 (define_expand "set_got"
13203 [(set (match_operand:SI 0 "register_operand")
13204 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13205 (clobber (reg:CC FLAGS_REG))])]
13208 if (flag_pic && !TARGET_VXWORKS_RTP)
13209 ix86_pc_thunk_call_expanded = true;
13212 (define_insn "*set_got"
13213 [(set (match_operand:SI 0 "register_operand" "=r")
13214 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13215 (clobber (reg:CC FLAGS_REG))]
13217 "* return output_set_got (operands[0], NULL_RTX);"
13218 [(set_attr "type" "multi")
13219 (set_attr "length" "12")])
13221 (define_expand "set_got_labelled"
13223 [(set (match_operand:SI 0 "register_operand")
13224 (unspec:SI [(label_ref (match_operand 1))]
13226 (clobber (reg:CC FLAGS_REG))])]
13229 if (flag_pic && !TARGET_VXWORKS_RTP)
13230 ix86_pc_thunk_call_expanded = true;
13233 (define_insn "*set_got_labelled"
13234 [(set (match_operand:SI 0 "register_operand" "=r")
13235 (unspec:SI [(label_ref (match_operand 1))]
13237 (clobber (reg:CC FLAGS_REG))]
13239 "* return output_set_got (operands[0], operands[1]);"
13240 [(set_attr "type" "multi")
13241 (set_attr "length" "12")])
13243 (define_insn "set_got_rex64"
13244 [(set (match_operand:DI 0 "register_operand" "=r")
13245 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13247 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13248 [(set_attr "type" "lea")
13249 (set_attr "length_address" "4")
13250 (set_attr "mode" "DI")])
13252 (define_insn "set_rip_rex64"
13253 [(set (match_operand:DI 0 "register_operand" "=r")
13254 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13256 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13257 [(set_attr "type" "lea")
13258 (set_attr "length_address" "4")
13259 (set_attr "mode" "DI")])
13261 (define_insn "set_got_offset_rex64"
13262 [(set (match_operand:DI 0 "register_operand" "=r")
13264 [(label_ref (match_operand 1))]
13265 UNSPEC_SET_GOT_OFFSET))]
13267 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13268 [(set_attr "type" "imov")
13269 (set_attr "length_immediate" "0")
13270 (set_attr "length_address" "8")
13271 (set_attr "mode" "DI")])
13273 (define_expand "epilogue"
13276 "ix86_expand_epilogue (1); DONE;")
13278 (define_expand "sibcall_epilogue"
13281 "ix86_expand_epilogue (0); DONE;")
13283 (define_expand "eh_return"
13284 [(use (match_operand 0 "register_operand"))]
13287 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13289 /* Tricky bit: we write the address of the handler to which we will
13290 be returning into someone else's stack frame, one word below the
13291 stack address we wish to restore. */
13292 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13293 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13294 /* Return address is always in word_mode. */
13295 tmp = gen_rtx_MEM (word_mode, tmp);
13296 if (GET_MODE (ra) != word_mode)
13297 ra = convert_to_mode (word_mode, ra, 1);
13298 emit_move_insn (tmp, ra);
13300 emit_jump_insn (gen_eh_return_internal ());
13305 (define_insn_and_split "eh_return_internal"
13309 "epilogue_completed"
13311 "ix86_expand_epilogue (2); DONE;")
13313 (define_expand "@leave_<mode>"
13315 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13316 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13317 (clobber (mem:BLK (scratch)))])]
13319 "operands[0] = GEN_INT (<MODE_SIZE>);")
13321 (define_insn "*leave"
13322 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13323 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13324 (clobber (mem:BLK (scratch)))]
13327 [(set_attr "type" "leave")])
13329 (define_insn "*leave_rex64"
13330 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13331 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13332 (clobber (mem:BLK (scratch)))]
13335 [(set_attr "type" "leave")])
13337 ;; Handle -fsplit-stack.
13339 (define_expand "split_stack_prologue"
13343 ix86_expand_split_stack_prologue ();
13347 ;; In order to support the call/return predictor, we use a return
13348 ;; instruction which the middle-end doesn't see.
13349 (define_insn "split_stack_return"
13350 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13351 UNSPECV_SPLIT_STACK_RETURN)]
13354 if (operands[0] == const0_rtx)
13359 [(set_attr "atom_unit" "jeu")
13360 (set_attr "modrm" "0")
13361 (set (attr "length")
13362 (if_then_else (match_operand:SI 0 "const0_operand")
13365 (set (attr "length_immediate")
13366 (if_then_else (match_operand:SI 0 "const0_operand")
13370 ;; If there are operand 0 bytes available on the stack, jump to
13373 (define_expand "split_stack_space_check"
13374 [(set (pc) (if_then_else
13375 (ltu (minus (reg SP_REG)
13376 (match_operand 0 "register_operand"))
13378 (label_ref (match_operand 1))
13382 rtx reg = gen_reg_rtx (Pmode);
13384 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13386 operands[2] = ix86_split_stack_guard ();
13387 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13392 ;; Bit manipulation instructions.
13394 (define_expand "ffs<mode>2"
13395 [(set (match_dup 2) (const_int -1))
13396 (parallel [(set (match_dup 3) (match_dup 4))
13397 (set (match_operand:SWI48 0 "register_operand")
13399 (match_operand:SWI48 1 "nonimmediate_operand")))])
13400 (set (match_dup 0) (if_then_else:SWI48
13401 (eq (match_dup 3) (const_int 0))
13404 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13405 (clobber (reg:CC FLAGS_REG))])]
13408 machine_mode flags_mode;
13410 if (<MODE>mode == SImode && !TARGET_CMOVE)
13412 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13416 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13418 operands[2] = gen_reg_rtx (<MODE>mode);
13419 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13420 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13423 (define_insn_and_split "ffssi2_no_cmove"
13424 [(set (match_operand:SI 0 "register_operand" "=r")
13425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13426 (clobber (match_scratch:SI 2 "=&q"))
13427 (clobber (reg:CC FLAGS_REG))]
13430 "&& reload_completed"
13431 [(parallel [(set (match_dup 4) (match_dup 5))
13432 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13433 (set (strict_low_part (match_dup 3))
13434 (eq:QI (match_dup 4) (const_int 0)))
13435 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13436 (clobber (reg:CC FLAGS_REG))])
13437 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13438 (clobber (reg:CC FLAGS_REG))])
13439 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13440 (clobber (reg:CC FLAGS_REG))])]
13442 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13444 operands[3] = gen_lowpart (QImode, operands[2]);
13445 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13446 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13448 ix86_expand_clear (operands[2]);
13451 (define_insn_and_split "*tzcnt<mode>_1"
13452 [(set (reg:CCC FLAGS_REG)
13453 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13455 (set (match_operand:SWI48 0 "register_operand" "=r")
13456 (ctz:SWI48 (match_dup 1)))]
13458 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13459 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13460 && optimize_function_for_speed_p (cfun)
13461 && !reg_mentioned_p (operands[0], operands[1])"
13463 [(set (reg:CCC FLAGS_REG)
13464 (compare:CCC (match_dup 1) (const_int 0)))
13466 (ctz:SWI48 (match_dup 1)))
13467 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13468 "ix86_expand_clear (operands[0]);"
13469 [(set_attr "type" "alu1")
13470 (set_attr "prefix_0f" "1")
13471 (set_attr "prefix_rep" "1")
13472 (set_attr "btver2_decode" "double")
13473 (set_attr "mode" "<MODE>")])
13475 ; False dependency happens when destination is only updated by tzcnt,
13476 ; lzcnt or popcnt. There is no false dependency when destination is
13477 ; also used in source.
13478 (define_insn "*tzcnt<mode>_1_falsedep"
13479 [(set (reg:CCC FLAGS_REG)
13480 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13482 (set (match_operand:SWI48 0 "register_operand" "=r")
13483 (ctz:SWI48 (match_dup 1)))
13484 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13485 UNSPEC_INSN_FALSE_DEP)]
13487 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13488 [(set_attr "type" "alu1")
13489 (set_attr "prefix_0f" "1")
13490 (set_attr "prefix_rep" "1")
13491 (set_attr "btver2_decode" "double")
13492 (set_attr "mode" "<MODE>")])
13494 (define_insn "*bsf<mode>_1"
13495 [(set (reg:CCZ FLAGS_REG)
13496 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13498 (set (match_operand:SWI48 0 "register_operand" "=r")
13499 (ctz:SWI48 (match_dup 1)))]
13501 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13502 [(set_attr "type" "alu1")
13503 (set_attr "prefix_0f" "1")
13504 (set_attr "btver2_decode" "double")
13505 (set_attr "znver1_decode" "vector")
13506 (set_attr "mode" "<MODE>")])
13508 (define_insn_and_split "ctz<mode>2"
13509 [(set (match_operand:SWI48 0 "register_operand" "=r")
13511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13512 (clobber (reg:CC FLAGS_REG))]
13516 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13517 else if (optimize_function_for_size_p (cfun))
13519 else if (TARGET_GENERIC)
13520 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13521 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13523 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13525 "(TARGET_BMI || TARGET_GENERIC)
13526 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13527 && optimize_function_for_speed_p (cfun)
13528 && !reg_mentioned_p (operands[0], operands[1])"
13530 [(set (match_dup 0)
13531 (ctz:SWI48 (match_dup 1)))
13532 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13533 (clobber (reg:CC FLAGS_REG))])]
13534 "ix86_expand_clear (operands[0]);"
13535 [(set_attr "type" "alu1")
13536 (set_attr "prefix_0f" "1")
13537 (set (attr "prefix_rep")
13539 (ior (match_test "TARGET_BMI")
13540 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13541 (match_test "TARGET_GENERIC")))
13543 (const_string "0")))
13544 (set_attr "mode" "<MODE>")])
13546 ; False dependency happens when destination is only updated by tzcnt,
13547 ; lzcnt or popcnt. There is no false dependency when destination is
13548 ; also used in source.
13549 (define_insn "*ctz<mode>2_falsedep"
13550 [(set (match_operand:SWI48 0 "register_operand" "=r")
13552 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13553 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13554 UNSPEC_INSN_FALSE_DEP)
13555 (clobber (reg:CC FLAGS_REG))]
13559 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13560 else if (TARGET_GENERIC)
13561 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13562 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13564 gcc_unreachable ();
13566 [(set_attr "type" "alu1")
13567 (set_attr "prefix_0f" "1")
13568 (set_attr "prefix_rep" "1")
13569 (set_attr "mode" "<MODE>")])
13571 (define_insn "bsr_rex64"
13572 [(set (match_operand:DI 0 "register_operand" "=r")
13573 (minus:DI (const_int 63)
13574 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13575 (clobber (reg:CC FLAGS_REG))]
13577 "bsr{q}\t{%1, %0|%0, %1}"
13578 [(set_attr "type" "alu1")
13579 (set_attr "prefix_0f" "1")
13580 (set_attr "znver1_decode" "vector")
13581 (set_attr "mode" "DI")])
13584 [(set (match_operand:SI 0 "register_operand" "=r")
13585 (minus:SI (const_int 31)
13586 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13587 (clobber (reg:CC FLAGS_REG))]
13589 "bsr{l}\t{%1, %0|%0, %1}"
13590 [(set_attr "type" "alu1")
13591 (set_attr "prefix_0f" "1")
13592 (set_attr "znver1_decode" "vector")
13593 (set_attr "mode" "SI")])
13595 (define_insn "*bsrhi"
13596 [(set (match_operand:HI 0 "register_operand" "=r")
13597 (minus:HI (const_int 15)
13598 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13599 (clobber (reg:CC FLAGS_REG))]
13601 "bsr{w}\t{%1, %0|%0, %1}"
13602 [(set_attr "type" "alu1")
13603 (set_attr "prefix_0f" "1")
13604 (set_attr "znver1_decode" "vector")
13605 (set_attr "mode" "HI")])
13607 (define_expand "clz<mode>2"
13609 [(set (match_operand:SWI48 0 "register_operand")
13612 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13613 (clobber (reg:CC FLAGS_REG))])
13615 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13616 (clobber (reg:CC FLAGS_REG))])]
13621 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13624 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13627 (define_insn_and_split "clz<mode>2_lzcnt"
13628 [(set (match_operand:SWI48 0 "register_operand" "=r")
13630 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13631 (clobber (reg:CC FLAGS_REG))]
13633 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13634 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13635 && optimize_function_for_speed_p (cfun)
13636 && !reg_mentioned_p (operands[0], operands[1])"
13638 [(set (match_dup 0)
13639 (clz:SWI48 (match_dup 1)))
13640 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13641 (clobber (reg:CC FLAGS_REG))])]
13642 "ix86_expand_clear (operands[0]);"
13643 [(set_attr "prefix_rep" "1")
13644 (set_attr "type" "bitmanip")
13645 (set_attr "mode" "<MODE>")])
13647 ; False dependency happens when destination is only updated by tzcnt,
13648 ; lzcnt or popcnt. There is no false dependency when destination is
13649 ; also used in source.
13650 (define_insn "*clz<mode>2_lzcnt_falsedep"
13651 [(set (match_operand:SWI48 0 "register_operand" "=r")
13653 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13654 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13655 UNSPEC_INSN_FALSE_DEP)
13656 (clobber (reg:CC FLAGS_REG))]
13658 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13659 [(set_attr "prefix_rep" "1")
13660 (set_attr "type" "bitmanip")
13661 (set_attr "mode" "<MODE>")])
13663 (define_int_iterator LT_ZCNT
13664 [(UNSPEC_TZCNT "TARGET_BMI")
13665 (UNSPEC_LZCNT "TARGET_LZCNT")])
13667 (define_int_attr lt_zcnt
13668 [(UNSPEC_TZCNT "tzcnt")
13669 (UNSPEC_LZCNT "lzcnt")])
13671 (define_int_attr lt_zcnt_type
13672 [(UNSPEC_TZCNT "alu1")
13673 (UNSPEC_LZCNT "bitmanip")])
13675 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13676 ;; provides operand size as output when source operand is zero.
13678 (define_insn_and_split "<lt_zcnt>_<mode>"
13679 [(set (match_operand:SWI48 0 "register_operand" "=r")
13681 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13682 (clobber (reg:CC FLAGS_REG))]
13684 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13685 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13686 && optimize_function_for_speed_p (cfun)
13687 && !reg_mentioned_p (operands[0], operands[1])"
13689 [(set (match_dup 0)
13690 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13691 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13692 (clobber (reg:CC FLAGS_REG))])]
13693 "ix86_expand_clear (operands[0]);"
13694 [(set_attr "type" "<lt_zcnt_type>")
13695 (set_attr "prefix_0f" "1")
13696 (set_attr "prefix_rep" "1")
13697 (set_attr "mode" "<MODE>")])
13699 ; False dependency happens when destination is only updated by tzcnt,
13700 ; lzcnt or popcnt. There is no false dependency when destination is
13701 ; also used in source.
13702 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13703 [(set (match_operand:SWI48 0 "register_operand" "=r")
13705 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13706 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13707 UNSPEC_INSN_FALSE_DEP)
13708 (clobber (reg:CC FLAGS_REG))]
13710 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13711 [(set_attr "type" "<lt_zcnt_type>")
13712 (set_attr "prefix_0f" "1")
13713 (set_attr "prefix_rep" "1")
13714 (set_attr "mode" "<MODE>")])
13716 (define_insn "<lt_zcnt>_hi"
13717 [(set (match_operand:HI 0 "register_operand" "=r")
13719 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13720 (clobber (reg:CC FLAGS_REG))]
13722 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13723 [(set_attr "type" "<lt_zcnt_type>")
13724 (set_attr "prefix_0f" "1")
13725 (set_attr "prefix_rep" "1")
13726 (set_attr "mode" "HI")])
13728 ;; BMI instructions.
13730 (define_insn "bmi_bextr_<mode>"
13731 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13732 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13733 (match_operand:SWI48 2 "register_operand" "r,r")]
13735 (clobber (reg:CC FLAGS_REG))]
13737 "bextr\t{%2, %1, %0|%0, %1, %2}"
13738 [(set_attr "type" "bitmanip")
13739 (set_attr "btver2_decode" "direct, double")
13740 (set_attr "mode" "<MODE>")])
13742 (define_insn "*bmi_bextr_<mode>_ccz"
13743 [(set (reg:CCZ FLAGS_REG)
13745 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13746 (match_operand:SWI48 2 "register_operand" "r,r")]
13749 (clobber (match_scratch:SWI48 0 "=r,r"))]
13751 "bextr\t{%2, %1, %0|%0, %1, %2}"
13752 [(set_attr "type" "bitmanip")
13753 (set_attr "btver2_decode" "direct, double")
13754 (set_attr "mode" "<MODE>")])
13756 (define_insn "*bmi_blsi_<mode>"
13757 [(set (match_operand:SWI48 0 "register_operand" "=r")
13760 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13762 (clobber (reg:CC FLAGS_REG))]
13764 "blsi\t{%1, %0|%0, %1}"
13765 [(set_attr "type" "bitmanip")
13766 (set_attr "btver2_decode" "double")
13767 (set_attr "mode" "<MODE>")])
13769 (define_insn "*bmi_blsmsk_<mode>"
13770 [(set (match_operand:SWI48 0 "register_operand" "=r")
13773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13776 (clobber (reg:CC FLAGS_REG))]
13778 "blsmsk\t{%1, %0|%0, %1}"
13779 [(set_attr "type" "bitmanip")
13780 (set_attr "btver2_decode" "double")
13781 (set_attr "mode" "<MODE>")])
13783 (define_insn "*bmi_blsr_<mode>"
13784 [(set (match_operand:SWI48 0 "register_operand" "=r")
13787 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13790 (clobber (reg:CC FLAGS_REG))]
13792 "blsr\t{%1, %0|%0, %1}"
13793 [(set_attr "type" "bitmanip")
13794 (set_attr "btver2_decode" "double")
13795 (set_attr "mode" "<MODE>")])
13797 (define_insn "*bmi_blsr_<mode>_cmp"
13798 [(set (reg:CCZ FLAGS_REG)
13802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13806 (set (match_operand:SWI48 0 "register_operand" "=r")
13813 "blsr\t{%1, %0|%0, %1}"
13814 [(set_attr "type" "bitmanip")
13815 (set_attr "btver2_decode" "double")
13816 (set_attr "mode" "<MODE>")])
13818 (define_insn "*bmi_blsr_<mode>_ccz"
13819 [(set (reg:CCZ FLAGS_REG)
13823 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13827 (clobber (match_scratch:SWI48 0 "=r"))]
13829 "blsr\t{%1, %0|%0, %1}"
13830 [(set_attr "type" "bitmanip")
13831 (set_attr "btver2_decode" "double")
13832 (set_attr "mode" "<MODE>")])
13834 ;; BMI2 instructions.
13835 (define_expand "bmi2_bzhi_<mode>3"
13837 [(set (match_operand:SWI48 0 "register_operand")
13838 (if_then_else:SWI48
13839 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13842 (zero_extract:SWI48
13843 (match_operand:SWI48 1 "nonimmediate_operand")
13844 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13848 (clobber (reg:CC FLAGS_REG))])]
13850 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13852 (define_insn "*bmi2_bzhi_<mode>3"
13853 [(set (match_operand:SWI48 0 "register_operand" "=r")
13854 (if_then_else:SWI48
13855 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13858 (zero_extract:SWI48
13859 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13860 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13861 (match_operand:SWI48 3 "const_int_operand" "n"))
13864 (clobber (reg:CC FLAGS_REG))]
13865 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13866 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13867 [(set_attr "type" "bitmanip")
13868 (set_attr "prefix" "vex")
13869 (set_attr "mode" "<MODE>")])
13871 (define_insn "*bmi2_bzhi_<mode>3_1"
13872 [(set (match_operand:SWI48 0 "register_operand" "=r")
13873 (if_then_else:SWI48
13874 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13875 (zero_extract:SWI48
13876 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13877 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13878 (match_operand:SWI48 3 "const_int_operand" "n"))
13881 (clobber (reg:CC FLAGS_REG))]
13882 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13883 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13884 [(set_attr "type" "bitmanip")
13885 (set_attr "prefix" "vex")
13886 (set_attr "mode" "<MODE>")])
13888 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13889 [(set (reg:CCZ FLAGS_REG)
13891 (if_then_else:SWI48
13892 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13893 (zero_extract:SWI48
13894 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13895 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13896 (match_operand:SWI48 3 "const_int_operand" "n"))
13900 (clobber (match_scratch:SWI48 0 "=r"))]
13901 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13902 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13903 [(set_attr "type" "bitmanip")
13904 (set_attr "prefix" "vex")
13905 (set_attr "mode" "<MODE>")])
13907 (define_insn "bmi2_pdep_<mode>3"
13908 [(set (match_operand:SWI48 0 "register_operand" "=r")
13909 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13910 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13913 "pdep\t{%2, %1, %0|%0, %1, %2}"
13914 [(set_attr "type" "bitmanip")
13915 (set_attr "prefix" "vex")
13916 (set_attr "mode" "<MODE>")])
13918 (define_insn "bmi2_pext_<mode>3"
13919 [(set (match_operand:SWI48 0 "register_operand" "=r")
13920 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13921 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13924 "pext\t{%2, %1, %0|%0, %1, %2}"
13925 [(set_attr "type" "bitmanip")
13926 (set_attr "prefix" "vex")
13927 (set_attr "mode" "<MODE>")])
13929 ;; TBM instructions.
13930 (define_expand "tbm_bextri_<mode>"
13932 [(set (match_operand:SWI48 0 "register_operand")
13933 (zero_extract:SWI48
13934 (match_operand:SWI48 1 "nonimmediate_operand")
13935 (match_operand 2 "const_0_to_255_operand" "N")
13936 (match_operand 3 "const_0_to_255_operand" "N")))
13937 (clobber (reg:CC FLAGS_REG))])]
13940 if (operands[2] == const0_rtx
13941 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13943 emit_move_insn (operands[0], const0_rtx);
13946 if (INTVAL (operands[2]) + INTVAL (operands[3])
13947 > <MODE_SIZE> * BITS_PER_UNIT)
13948 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13951 (define_insn "*tbm_bextri_<mode>"
13952 [(set (match_operand:SWI48 0 "register_operand" "=r")
13953 (zero_extract:SWI48
13954 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13955 (match_operand 2 "const_0_to_255_operand" "N")
13956 (match_operand 3 "const_0_to_255_operand" "N")))
13957 (clobber (reg:CC FLAGS_REG))]
13960 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13961 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13963 [(set_attr "type" "bitmanip")
13964 (set_attr "mode" "<MODE>")])
13966 (define_insn "*tbm_blcfill_<mode>"
13967 [(set (match_operand:SWI48 0 "register_operand" "=r")
13970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13973 (clobber (reg:CC FLAGS_REG))]
13975 "blcfill\t{%1, %0|%0, %1}"
13976 [(set_attr "type" "bitmanip")
13977 (set_attr "mode" "<MODE>")])
13979 (define_insn "*tbm_blci_<mode>"
13980 [(set (match_operand:SWI48 0 "register_operand" "=r")
13984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13987 (clobber (reg:CC FLAGS_REG))]
13989 "blci\t{%1, %0|%0, %1}"
13990 [(set_attr "type" "bitmanip")
13991 (set_attr "mode" "<MODE>")])
13993 (define_insn "*tbm_blcic_<mode>"
13994 [(set (match_operand:SWI48 0 "register_operand" "=r")
13997 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14001 (clobber (reg:CC FLAGS_REG))]
14003 "blcic\t{%1, %0|%0, %1}"
14004 [(set_attr "type" "bitmanip")
14005 (set_attr "mode" "<MODE>")])
14007 (define_insn "*tbm_blcmsk_<mode>"
14008 [(set (match_operand:SWI48 0 "register_operand" "=r")
14011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14014 (clobber (reg:CC FLAGS_REG))]
14016 "blcmsk\t{%1, %0|%0, %1}"
14017 [(set_attr "type" "bitmanip")
14018 (set_attr "mode" "<MODE>")])
14020 (define_insn "*tbm_blcs_<mode>"
14021 [(set (match_operand:SWI48 0 "register_operand" "=r")
14024 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14027 (clobber (reg:CC FLAGS_REG))]
14029 "blcs\t{%1, %0|%0, %1}"
14030 [(set_attr "type" "bitmanip")
14031 (set_attr "mode" "<MODE>")])
14033 (define_insn "*tbm_blsfill_<mode>"
14034 [(set (match_operand:SWI48 0 "register_operand" "=r")
14037 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14040 (clobber (reg:CC FLAGS_REG))]
14042 "blsfill\t{%1, %0|%0, %1}"
14043 [(set_attr "type" "bitmanip")
14044 (set_attr "mode" "<MODE>")])
14046 (define_insn "*tbm_blsic_<mode>"
14047 [(set (match_operand:SWI48 0 "register_operand" "=r")
14050 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14054 (clobber (reg:CC FLAGS_REG))]
14056 "blsic\t{%1, %0|%0, %1}"
14057 [(set_attr "type" "bitmanip")
14058 (set_attr "mode" "<MODE>")])
14060 (define_insn "*tbm_t1mskc_<mode>"
14061 [(set (match_operand:SWI48 0 "register_operand" "=r")
14064 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14068 (clobber (reg:CC FLAGS_REG))]
14070 "t1mskc\t{%1, %0|%0, %1}"
14071 [(set_attr "type" "bitmanip")
14072 (set_attr "mode" "<MODE>")])
14074 (define_insn "*tbm_tzmsk_<mode>"
14075 [(set (match_operand:SWI48 0 "register_operand" "=r")
14078 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14082 (clobber (reg:CC FLAGS_REG))]
14084 "tzmsk\t{%1, %0|%0, %1}"
14085 [(set_attr "type" "bitmanip")
14086 (set_attr "mode" "<MODE>")])
14088 (define_insn_and_split "popcount<mode>2"
14089 [(set (match_operand:SWI48 0 "register_operand" "=r")
14091 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14092 (clobber (reg:CC FLAGS_REG))]
14096 return "popcnt\t{%1, %0|%0, %1}";
14098 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14101 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14102 && optimize_function_for_speed_p (cfun)
14103 && !reg_mentioned_p (operands[0], operands[1])"
14105 [(set (match_dup 0)
14106 (popcount:SWI48 (match_dup 1)))
14107 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14108 (clobber (reg:CC FLAGS_REG))])]
14109 "ix86_expand_clear (operands[0]);"
14110 [(set_attr "prefix_rep" "1")
14111 (set_attr "type" "bitmanip")
14112 (set_attr "mode" "<MODE>")])
14114 ; False dependency happens when destination is only updated by tzcnt,
14115 ; lzcnt or popcnt. There is no false dependency when destination is
14116 ; also used in source.
14117 (define_insn "*popcount<mode>2_falsedep"
14118 [(set (match_operand:SWI48 0 "register_operand" "=r")
14120 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14121 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14122 UNSPEC_INSN_FALSE_DEP)
14123 (clobber (reg:CC FLAGS_REG))]
14127 return "popcnt\t{%1, %0|%0, %1}";
14129 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14132 [(set_attr "prefix_rep" "1")
14133 (set_attr "type" "bitmanip")
14134 (set_attr "mode" "<MODE>")])
14136 (define_insn_and_split "*popcounthi2_1"
14137 [(set (match_operand:SI 0 "register_operand")
14139 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14140 (clobber (reg:CC FLAGS_REG))]
14142 && ix86_pre_reload_split ()"
14147 rtx tmp = gen_reg_rtx (HImode);
14149 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14150 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14154 (define_insn "popcounthi2"
14155 [(set (match_operand:HI 0 "register_operand" "=r")
14157 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14158 (clobber (reg:CC FLAGS_REG))]
14162 return "popcnt\t{%1, %0|%0, %1}";
14164 return "popcnt{w}\t{%1, %0|%0, %1}";
14167 [(set_attr "prefix_rep" "1")
14168 (set_attr "type" "bitmanip")
14169 (set_attr "mode" "HI")])
14171 (define_expand "bswapdi2"
14172 [(set (match_operand:DI 0 "register_operand")
14173 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14177 operands[1] = force_reg (DImode, operands[1]);
14180 (define_expand "bswapsi2"
14181 [(set (match_operand:SI 0 "register_operand")
14182 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14187 else if (TARGET_BSWAP)
14188 operands[1] = force_reg (SImode, operands[1]);
14191 rtx x = operands[0];
14193 emit_move_insn (x, operands[1]);
14194 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14195 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14196 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14201 (define_insn "*bswap<mode>2_movbe"
14202 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14203 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14205 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14208 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14209 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14210 [(set_attr "type" "bitmanip,imov,imov")
14211 (set_attr "modrm" "0,1,1")
14212 (set_attr "prefix_0f" "*,1,1")
14213 (set_attr "prefix_extra" "*,1,1")
14214 (set_attr "mode" "<MODE>")])
14216 (define_insn "*bswap<mode>2"
14217 [(set (match_operand:SWI48 0 "register_operand" "=r")
14218 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14221 [(set_attr "type" "bitmanip")
14222 (set_attr "modrm" "0")
14223 (set_attr "mode" "<MODE>")])
14225 (define_expand "bswaphi2"
14226 [(set (match_operand:HI 0 "register_operand")
14227 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14230 (define_insn "*bswaphi2_movbe"
14231 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14232 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14236 xchg{b}\t{%h0, %b0|%b0, %h0}
14237 movbe{w}\t{%1, %0|%0, %1}
14238 movbe{w}\t{%1, %0|%0, %1}"
14239 [(set_attr "type" "imov")
14240 (set_attr "modrm" "*,1,1")
14241 (set_attr "prefix_0f" "*,1,1")
14242 (set_attr "prefix_extra" "*,1,1")
14243 (set_attr "pent_pair" "np,*,*")
14244 (set_attr "athlon_decode" "vector,*,*")
14245 (set_attr "amdfam10_decode" "double,*,*")
14246 (set_attr "bdver1_decode" "double,*,*")
14247 (set_attr "mode" "QI,HI,HI")])
14250 [(set (match_operand:HI 0 "general_reg_operand")
14251 (bswap:HI (match_dup 0)))]
14253 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14254 && peep2_regno_dead_p (0, FLAGS_REG)"
14255 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14256 (clobber (reg:CC FLAGS_REG))])])
14258 (define_insn "bswaphi_lowpart"
14259 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14260 (bswap:HI (match_dup 0)))
14261 (clobber (reg:CC FLAGS_REG))]
14264 xchg{b}\t{%h0, %b0|%b0, %h0}
14265 rol{w}\t{$8, %0|%0, 8}"
14266 [(set (attr "preferred_for_size")
14267 (cond [(eq_attr "alternative" "0")
14268 (symbol_ref "true")]
14269 (symbol_ref "false")))
14270 (set (attr "preferred_for_speed")
14271 (cond [(eq_attr "alternative" "0")
14272 (symbol_ref "TARGET_USE_XCHGB")]
14273 (symbol_ref "!TARGET_USE_XCHGB")))
14274 (set_attr "length" "2,4")
14275 (set_attr "mode" "QI,HI")])
14277 (define_expand "paritydi2"
14278 [(set (match_operand:DI 0 "register_operand")
14279 (parity:DI (match_operand:DI 1 "register_operand")))]
14282 rtx scratch = gen_reg_rtx (QImode);
14284 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14285 NULL_RTX, operands[1]));
14287 ix86_expand_setcc (scratch, ORDERED,
14288 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14291 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14294 rtx tmp = gen_reg_rtx (SImode);
14296 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14297 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14302 (define_expand "paritysi2"
14303 [(set (match_operand:SI 0 "register_operand")
14304 (parity:SI (match_operand:SI 1 "register_operand")))]
14307 rtx scratch = gen_reg_rtx (QImode);
14309 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14311 ix86_expand_setcc (scratch, ORDERED,
14312 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14314 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14318 (define_insn_and_split "paritydi2_cmp"
14319 [(set (reg:CC FLAGS_REG)
14320 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14322 (clobber (match_scratch:DI 0 "=r"))
14323 (clobber (match_scratch:SI 1 "=&r"))
14324 (clobber (match_scratch:HI 2 "=Q"))]
14327 "&& reload_completed"
14329 [(set (match_dup 1)
14330 (xor:SI (match_dup 1) (match_dup 4)))
14331 (clobber (reg:CC FLAGS_REG))])
14333 [(set (reg:CC FLAGS_REG)
14334 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14335 (clobber (match_dup 1))
14336 (clobber (match_dup 2))])]
14338 operands[4] = gen_lowpart (SImode, operands[3]);
14342 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14343 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14346 operands[1] = gen_highpart (SImode, operands[3]);
14349 (define_insn_and_split "paritysi2_cmp"
14350 [(set (reg:CC FLAGS_REG)
14351 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14353 (clobber (match_scratch:SI 0 "=r"))
14354 (clobber (match_scratch:HI 1 "=&Q"))]
14357 "&& reload_completed"
14359 [(set (match_dup 1)
14360 (xor:HI (match_dup 1) (match_dup 3)))
14361 (clobber (reg:CC FLAGS_REG))])
14363 [(set (reg:CC FLAGS_REG)
14364 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14365 (clobber (match_dup 1))])]
14367 operands[3] = gen_lowpart (HImode, operands[2]);
14369 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14370 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14373 (define_insn "*parityhi2_cmp"
14374 [(set (reg:CC FLAGS_REG)
14375 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14377 (clobber (match_scratch:HI 0 "=Q"))]
14379 "xor{b}\t{%h0, %b0|%b0, %h0}"
14380 [(set_attr "length" "2")
14381 (set_attr "mode" "HI")])
14384 ;; Thread-local storage patterns for ELF.
14386 ;; Note that these code sequences must appear exactly as shown
14387 ;; in order to allow linker relaxation.
14389 (define_insn "*tls_global_dynamic_32_gnu"
14390 [(set (match_operand:SI 0 "register_operand" "=a")
14392 [(match_operand:SI 1 "register_operand" "Yb")
14393 (match_operand 2 "tls_symbolic_operand")
14394 (match_operand 3 "constant_call_address_operand" "Bz")
14397 (clobber (match_scratch:SI 4 "=d"))
14398 (clobber (match_scratch:SI 5 "=c"))
14399 (clobber (reg:CC FLAGS_REG))]
14400 "!TARGET_64BIT && TARGET_GNU_TLS"
14402 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14404 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14407 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14408 if (TARGET_SUN_TLS)
14409 #ifdef HAVE_AS_IX86_TLSGDPLT
14410 return "call\t%a2@tlsgdplt";
14412 return "call\t%p3@plt";
14414 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14415 return "call\t%P3";
14416 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14418 [(set_attr "type" "multi")
14419 (set_attr "length" "12")])
14421 (define_expand "tls_global_dynamic_32"
14423 [(set (match_operand:SI 0 "register_operand")
14424 (unspec:SI [(match_operand:SI 2 "register_operand")
14425 (match_operand 1 "tls_symbolic_operand")
14426 (match_operand 3 "constant_call_address_operand")
14429 (clobber (match_scratch:SI 4))
14430 (clobber (match_scratch:SI 5))
14431 (clobber (reg:CC FLAGS_REG))])]
14433 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14435 (define_insn "*tls_global_dynamic_64_<mode>"
14436 [(set (match_operand:P 0 "register_operand" "=a")
14438 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14439 (match_operand 3)))
14440 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14446 /* The .loc directive has effect for 'the immediately following assembly
14447 instruction'. So for a sequence:
14451 the 'immediately following assembly instruction' is insn1.
14452 We want to emit an insn prefix here, but if we use .byte (as shown in
14453 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14454 inside the insn sequence, rather than to the start. After relaxation
14455 of the sequence by the linker, the .loc might point inside an insn.
14456 Use data16 prefix instead, which doesn't have this problem. */
14457 fputs ("\tdata16", asm_out_file);
14459 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14460 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14461 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14463 fputs (ASM_BYTE "0x66\n", asm_out_file);
14464 fputs ("\trex64\n", asm_out_file);
14465 if (TARGET_SUN_TLS)
14466 return "call\t%p2@plt";
14467 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14468 return "call\t%P2";
14469 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14471 [(set_attr "type" "multi")
14472 (set (attr "length")
14473 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14475 (define_insn "*tls_global_dynamic_64_largepic"
14476 [(set (match_operand:DI 0 "register_operand" "=a")
14478 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14479 (match_operand:DI 3 "immediate_operand" "i")))
14480 (match_operand 4)))
14481 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14484 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14485 && GET_CODE (operands[3]) == CONST
14486 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14487 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14490 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14491 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14492 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14493 return "call\t{*%%rax|rax}";
14495 [(set_attr "type" "multi")
14496 (set_attr "length" "22")])
14498 (define_expand "@tls_global_dynamic_64_<mode>"
14500 [(set (match_operand:P 0 "register_operand")
14502 (mem:QI (match_operand 2))
14504 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14508 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14510 (define_insn "*tls_local_dynamic_base_32_gnu"
14511 [(set (match_operand:SI 0 "register_operand" "=a")
14513 [(match_operand:SI 1 "register_operand" "Yb")
14514 (match_operand 2 "constant_call_address_operand" "Bz")
14516 UNSPEC_TLS_LD_BASE))
14517 (clobber (match_scratch:SI 3 "=d"))
14518 (clobber (match_scratch:SI 4 "=c"))
14519 (clobber (reg:CC FLAGS_REG))]
14520 "!TARGET_64BIT && TARGET_GNU_TLS"
14523 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14524 if (TARGET_SUN_TLS)
14526 if (HAVE_AS_IX86_TLSLDMPLT)
14527 return "call\t%&@tlsldmplt";
14529 return "call\t%p2@plt";
14531 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14532 return "call\t%P2";
14533 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14535 [(set_attr "type" "multi")
14536 (set_attr "length" "11")])
14538 (define_expand "tls_local_dynamic_base_32"
14540 [(set (match_operand:SI 0 "register_operand")
14542 [(match_operand:SI 1 "register_operand")
14543 (match_operand 2 "constant_call_address_operand")
14545 UNSPEC_TLS_LD_BASE))
14546 (clobber (match_scratch:SI 3))
14547 (clobber (match_scratch:SI 4))
14548 (clobber (reg:CC FLAGS_REG))])]
14550 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14552 (define_insn "*tls_local_dynamic_base_64_<mode>"
14553 [(set (match_operand:P 0 "register_operand" "=a")
14555 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14556 (match_operand 2)))
14557 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14561 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14562 if (TARGET_SUN_TLS)
14563 return "call\t%p1@plt";
14564 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14565 return "call\t%P1";
14566 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14568 [(set_attr "type" "multi")
14569 (set_attr "length" "12")])
14571 (define_insn "*tls_local_dynamic_base_64_largepic"
14572 [(set (match_operand:DI 0 "register_operand" "=a")
14574 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14575 (match_operand:DI 2 "immediate_operand" "i")))
14576 (match_operand 3)))
14577 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14578 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14579 && GET_CODE (operands[2]) == CONST
14580 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14581 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14584 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14585 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14586 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14587 return "call\t{*%%rax|rax}";
14589 [(set_attr "type" "multi")
14590 (set_attr "length" "22")])
14592 (define_expand "@tls_local_dynamic_base_64_<mode>"
14594 [(set (match_operand:P 0 "register_operand")
14596 (mem:QI (match_operand 1))
14598 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14600 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14602 ;; Local dynamic of a single variable is a lose. Show combine how
14603 ;; to convert that back to global dynamic.
14605 (define_insn_and_split "*tls_local_dynamic_32_once"
14606 [(set (match_operand:SI 0 "register_operand" "=a")
14608 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609 (match_operand 2 "constant_call_address_operand" "Bz")
14611 UNSPEC_TLS_LD_BASE)
14612 (const:SI (unspec:SI
14613 [(match_operand 3 "tls_symbolic_operand")]
14615 (clobber (match_scratch:SI 4 "=d"))
14616 (clobber (match_scratch:SI 5 "=c"))
14617 (clobber (reg:CC FLAGS_REG))]
14622 [(set (match_dup 0)
14623 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14626 (clobber (match_dup 4))
14627 (clobber (match_dup 5))
14628 (clobber (reg:CC FLAGS_REG))])])
14630 ;; Load and add the thread base pointer from %<tp_seg>:0.
14631 (define_insn_and_split "*load_tp_<mode>"
14632 [(set (match_operand:PTR 0 "register_operand" "=r")
14633 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14637 [(set (match_dup 0)
14640 addr_space_t as = DEFAULT_TLS_SEG_REG;
14642 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14643 set_mem_addr_space (operands[1], as);
14646 (define_insn_and_split "*load_tp_x32_zext"
14647 [(set (match_operand:DI 0 "register_operand" "=r")
14649 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14653 [(set (match_dup 0)
14654 (zero_extend:DI (match_dup 1)))]
14656 addr_space_t as = DEFAULT_TLS_SEG_REG;
14658 operands[1] = gen_const_mem (SImode, const0_rtx);
14659 set_mem_addr_space (operands[1], as);
14662 (define_insn_and_split "*add_tp_<mode>"
14663 [(set (match_operand:PTR 0 "register_operand" "=r")
14665 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14666 (match_operand:PTR 1 "register_operand" "0")))
14667 (clobber (reg:CC FLAGS_REG))]
14672 [(set (match_dup 0)
14673 (plus:PTR (match_dup 1) (match_dup 2)))
14674 (clobber (reg:CC FLAGS_REG))])]
14676 addr_space_t as = DEFAULT_TLS_SEG_REG;
14678 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14679 set_mem_addr_space (operands[2], as);
14682 (define_insn_and_split "*add_tp_x32_zext"
14683 [(set (match_operand:DI 0 "register_operand" "=r")
14685 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14686 (match_operand:SI 1 "register_operand" "0"))))
14687 (clobber (reg:CC FLAGS_REG))]
14692 [(set (match_dup 0)
14694 (plus:SI (match_dup 1) (match_dup 2))))
14695 (clobber (reg:CC FLAGS_REG))])]
14697 addr_space_t as = DEFAULT_TLS_SEG_REG;
14699 operands[2] = gen_const_mem (SImode, const0_rtx);
14700 set_mem_addr_space (operands[2], as);
14703 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14704 ;; %rax as destination of the initial executable code sequence.
14705 (define_insn "tls_initial_exec_64_sun"
14706 [(set (match_operand:DI 0 "register_operand" "=a")
14708 [(match_operand 1 "tls_symbolic_operand")]
14709 UNSPEC_TLS_IE_SUN))
14710 (clobber (reg:CC FLAGS_REG))]
14711 "TARGET_64BIT && TARGET_SUN_TLS"
14714 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14715 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14717 [(set_attr "type" "multi")])
14719 ;; GNU2 TLS patterns can be split.
14721 (define_expand "tls_dynamic_gnu2_32"
14722 [(set (match_dup 3)
14723 (plus:SI (match_operand:SI 2 "register_operand")
14725 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14728 [(set (match_operand:SI 0 "register_operand")
14729 (unspec:SI [(match_dup 1) (match_dup 3)
14730 (match_dup 2) (reg:SI SP_REG)]
14732 (clobber (reg:CC FLAGS_REG))])]
14733 "!TARGET_64BIT && TARGET_GNU2_TLS"
14735 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14736 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14739 (define_insn "*tls_dynamic_gnu2_lea_32"
14740 [(set (match_operand:SI 0 "register_operand" "=r")
14741 (plus:SI (match_operand:SI 1 "register_operand" "b")
14743 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14744 UNSPEC_TLSDESC))))]
14745 "!TARGET_64BIT && TARGET_GNU2_TLS"
14746 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14747 [(set_attr "type" "lea")
14748 (set_attr "mode" "SI")
14749 (set_attr "length" "6")
14750 (set_attr "length_address" "4")])
14752 (define_insn "*tls_dynamic_gnu2_call_32"
14753 [(set (match_operand:SI 0 "register_operand" "=a")
14754 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14755 (match_operand:SI 2 "register_operand" "0")
14756 ;; we have to make sure %ebx still points to the GOT
14757 (match_operand:SI 3 "register_operand" "b")
14760 (clobber (reg:CC FLAGS_REG))]
14761 "!TARGET_64BIT && TARGET_GNU2_TLS"
14762 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14763 [(set_attr "type" "call")
14764 (set_attr "length" "2")
14765 (set_attr "length_address" "0")])
14767 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14768 [(set (match_operand:SI 0 "register_operand" "=&a")
14770 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14771 (match_operand:SI 4)
14772 (match_operand:SI 2 "register_operand" "b")
14775 (const:SI (unspec:SI
14776 [(match_operand 1 "tls_symbolic_operand")]
14778 (clobber (reg:CC FLAGS_REG))]
14779 "!TARGET_64BIT && TARGET_GNU2_TLS"
14782 [(set (match_dup 0) (match_dup 5))]
14784 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14785 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14788 (define_expand "tls_dynamic_gnu2_64"
14789 [(set (match_dup 2)
14790 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14793 [(set (match_operand:DI 0 "register_operand")
14794 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14796 (clobber (reg:CC FLAGS_REG))])]
14797 "TARGET_64BIT && TARGET_GNU2_TLS"
14799 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14800 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14803 (define_insn "*tls_dynamic_gnu2_lea_64"
14804 [(set (match_operand:DI 0 "register_operand" "=r")
14805 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14807 "TARGET_64BIT && TARGET_GNU2_TLS"
14808 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14809 [(set_attr "type" "lea")
14810 (set_attr "mode" "DI")
14811 (set_attr "length" "7")
14812 (set_attr "length_address" "4")])
14814 (define_insn "*tls_dynamic_gnu2_call_64"
14815 [(set (match_operand:DI 0 "register_operand" "=a")
14816 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14817 (match_operand:DI 2 "register_operand" "0")
14820 (clobber (reg:CC FLAGS_REG))]
14821 "TARGET_64BIT && TARGET_GNU2_TLS"
14822 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14823 [(set_attr "type" "call")
14824 (set_attr "length" "2")
14825 (set_attr "length_address" "0")])
14827 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14828 [(set (match_operand:DI 0 "register_operand" "=&a")
14830 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14831 (match_operand:DI 3)
14834 (const:DI (unspec:DI
14835 [(match_operand 1 "tls_symbolic_operand")]
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_64BIT && TARGET_GNU2_TLS"
14841 [(set (match_dup 0) (match_dup 4))]
14843 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14844 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14848 [(match_operand 0 "tls_address_pattern")]
14849 "TARGET_TLS_DIRECT_SEG_REFS"
14851 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14854 ;; These patterns match the binary 387 instructions for addM3, subM3,
14855 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14856 ;; SFmode. The first is the normal insn, the second the same insn but
14857 ;; with one operand a conversion, and the third the same insn but with
14858 ;; the other operand a conversion. The conversion may be SFmode or
14859 ;; SImode if the target mode DFmode, but only SImode if the target mode
14862 ;; Gcc is slightly more smart about handling normal two address instructions
14863 ;; so use special patterns for add and mull.
14865 (define_insn "*fop_xf_comm_i387"
14866 [(set (match_operand:XF 0 "register_operand" "=f")
14867 (match_operator:XF 3 "binary_fp_operator"
14868 [(match_operand:XF 1 "register_operand" "%0")
14869 (match_operand:XF 2 "register_operand" "f")]))]
14871 && COMMUTATIVE_ARITH_P (operands[3])"
14872 "* return output_387_binary_op (insn, operands);"
14873 [(set (attr "type")
14874 (if_then_else (match_operand:XF 3 "mult_operator")
14875 (const_string "fmul")
14876 (const_string "fop")))
14877 (set_attr "mode" "XF")])
14879 (define_insn "*fop_<mode>_comm"
14880 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14881 (match_operator:MODEF 3 "binary_fp_operator"
14882 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14883 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14884 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14885 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14886 && COMMUTATIVE_ARITH_P (operands[3])
14887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14888 "* return output_387_binary_op (insn, operands);"
14889 [(set (attr "type")
14890 (if_then_else (eq_attr "alternative" "1,2")
14891 (if_then_else (match_operand:MODEF 3 "mult_operator")
14892 (const_string "ssemul")
14893 (const_string "sseadd"))
14894 (if_then_else (match_operand:MODEF 3 "mult_operator")
14895 (const_string "fmul")
14896 (const_string "fop"))))
14897 (set_attr "isa" "*,noavx,avx")
14898 (set_attr "prefix" "orig,orig,vex")
14899 (set_attr "mode" "<MODE>")
14900 (set (attr "enabled")
14902 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14904 (eq_attr "alternative" "0")
14905 (symbol_ref "TARGET_MIX_SSE_I387
14906 && X87_ENABLE_ARITH (<MODE>mode)")
14907 (const_string "*"))
14909 (eq_attr "alternative" "0")
14910 (symbol_ref "true")
14911 (symbol_ref "false"))))])
14913 (define_insn "*rcpsf2_sse"
14914 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14915 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14917 "TARGET_SSE && TARGET_SSE_MATH"
14919 %vrcpss\t{%d1, %0|%0, %d1}
14920 %vrcpss\t{%d1, %0|%0, %d1}
14921 %vrcpss\t{%1, %d0|%d0, %1}"
14922 [(set_attr "type" "sse")
14923 (set_attr "atom_sse_attr" "rcp")
14924 (set_attr "btver2_sse_attr" "rcp")
14925 (set_attr "prefix" "maybe_vex")
14926 (set_attr "mode" "SF")
14927 (set_attr "avx_partial_xmm_update" "false,false,true")
14928 (set (attr "preferred_for_speed")
14929 (cond [(match_test "TARGET_AVX")
14930 (symbol_ref "true")
14931 (eq_attr "alternative" "1,2")
14932 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14934 (symbol_ref "true")))])
14936 (define_insn "*fop_xf_1_i387"
14937 [(set (match_operand:XF 0 "register_operand" "=f,f")
14938 (match_operator:XF 3 "binary_fp_operator"
14939 [(match_operand:XF 1 "register_operand" "0,f")
14940 (match_operand:XF 2 "register_operand" "f,0")]))]
14942 && !COMMUTATIVE_ARITH_P (operands[3])"
14943 "* return output_387_binary_op (insn, operands);"
14944 [(set (attr "type")
14945 (if_then_else (match_operand:XF 3 "div_operator")
14946 (const_string "fdiv")
14947 (const_string "fop")))
14948 (set_attr "mode" "XF")])
14950 (define_insn "*fop_<mode>_1"
14951 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14952 (match_operator:MODEF 3 "binary_fp_operator"
14953 [(match_operand:MODEF 1
14954 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14955 (match_operand:MODEF 2
14956 "nonimmediate_operand" "fm,0,xm,vm")]))]
14957 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14958 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14959 && !COMMUTATIVE_ARITH_P (operands[3])
14960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14961 "* return output_387_binary_op (insn, operands);"
14962 [(set (attr "type")
14963 (if_then_else (eq_attr "alternative" "2,3")
14964 (if_then_else (match_operand:MODEF 3 "div_operator")
14965 (const_string "ssediv")
14966 (const_string "sseadd"))
14967 (if_then_else (match_operand:MODEF 3 "div_operator")
14968 (const_string "fdiv")
14969 (const_string "fop"))))
14970 (set_attr "isa" "*,*,noavx,avx")
14971 (set_attr "prefix" "orig,orig,orig,vex")
14972 (set_attr "mode" "<MODE>")
14973 (set (attr "enabled")
14975 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14977 (eq_attr "alternative" "0,1")
14978 (symbol_ref "TARGET_MIX_SSE_I387
14979 && X87_ENABLE_ARITH (<MODE>mode)")
14980 (const_string "*"))
14982 (eq_attr "alternative" "0,1")
14983 (symbol_ref "true")
14984 (symbol_ref "false"))))])
14986 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14987 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14988 (match_operator:X87MODEF 3 "binary_fp_operator"
14990 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14991 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14992 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14993 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14994 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14995 || optimize_function_for_size_p (cfun))"
14996 "* return output_387_binary_op (insn, operands);"
14997 [(set (attr "type")
14998 (cond [(match_operand:X87MODEF 3 "mult_operator")
14999 (const_string "fmul")
15000 (match_operand:X87MODEF 3 "div_operator")
15001 (const_string "fdiv")
15003 (const_string "fop")))
15004 (set_attr "fp_int_src" "true")
15005 (set_attr "mode" "<SWI24:MODE>")])
15007 (define_insn "*fop_<X87MODEF:mode>_3_i387"
15008 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15009 (match_operator:X87MODEF 3 "binary_fp_operator"
15010 [(match_operand:X87MODEF 1 "register_operand" "0")
15012 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15013 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15014 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15015 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15016 || optimize_function_for_size_p (cfun))"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set (attr "type")
15019 (cond [(match_operand:X87MODEF 3 "mult_operator")
15020 (const_string "fmul")
15021 (match_operand:X87MODEF 3 "div_operator")
15022 (const_string "fdiv")
15024 (const_string "fop")))
15025 (set_attr "fp_int_src" "true")
15026 (set_attr "mode" "<SWI24:MODE>")])
15028 (define_insn "*fop_xf_4_i387"
15029 [(set (match_operand:XF 0 "register_operand" "=f,f")
15030 (match_operator:XF 3 "binary_fp_operator"
15032 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15033 (match_operand:XF 2 "register_operand" "0,f")]))]
15035 "* return output_387_binary_op (insn, operands);"
15036 [(set (attr "type")
15037 (cond [(match_operand:XF 3 "mult_operator")
15038 (const_string "fmul")
15039 (match_operand:XF 3 "div_operator")
15040 (const_string "fdiv")
15042 (const_string "fop")))
15043 (set_attr "mode" "<MODE>")])
15045 (define_insn "*fop_df_4_i387"
15046 [(set (match_operand:DF 0 "register_operand" "=f,f")
15047 (match_operator:DF 3 "binary_fp_operator"
15049 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15050 (match_operand:DF 2 "register_operand" "0,f")]))]
15051 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15052 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15053 "* return output_387_binary_op (insn, operands);"
15054 [(set (attr "type")
15055 (cond [(match_operand:DF 3 "mult_operator")
15056 (const_string "fmul")
15057 (match_operand:DF 3 "div_operator")
15058 (const_string "fdiv")
15060 (const_string "fop")))
15061 (set_attr "mode" "SF")])
15063 (define_insn "*fop_xf_5_i387"
15064 [(set (match_operand:XF 0 "register_operand" "=f,f")
15065 (match_operator:XF 3 "binary_fp_operator"
15066 [(match_operand:XF 1 "register_operand" "0,f")
15068 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (cond [(match_operand:XF 3 "mult_operator")
15073 (const_string "fmul")
15074 (match_operand:XF 3 "div_operator")
15075 (const_string "fdiv")
15077 (const_string "fop")))
15078 (set_attr "mode" "<MODE>")])
15080 (define_insn "*fop_df_5_i387"
15081 [(set (match_operand:DF 0 "register_operand" "=f,f")
15082 (match_operator:DF 3 "binary_fp_operator"
15083 [(match_operand:DF 1 "register_operand" "0,f")
15085 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15086 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15087 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15088 "* return output_387_binary_op (insn, operands);"
15089 [(set (attr "type")
15090 (cond [(match_operand:DF 3 "mult_operator")
15091 (const_string "fmul")
15092 (match_operand:DF 3 "div_operator")
15093 (const_string "fdiv")
15095 (const_string "fop")))
15096 (set_attr "mode" "SF")])
15098 (define_insn "*fop_xf_6_i387"
15099 [(set (match_operand:XF 0 "register_operand" "=f,f")
15100 (match_operator:XF 3 "binary_fp_operator"
15102 (match_operand:MODEF 1 "register_operand" "0,f"))
15104 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15106 "* return output_387_binary_op (insn, operands);"
15107 [(set (attr "type")
15108 (cond [(match_operand:XF 3 "mult_operator")
15109 (const_string "fmul")
15110 (match_operand:XF 3 "div_operator")
15111 (const_string "fdiv")
15113 (const_string "fop")))
15114 (set_attr "mode" "<MODE>")])
15116 (define_insn "*fop_df_6_i387"
15117 [(set (match_operand:DF 0 "register_operand" "=f,f")
15118 (match_operator:DF 3 "binary_fp_operator"
15120 (match_operand:SF 1 "register_operand" "0,f"))
15122 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15123 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15124 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:DF 3 "mult_operator")
15128 (const_string "fmul")
15129 (match_operand:DF 3 "div_operator")
15130 (const_string "fdiv")
15132 (const_string "fop")))
15133 (set_attr "mode" "SF")])
15135 ;; FPU special functions.
15137 ;; This pattern implements a no-op XFmode truncation for
15138 ;; all fancy i386 XFmode math functions.
15140 (define_insn "truncxf<mode>2_i387_noop_unspec"
15141 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
15142 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15143 UNSPEC_TRUNC_NOOP))]
15144 "TARGET_USE_FANCY_MATH_387"
15145 "* return output_387_reg_move (insn, operands);"
15146 [(set_attr "type" "fmov")
15147 (set_attr "mode" "<MODE>")])
15149 (define_insn "sqrtxf2"
15150 [(set (match_operand:XF 0 "register_operand" "=f")
15151 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15152 "TARGET_USE_FANCY_MATH_387"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "mode" "XF")
15156 (set_attr "athlon_decode" "direct")
15157 (set_attr "amdfam10_decode" "direct")
15158 (set_attr "bdver1_decode" "direct")])
15160 (define_insn "*rsqrtsf2_sse"
15161 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15162 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15164 "TARGET_SSE && TARGET_SSE_MATH"
15166 %vrsqrtss\t{%d1, %0|%0, %d1}
15167 %vrsqrtss\t{%d1, %0|%0, %d1}
15168 %vrsqrtss\t{%1, %d0|%d0, %1}"
15169 [(set_attr "type" "sse")
15170 (set_attr "atom_sse_attr" "rcp")
15171 (set_attr "btver2_sse_attr" "rcp")
15172 (set_attr "prefix" "maybe_vex")
15173 (set_attr "mode" "SF")
15174 (set_attr "avx_partial_xmm_update" "false,false,true")
15175 (set (attr "preferred_for_speed")
15176 (cond [(match_test "TARGET_AVX")
15177 (symbol_ref "true")
15178 (eq_attr "alternative" "1,2")
15179 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15181 (symbol_ref "true")))])
15183 (define_expand "rsqrtsf2"
15184 [(set (match_operand:SF 0 "register_operand")
15185 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15187 "TARGET_SSE && TARGET_SSE_MATH"
15189 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15193 (define_insn "*sqrt<mode>2_sse"
15194 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
15196 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
15197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15199 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15200 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15201 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15202 [(set_attr "type" "sse")
15203 (set_attr "atom_sse_attr" "sqrt")
15204 (set_attr "btver2_sse_attr" "sqrt")
15205 (set_attr "prefix" "maybe_vex")
15206 (set_attr "avx_partial_xmm_update" "false,false,true")
15207 (set_attr "mode" "<MODE>")
15208 (set (attr "preferred_for_speed")
15209 (cond [(match_test "TARGET_AVX")
15210 (symbol_ref "true")
15211 (eq_attr "alternative" "1,2")
15212 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15214 (symbol_ref "true")))])
15216 (define_expand "sqrt<mode>2"
15217 [(set (match_operand:MODEF 0 "register_operand")
15219 (match_operand:MODEF 1 "nonimmediate_operand")))]
15220 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15221 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15223 if (<MODE>mode == SFmode
15224 && TARGET_SSE && TARGET_SSE_MATH
15225 && TARGET_RECIP_SQRT
15226 && !optimize_function_for_size_p (cfun)
15227 && flag_finite_math_only && !flag_trapping_math
15228 && flag_unsafe_math_optimizations)
15230 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15234 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15236 rtx op0 = gen_reg_rtx (XFmode);
15237 rtx op1 = gen_reg_rtx (XFmode);
15239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15240 emit_insn (gen_sqrtxf2 (op0, op1));
15241 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15246 (define_expand "hypot<mode>3"
15247 [(use (match_operand:MODEF 0 "register_operand"))
15248 (use (match_operand:MODEF 1 "general_operand"))
15249 (use (match_operand:MODEF 2 "general_operand"))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15252 || TARGET_MIX_SSE_I387)
15253 && flag_finite_math_only
15254 && flag_unsafe_math_optimizations"
15256 rtx op0 = gen_reg_rtx (XFmode);
15257 rtx op1 = gen_reg_rtx (XFmode);
15258 rtx op2 = gen_reg_rtx (XFmode);
15260 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15263 emit_insn (gen_mulxf3 (op1, op1, op1));
15264 emit_insn (gen_mulxf3 (op2, op2, op2));
15265 emit_insn (gen_addxf3 (op0, op2, op1));
15266 emit_insn (gen_sqrtxf2 (op0, op0));
15268 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15272 (define_insn "x86_fnstsw_1"
15273 [(set (match_operand:HI 0 "register_operand" "=a")
15274 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
15277 [(set_attr "length" "2")
15278 (set_attr "mode" "SI")
15279 (set_attr "unit" "i387")])
15281 (define_insn "fpremxf4_i387"
15282 [(set (match_operand:XF 0 "register_operand" "=f")
15283 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15284 (match_operand:XF 3 "register_operand" "1")]
15286 (set (match_operand:XF 1 "register_operand" "=f")
15287 (unspec:XF [(match_dup 2) (match_dup 3)]
15289 (set (reg:CCFP FPSR_REG)
15290 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15292 "TARGET_USE_FANCY_MATH_387
15293 && flag_finite_math_only"
15295 [(set_attr "type" "fpspc")
15296 (set_attr "znver1_decode" "vector")
15297 (set_attr "mode" "XF")])
15299 (define_expand "fmodxf3"
15300 [(use (match_operand:XF 0 "register_operand"))
15301 (use (match_operand:XF 1 "general_operand"))
15302 (use (match_operand:XF 2 "general_operand"))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && flag_finite_math_only"
15306 rtx_code_label *label = gen_label_rtx ();
15308 rtx op1 = gen_reg_rtx (XFmode);
15309 rtx op2 = gen_reg_rtx (XFmode);
15311 emit_move_insn (op2, operands[2]);
15312 emit_move_insn (op1, operands[1]);
15314 emit_label (label);
15315 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15316 ix86_emit_fp_unordered_jump (label);
15317 LABEL_NUSES (label) = 1;
15319 emit_move_insn (operands[0], op1);
15323 (define_expand "fmod<mode>3"
15324 [(use (match_operand:MODEF 0 "register_operand"))
15325 (use (match_operand:MODEF 1 "general_operand"))
15326 (use (match_operand:MODEF 2 "general_operand"))]
15327 "TARGET_USE_FANCY_MATH_387
15328 && flag_finite_math_only"
15330 rtx (*gen_truncxf) (rtx, rtx);
15332 rtx_code_label *label = gen_label_rtx ();
15334 rtx op1 = gen_reg_rtx (XFmode);
15335 rtx op2 = gen_reg_rtx (XFmode);
15337 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15338 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15340 emit_label (label);
15341 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15342 ix86_emit_fp_unordered_jump (label);
15343 LABEL_NUSES (label) = 1;
15345 /* Truncate the result properly for strict SSE math. */
15346 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15347 && !TARGET_MIX_SSE_I387)
15348 gen_truncxf = gen_truncxf<mode>2;
15350 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15352 emit_insn (gen_truncxf (operands[0], op1));
15356 (define_insn "fprem1xf4_i387"
15357 [(set (match_operand:XF 0 "register_operand" "=f")
15358 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15359 (match_operand:XF 3 "register_operand" "1")]
15361 (set (match_operand:XF 1 "register_operand" "=f")
15362 (unspec:XF [(match_dup 2) (match_dup 3)]
15364 (set (reg:CCFP FPSR_REG)
15365 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15367 "TARGET_USE_FANCY_MATH_387
15368 && flag_finite_math_only"
15370 [(set_attr "type" "fpspc")
15371 (set_attr "znver1_decode" "vector")
15372 (set_attr "mode" "XF")])
15374 (define_expand "remainderxf3"
15375 [(use (match_operand:XF 0 "register_operand"))
15376 (use (match_operand:XF 1 "general_operand"))
15377 (use (match_operand:XF 2 "general_operand"))]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_finite_math_only"
15381 rtx_code_label *label = gen_label_rtx ();
15383 rtx op1 = gen_reg_rtx (XFmode);
15384 rtx op2 = gen_reg_rtx (XFmode);
15386 emit_move_insn (op2, operands[2]);
15387 emit_move_insn (op1, operands[1]);
15389 emit_label (label);
15390 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15391 ix86_emit_fp_unordered_jump (label);
15392 LABEL_NUSES (label) = 1;
15394 emit_move_insn (operands[0], op1);
15398 (define_expand "remainder<mode>3"
15399 [(use (match_operand:MODEF 0 "register_operand"))
15400 (use (match_operand:MODEF 1 "general_operand"))
15401 (use (match_operand:MODEF 2 "general_operand"))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_finite_math_only"
15405 rtx (*gen_truncxf) (rtx, rtx);
15407 rtx_code_label *label = gen_label_rtx ();
15409 rtx op1 = gen_reg_rtx (XFmode);
15410 rtx op2 = gen_reg_rtx (XFmode);
15412 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15413 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15415 emit_label (label);
15417 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15418 ix86_emit_fp_unordered_jump (label);
15419 LABEL_NUSES (label) = 1;
15421 /* Truncate the result properly for strict SSE math. */
15422 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15423 && !TARGET_MIX_SSE_I387)
15424 gen_truncxf = gen_truncxf<mode>2;
15426 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15428 emit_insn (gen_truncxf (operands[0], op1));
15432 (define_int_iterator SINCOS
15436 (define_int_attr sincos
15437 [(UNSPEC_SIN "sin")
15438 (UNSPEC_COS "cos")])
15440 (define_insn "<sincos>xf2"
15441 [(set (match_operand:XF 0 "register_operand" "=f")
15442 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15444 "TARGET_USE_FANCY_MATH_387
15445 && flag_unsafe_math_optimizations"
15447 [(set_attr "type" "fpspc")
15448 (set_attr "znver1_decode" "vector")
15449 (set_attr "mode" "XF")])
15451 (define_expand "<sincos><mode>2"
15452 [(set (match_operand:MODEF 0 "register_operand")
15453 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15455 "TARGET_USE_FANCY_MATH_387
15456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15457 || TARGET_MIX_SSE_I387)
15458 && flag_unsafe_math_optimizations"
15460 rtx op0 = gen_reg_rtx (XFmode);
15461 rtx op1 = gen_reg_rtx (XFmode);
15463 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464 emit_insn (gen_<sincos>xf2 (op0, op1));
15465 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15469 (define_insn "sincosxf3"
15470 [(set (match_operand:XF 0 "register_operand" "=f")
15471 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15472 UNSPEC_SINCOS_COS))
15473 (set (match_operand:XF 1 "register_operand" "=f")
15474 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && flag_unsafe_math_optimizations"
15478 [(set_attr "type" "fpspc")
15479 (set_attr "znver1_decode" "vector")
15480 (set_attr "mode" "XF")])
15482 (define_expand "sincos<mode>3"
15483 [(use (match_operand:MODEF 0 "register_operand"))
15484 (use (match_operand:MODEF 1 "register_operand"))
15485 (use (match_operand:MODEF 2 "general_operand"))]
15486 "TARGET_USE_FANCY_MATH_387
15487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15488 || TARGET_MIX_SSE_I387)
15489 && flag_unsafe_math_optimizations"
15491 rtx op0 = gen_reg_rtx (XFmode);
15492 rtx op1 = gen_reg_rtx (XFmode);
15493 rtx op2 = gen_reg_rtx (XFmode);
15495 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15496 emit_insn (gen_sincosxf3 (op0, op1, op2));
15497 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15498 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15502 (define_insn "fptanxf4_i387"
15503 [(set (match_operand:SF 0 "register_operand" "=f")
15504 (match_operand:SF 3 "const1_operand"))
15505 (set (match_operand:XF 1 "register_operand" "=f")
15506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15508 "TARGET_USE_FANCY_MATH_387
15509 && flag_unsafe_math_optimizations"
15511 [(set_attr "type" "fpspc")
15512 (set_attr "znver1_decode" "vector")
15513 (set_attr "mode" "XF")])
15515 (define_expand "tanxf2"
15516 [(use (match_operand:XF 0 "register_operand"))
15517 (use (match_operand:XF 1 "register_operand"))]
15518 "TARGET_USE_FANCY_MATH_387
15519 && flag_unsafe_math_optimizations"
15521 rtx one = gen_reg_rtx (SFmode);
15522 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15523 CONST1_RTX (SFmode)));
15527 (define_expand "tan<mode>2"
15528 [(use (match_operand:MODEF 0 "register_operand"))
15529 (use (match_operand:MODEF 1 "general_operand"))]
15530 "TARGET_USE_FANCY_MATH_387
15531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15532 || TARGET_MIX_SSE_I387)
15533 && flag_unsafe_math_optimizations"
15535 rtx op0 = gen_reg_rtx (XFmode);
15536 rtx op1 = gen_reg_rtx (XFmode);
15538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15539 emit_insn (gen_tanxf2 (op0, op1));
15540 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15544 (define_insn "atan2xf3"
15545 [(set (match_operand:XF 0 "register_operand" "=f")
15546 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15547 (match_operand:XF 2 "register_operand" "f")]
15549 (clobber (match_scratch:XF 3 "=2"))]
15550 "TARGET_USE_FANCY_MATH_387
15551 && flag_unsafe_math_optimizations"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "znver1_decode" "vector")
15555 (set_attr "mode" "XF")])
15557 (define_expand "atan2<mode>3"
15558 [(use (match_operand:MODEF 0 "register_operand"))
15559 (use (match_operand:MODEF 1 "general_operand"))
15560 (use (match_operand:MODEF 2 "general_operand"))]
15561 "TARGET_USE_FANCY_MATH_387
15562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15563 || TARGET_MIX_SSE_I387)
15564 && flag_unsafe_math_optimizations"
15566 rtx op0 = gen_reg_rtx (XFmode);
15567 rtx op1 = gen_reg_rtx (XFmode);
15568 rtx op2 = gen_reg_rtx (XFmode);
15570 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15571 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15573 emit_insn (gen_atan2xf3 (op0, op2, op1));
15574 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15578 (define_expand "atanxf2"
15579 [(parallel [(set (match_operand:XF 0 "register_operand")
15580 (unspec:XF [(match_dup 2)
15581 (match_operand:XF 1 "register_operand")]
15583 (clobber (match_scratch:XF 3))])]
15584 "TARGET_USE_FANCY_MATH_387
15585 && flag_unsafe_math_optimizations"
15586 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15588 (define_expand "atan<mode>2"
15589 [(use (match_operand:MODEF 0 "register_operand"))
15590 (use (match_operand:MODEF 1 "general_operand"))]
15591 "TARGET_USE_FANCY_MATH_387
15592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15593 || TARGET_MIX_SSE_I387)
15594 && flag_unsafe_math_optimizations"
15596 rtx op0 = gen_reg_rtx (XFmode);
15597 rtx op1 = gen_reg_rtx (XFmode);
15599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15600 emit_insn (gen_atanxf2 (op0, op1));
15601 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15605 (define_expand "asinxf2"
15606 [(set (match_dup 2)
15607 (mult:XF (match_operand:XF 1 "register_operand")
15609 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15610 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15611 (parallel [(set (match_operand:XF 0 "register_operand")
15612 (unspec:XF [(match_dup 5) (match_dup 1)]
15614 (clobber (match_scratch:XF 6))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15620 for (i = 2; i < 6; i++)
15621 operands[i] = gen_reg_rtx (XFmode);
15623 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15626 (define_expand "asin<mode>2"
15627 [(use (match_operand:MODEF 0 "register_operand"))
15628 (use (match_operand:MODEF 1 "general_operand"))]
15629 "TARGET_USE_FANCY_MATH_387
15630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15631 || TARGET_MIX_SSE_I387)
15632 && flag_unsafe_math_optimizations"
15634 rtx op0 = gen_reg_rtx (XFmode);
15635 rtx op1 = gen_reg_rtx (XFmode);
15637 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15638 emit_insn (gen_asinxf2 (op0, op1));
15639 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15643 (define_expand "acosxf2"
15644 [(set (match_dup 2)
15645 (mult:XF (match_operand:XF 1 "register_operand")
15647 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15648 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15649 (parallel [(set (match_operand:XF 0 "register_operand")
15650 (unspec:XF [(match_dup 1) (match_dup 5)]
15652 (clobber (match_scratch:XF 6))])]
15653 "TARGET_USE_FANCY_MATH_387
15654 && flag_unsafe_math_optimizations"
15658 for (i = 2; i < 6; i++)
15659 operands[i] = gen_reg_rtx (XFmode);
15661 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15664 (define_expand "acos<mode>2"
15665 [(use (match_operand:MODEF 0 "register_operand"))
15666 (use (match_operand:MODEF 1 "general_operand"))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15669 || TARGET_MIX_SSE_I387)
15670 && flag_unsafe_math_optimizations"
15672 rtx op0 = gen_reg_rtx (XFmode);
15673 rtx op1 = gen_reg_rtx (XFmode);
15675 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15676 emit_insn (gen_acosxf2 (op0, op1));
15677 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15681 (define_expand "sinhxf2"
15682 [(use (match_operand:XF 0 "register_operand"))
15683 (use (match_operand:XF 1 "register_operand"))]
15684 "TARGET_USE_FANCY_MATH_387
15685 && flag_finite_math_only
15686 && flag_unsafe_math_optimizations"
15688 ix86_emit_i387_sinh (operands[0], operands[1]);
15692 (define_expand "sinh<mode>2"
15693 [(use (match_operand:MODEF 0 "register_operand"))
15694 (use (match_operand:MODEF 1 "general_operand"))]
15695 "TARGET_USE_FANCY_MATH_387
15696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15697 || TARGET_MIX_SSE_I387)
15698 && flag_finite_math_only
15699 && flag_unsafe_math_optimizations"
15701 rtx op0 = gen_reg_rtx (XFmode);
15702 rtx op1 = gen_reg_rtx (XFmode);
15704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15705 emit_insn (gen_sinhxf2 (op0, op1));
15706 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15710 (define_expand "coshxf2"
15711 [(use (match_operand:XF 0 "register_operand"))
15712 (use (match_operand:XF 1 "register_operand"))]
15713 "TARGET_USE_FANCY_MATH_387
15714 && flag_unsafe_math_optimizations"
15716 ix86_emit_i387_cosh (operands[0], operands[1]);
15720 (define_expand "cosh<mode>2"
15721 [(use (match_operand:MODEF 0 "register_operand"))
15722 (use (match_operand:MODEF 1 "general_operand"))]
15723 "TARGET_USE_FANCY_MATH_387
15724 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15725 || TARGET_MIX_SSE_I387)
15726 && flag_unsafe_math_optimizations"
15728 rtx op0 = gen_reg_rtx (XFmode);
15729 rtx op1 = gen_reg_rtx (XFmode);
15731 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15732 emit_insn (gen_coshxf2 (op0, op1));
15733 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15737 (define_expand "tanhxf2"
15738 [(use (match_operand:XF 0 "register_operand"))
15739 (use (match_operand:XF 1 "register_operand"))]
15740 "TARGET_USE_FANCY_MATH_387
15741 && flag_unsafe_math_optimizations"
15743 ix86_emit_i387_tanh (operands[0], operands[1]);
15747 (define_expand "tanh<mode>2"
15748 [(use (match_operand:MODEF 0 "register_operand"))
15749 (use (match_operand:MODEF 1 "general_operand"))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15752 || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15755 rtx op0 = gen_reg_rtx (XFmode);
15756 rtx op1 = gen_reg_rtx (XFmode);
15758 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15759 emit_insn (gen_tanhxf2 (op0, op1));
15760 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15764 (define_expand "asinhxf2"
15765 [(use (match_operand:XF 0 "register_operand"))
15766 (use (match_operand:XF 1 "register_operand"))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && flag_finite_math_only
15769 && flag_unsafe_math_optimizations"
15771 ix86_emit_i387_asinh (operands[0], operands[1]);
15775 (define_expand "asinh<mode>2"
15776 [(use (match_operand:MODEF 0 "register_operand"))
15777 (use (match_operand:MODEF 1 "general_operand"))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15780 || TARGET_MIX_SSE_I387)
15781 && flag_finite_math_only
15782 && flag_unsafe_math_optimizations"
15784 rtx op0 = gen_reg_rtx (XFmode);
15785 rtx op1 = gen_reg_rtx (XFmode);
15787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15788 emit_insn (gen_asinhxf2 (op0, op1));
15789 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15793 (define_expand "acoshxf2"
15794 [(use (match_operand:XF 0 "register_operand"))
15795 (use (match_operand:XF 1 "register_operand"))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && flag_unsafe_math_optimizations"
15799 ix86_emit_i387_acosh (operands[0], operands[1]);
15803 (define_expand "acosh<mode>2"
15804 [(use (match_operand:MODEF 0 "register_operand"))
15805 (use (match_operand:MODEF 1 "general_operand"))]
15806 "TARGET_USE_FANCY_MATH_387
15807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15808 || TARGET_MIX_SSE_I387)
15809 && flag_unsafe_math_optimizations"
15811 rtx op0 = gen_reg_rtx (XFmode);
15812 rtx op1 = gen_reg_rtx (XFmode);
15814 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15815 emit_insn (gen_acoshxf2 (op0, op1));
15816 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15820 (define_expand "atanhxf2"
15821 [(use (match_operand:XF 0 "register_operand"))
15822 (use (match_operand:XF 1 "register_operand"))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && flag_unsafe_math_optimizations"
15826 ix86_emit_i387_atanh (operands[0], operands[1]);
15830 (define_expand "atanh<mode>2"
15831 [(use (match_operand:MODEF 0 "register_operand"))
15832 (use (match_operand:MODEF 1 "general_operand"))]
15833 "TARGET_USE_FANCY_MATH_387
15834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15835 || TARGET_MIX_SSE_I387)
15836 && flag_unsafe_math_optimizations"
15838 rtx op0 = gen_reg_rtx (XFmode);
15839 rtx op1 = gen_reg_rtx (XFmode);
15841 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15842 emit_insn (gen_atanhxf2 (op0, op1));
15843 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15847 (define_insn "fyl2xxf3_i387"
15848 [(set (match_operand:XF 0 "register_operand" "=f")
15849 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15850 (match_operand:XF 2 "register_operand" "f")]
15852 (clobber (match_scratch:XF 3 "=2"))]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15856 [(set_attr "type" "fpspc")
15857 (set_attr "znver1_decode" "vector")
15858 (set_attr "mode" "XF")])
15860 (define_expand "logxf2"
15861 [(parallel [(set (match_operand:XF 0 "register_operand")
15862 (unspec:XF [(match_operand:XF 1 "register_operand")
15863 (match_dup 2)] UNSPEC_FYL2X))
15864 (clobber (match_scratch:XF 3))])]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations"
15869 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15872 (define_expand "log<mode>2"
15873 [(use (match_operand:MODEF 0 "register_operand"))
15874 (use (match_operand:MODEF 1 "general_operand"))]
15875 "TARGET_USE_FANCY_MATH_387
15876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15877 || TARGET_MIX_SSE_I387)
15878 && flag_unsafe_math_optimizations"
15880 rtx op0 = gen_reg_rtx (XFmode);
15881 rtx op1 = gen_reg_rtx (XFmode);
15883 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15884 emit_insn (gen_logxf2 (op0, op1));
15885 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15889 (define_expand "log10xf2"
15890 [(parallel [(set (match_operand:XF 0 "register_operand")
15891 (unspec:XF [(match_operand:XF 1 "register_operand")
15892 (match_dup 2)] UNSPEC_FYL2X))
15893 (clobber (match_scratch:XF 3))])]
15894 "TARGET_USE_FANCY_MATH_387
15895 && flag_unsafe_math_optimizations"
15898 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15901 (define_expand "log10<mode>2"
15902 [(use (match_operand:MODEF 0 "register_operand"))
15903 (use (match_operand:MODEF 1 "general_operand"))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15906 || TARGET_MIX_SSE_I387)
15907 && flag_unsafe_math_optimizations"
15909 rtx op0 = gen_reg_rtx (XFmode);
15910 rtx op1 = gen_reg_rtx (XFmode);
15912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15913 emit_insn (gen_log10xf2 (op0, op1));
15914 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15918 (define_expand "log2xf2"
15919 [(parallel [(set (match_operand:XF 0 "register_operand")
15920 (unspec:XF [(match_operand:XF 1 "register_operand")
15921 (match_dup 2)] UNSPEC_FYL2X))
15922 (clobber (match_scratch:XF 3))])]
15923 "TARGET_USE_FANCY_MATH_387
15924 && flag_unsafe_math_optimizations"
15925 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15927 (define_expand "log2<mode>2"
15928 [(use (match_operand:MODEF 0 "register_operand"))
15929 (use (match_operand:MODEF 1 "general_operand"))]
15930 "TARGET_USE_FANCY_MATH_387
15931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15932 || TARGET_MIX_SSE_I387)
15933 && flag_unsafe_math_optimizations"
15935 rtx op0 = gen_reg_rtx (XFmode);
15936 rtx op1 = gen_reg_rtx (XFmode);
15938 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15939 emit_insn (gen_log2xf2 (op0, op1));
15940 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15944 (define_insn "fyl2xp1xf3_i387"
15945 [(set (match_operand:XF 0 "register_operand" "=f")
15946 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15947 (match_operand:XF 2 "register_operand" "f")]
15949 (clobber (match_scratch:XF 3 "=2"))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && flag_unsafe_math_optimizations"
15953 [(set_attr "type" "fpspc")
15954 (set_attr "znver1_decode" "vector")
15955 (set_attr "mode" "XF")])
15957 (define_expand "log1pxf2"
15958 [(use (match_operand:XF 0 "register_operand"))
15959 (use (match_operand:XF 1 "register_operand"))]
15960 "TARGET_USE_FANCY_MATH_387
15961 && flag_unsafe_math_optimizations"
15963 ix86_emit_i387_log1p (operands[0], operands[1]);
15967 (define_expand "log1p<mode>2"
15968 [(use (match_operand:MODEF 0 "register_operand"))
15969 (use (match_operand:MODEF 1 "general_operand"))]
15970 "TARGET_USE_FANCY_MATH_387
15971 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15972 || TARGET_MIX_SSE_I387)
15973 && flag_unsafe_math_optimizations"
15975 rtx op0 = gen_reg_rtx (XFmode);
15976 rtx op1 = gen_reg_rtx (XFmode);
15978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15979 emit_insn (gen_log1pxf2 (op0, op1));
15980 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15984 (define_insn "fxtractxf3_i387"
15985 [(set (match_operand:XF 0 "register_operand" "=f")
15986 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15987 UNSPEC_XTRACT_FRACT))
15988 (set (match_operand:XF 1 "register_operand" "=f")
15989 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15990 "TARGET_USE_FANCY_MATH_387
15991 && flag_unsafe_math_optimizations"
15993 [(set_attr "type" "fpspc")
15994 (set_attr "znver1_decode" "vector")
15995 (set_attr "mode" "XF")])
15997 (define_expand "logbxf2"
15998 [(parallel [(set (match_dup 2)
15999 (unspec:XF [(match_operand:XF 1 "register_operand")]
16000 UNSPEC_XTRACT_FRACT))
16001 (set (match_operand:XF 0 "register_operand")
16002 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16003 "TARGET_USE_FANCY_MATH_387
16004 && flag_unsafe_math_optimizations"
16005 "operands[2] = gen_reg_rtx (XFmode);")
16007 (define_expand "logb<mode>2"
16008 [(use (match_operand:MODEF 0 "register_operand"))
16009 (use (match_operand:MODEF 1 "general_operand"))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16012 || TARGET_MIX_SSE_I387)
16013 && flag_unsafe_math_optimizations"
16015 rtx op0 = gen_reg_rtx (XFmode);
16016 rtx op1 = gen_reg_rtx (XFmode);
16018 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16019 emit_insn (gen_logbxf2 (op0, op1));
16020 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16024 (define_expand "ilogbxf2"
16025 [(use (match_operand:SI 0 "register_operand"))
16026 (use (match_operand:XF 1 "register_operand"))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && flag_unsafe_math_optimizations"
16032 if (optimize_insn_for_size_p ())
16035 op0 = gen_reg_rtx (XFmode);
16036 op1 = gen_reg_rtx (XFmode);
16038 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16039 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16043 (define_expand "ilogb<mode>2"
16044 [(use (match_operand:SI 0 "register_operand"))
16045 (use (match_operand:MODEF 1 "general_operand"))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16048 || TARGET_MIX_SSE_I387)
16049 && flag_unsafe_math_optimizations"
16053 if (optimize_insn_for_size_p ())
16056 op0 = gen_reg_rtx (XFmode);
16057 op1 = gen_reg_rtx (XFmode);
16058 op2 = gen_reg_rtx (XFmode);
16060 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
16061 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
16062 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16066 (define_insn "*f2xm1xf2_i387"
16067 [(set (match_operand:XF 0 "register_operand" "=f")
16068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16070 "TARGET_USE_FANCY_MATH_387
16071 && flag_unsafe_math_optimizations"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "znver1_decode" "vector")
16075 (set_attr "mode" "XF")])
16077 (define_insn "fscalexf4_i387"
16078 [(set (match_operand:XF 0 "register_operand" "=f")
16079 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16080 (match_operand:XF 3 "register_operand" "1")]
16081 UNSPEC_FSCALE_FRACT))
16082 (set (match_operand:XF 1 "register_operand" "=f")
16083 (unspec:XF [(match_dup 2) (match_dup 3)]
16084 UNSPEC_FSCALE_EXP))]
16085 "TARGET_USE_FANCY_MATH_387
16086 && flag_unsafe_math_optimizations"
16088 [(set_attr "type" "fpspc")
16089 (set_attr "znver1_decode" "vector")
16090 (set_attr "mode" "XF")])
16092 (define_expand "expNcorexf3"
16093 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16094 (match_operand:XF 2 "register_operand")))
16095 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16096 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16097 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16098 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16099 (parallel [(set (match_operand:XF 0 "register_operand")
16100 (unspec:XF [(match_dup 8) (match_dup 4)]
16101 UNSPEC_FSCALE_FRACT))
16103 (unspec:XF [(match_dup 8) (match_dup 4)]
16104 UNSPEC_FSCALE_EXP))])]
16105 "TARGET_USE_FANCY_MATH_387
16106 && flag_unsafe_math_optimizations"
16110 for (i = 3; i < 10; i++)
16111 operands[i] = gen_reg_rtx (XFmode);
16113 emit_move_insn (operands[7], CONST1_RTX (XFmode));
16116 (define_expand "expxf2"
16117 [(use (match_operand:XF 0 "register_operand"))
16118 (use (match_operand:XF 1 "register_operand"))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && flag_unsafe_math_optimizations"
16122 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
16124 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16128 (define_expand "exp<mode>2"
16129 [(use (match_operand:MODEF 0 "register_operand"))
16130 (use (match_operand:MODEF 1 "general_operand"))]
16131 "TARGET_USE_FANCY_MATH_387
16132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16133 || TARGET_MIX_SSE_I387)
16134 && flag_unsafe_math_optimizations"
16136 rtx op0 = gen_reg_rtx (XFmode);
16137 rtx op1 = gen_reg_rtx (XFmode);
16139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16140 emit_insn (gen_expxf2 (op0, op1));
16141 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16145 (define_expand "exp10xf2"
16146 [(use (match_operand:XF 0 "register_operand"))
16147 (use (match_operand:XF 1 "register_operand"))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && flag_unsafe_math_optimizations"
16151 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
16153 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16157 (define_expand "exp10<mode>2"
16158 [(use (match_operand:MODEF 0 "register_operand"))
16159 (use (match_operand:MODEF 1 "general_operand"))]
16160 "TARGET_USE_FANCY_MATH_387
16161 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16162 || TARGET_MIX_SSE_I387)
16163 && flag_unsafe_math_optimizations"
16165 rtx op0 = gen_reg_rtx (XFmode);
16166 rtx op1 = gen_reg_rtx (XFmode);
16168 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16169 emit_insn (gen_exp10xf2 (op0, op1));
16170 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16174 (define_expand "exp2xf2"
16175 [(use (match_operand:XF 0 "register_operand"))
16176 (use (match_operand:XF 1 "register_operand"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && flag_unsafe_math_optimizations"
16180 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
16182 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16186 (define_expand "exp2<mode>2"
16187 [(use (match_operand:MODEF 0 "register_operand"))
16188 (use (match_operand:MODEF 1 "general_operand"))]
16189 "TARGET_USE_FANCY_MATH_387
16190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16191 || TARGET_MIX_SSE_I387)
16192 && flag_unsafe_math_optimizations"
16194 rtx op0 = gen_reg_rtx (XFmode);
16195 rtx op1 = gen_reg_rtx (XFmode);
16197 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16198 emit_insn (gen_exp2xf2 (op0, op1));
16199 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16203 (define_expand "expm1xf2"
16204 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16206 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16207 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16208 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16209 (parallel [(set (match_dup 7)
16210 (unspec:XF [(match_dup 6) (match_dup 4)]
16211 UNSPEC_FSCALE_FRACT))
16213 (unspec:XF [(match_dup 6) (match_dup 4)]
16214 UNSPEC_FSCALE_EXP))])
16215 (parallel [(set (match_dup 10)
16216 (unspec:XF [(match_dup 9) (match_dup 8)]
16217 UNSPEC_FSCALE_FRACT))
16218 (set (match_dup 11)
16219 (unspec:XF [(match_dup 9) (match_dup 8)]
16220 UNSPEC_FSCALE_EXP))])
16221 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16222 (set (match_operand:XF 0 "register_operand")
16223 (plus:XF (match_dup 12) (match_dup 7)))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16229 for (i = 2; i < 13; i++)
16230 operands[i] = gen_reg_rtx (XFmode);
16232 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16233 emit_move_insn (operands[9], CONST1_RTX (XFmode));
16236 (define_expand "expm1<mode>2"
16237 [(use (match_operand:MODEF 0 "register_operand"))
16238 (use (match_operand:MODEF 1 "general_operand"))]
16239 "TARGET_USE_FANCY_MATH_387
16240 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16241 || TARGET_MIX_SSE_I387)
16242 && flag_unsafe_math_optimizations"
16244 rtx op0 = gen_reg_rtx (XFmode);
16245 rtx op1 = gen_reg_rtx (XFmode);
16247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16248 emit_insn (gen_expm1xf2 (op0, op1));
16249 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16253 (define_expand "ldexpxf3"
16254 [(match_operand:XF 0 "register_operand")
16255 (match_operand:XF 1 "register_operand")
16256 (match_operand:SI 2 "register_operand")]
16257 "TARGET_USE_FANCY_MATH_387
16258 && flag_unsafe_math_optimizations"
16260 rtx tmp1 = gen_reg_rtx (XFmode);
16261 rtx tmp2 = gen_reg_rtx (XFmode);
16263 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16264 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16265 operands[1], tmp1));
16269 (define_expand "ldexp<mode>3"
16270 [(use (match_operand:MODEF 0 "register_operand"))
16271 (use (match_operand:MODEF 1 "general_operand"))
16272 (use (match_operand:SI 2 "register_operand"))]
16273 "TARGET_USE_FANCY_MATH_387
16274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16275 || TARGET_MIX_SSE_I387)
16276 && flag_unsafe_math_optimizations"
16278 rtx op0 = gen_reg_rtx (XFmode);
16279 rtx op1 = gen_reg_rtx (XFmode);
16281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16282 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16283 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16287 (define_expand "scalbxf3"
16288 [(parallel [(set (match_operand:XF 0 " register_operand")
16289 (unspec:XF [(match_operand:XF 1 "register_operand")
16290 (match_operand:XF 2 "register_operand")]
16291 UNSPEC_FSCALE_FRACT))
16293 (unspec:XF [(match_dup 1) (match_dup 2)]
16294 UNSPEC_FSCALE_EXP))])]
16295 "TARGET_USE_FANCY_MATH_387
16296 && flag_unsafe_math_optimizations"
16297 "operands[3] = gen_reg_rtx (XFmode);")
16299 (define_expand "scalb<mode>3"
16300 [(use (match_operand:MODEF 0 "register_operand"))
16301 (use (match_operand:MODEF 1 "general_operand"))
16302 (use (match_operand:MODEF 2 "general_operand"))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16305 || TARGET_MIX_SSE_I387)
16306 && flag_unsafe_math_optimizations"
16308 rtx op0 = gen_reg_rtx (XFmode);
16309 rtx op1 = gen_reg_rtx (XFmode);
16310 rtx op2 = gen_reg_rtx (XFmode);
16312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16313 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16314 emit_insn (gen_scalbxf3 (op0, op1, op2));
16315 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16319 (define_expand "significandxf2"
16320 [(parallel [(set (match_operand:XF 0 "register_operand")
16321 (unspec:XF [(match_operand:XF 1 "register_operand")]
16322 UNSPEC_XTRACT_FRACT))
16324 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16325 "TARGET_USE_FANCY_MATH_387
16326 && flag_unsafe_math_optimizations"
16327 "operands[2] = gen_reg_rtx (XFmode);")
16329 (define_expand "significand<mode>2"
16330 [(use (match_operand:MODEF 0 "register_operand"))
16331 (use (match_operand:MODEF 1 "general_operand"))]
16332 "TARGET_USE_FANCY_MATH_387
16333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16334 || TARGET_MIX_SSE_I387)
16335 && flag_unsafe_math_optimizations"
16337 rtx op0 = gen_reg_rtx (XFmode);
16338 rtx op1 = gen_reg_rtx (XFmode);
16340 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16341 emit_insn (gen_significandxf2 (op0, op1));
16342 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16347 (define_insn "sse4_1_round<mode>2"
16348 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
16350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
16351 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
16355 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16356 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16357 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16358 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16359 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16360 [(set_attr "type" "ssecvt")
16361 (set_attr "prefix_extra" "1,1,1,*,*")
16362 (set_attr "length_immediate" "*,*,*,1,1")
16363 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
16364 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
16365 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
16366 (set_attr "mode" "<MODE>")
16367 (set (attr "preferred_for_speed")
16368 (cond [(match_test "TARGET_AVX")
16369 (symbol_ref "true")
16370 (eq_attr "alternative" "1,2")
16371 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16373 (symbol_ref "true")))])
16375 (define_insn "rintxf2"
16376 [(set (match_operand:XF 0 "register_operand" "=f")
16377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16379 "TARGET_USE_FANCY_MATH_387"
16381 [(set_attr "type" "fpspc")
16382 (set_attr "znver1_decode" "vector")
16383 (set_attr "mode" "XF")])
16385 (define_expand "rint<mode>2"
16386 [(use (match_operand:MODEF 0 "register_operand"))
16387 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16388 "TARGET_USE_FANCY_MATH_387
16389 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16391 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16394 emit_insn (gen_sse4_1_round<mode>2
16395 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16397 ix86_expand_rint (operands[0], operands[1]);
16401 rtx op0 = gen_reg_rtx (XFmode);
16402 rtx op1 = gen_reg_rtx (XFmode);
16404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16405 emit_insn (gen_rintxf2 (op0, op1));
16406 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16411 (define_expand "nearbyintxf2"
16412 [(set (match_operand:XF 0 "register_operand")
16413 (unspec:XF [(match_operand:XF 1 "register_operand")]
16415 "TARGET_USE_FANCY_MATH_387
16416 && !flag_trapping_math")
16418 (define_expand "nearbyint<mode>2"
16419 [(use (match_operand:MODEF 0 "register_operand"))
16420 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16421 "(TARGET_USE_FANCY_MATH_387
16422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423 || TARGET_MIX_SSE_I387)
16424 && !flag_trapping_math)
16425 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16427 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16428 emit_insn (gen_sse4_1_round<mode>2
16429 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16433 rtx op0 = gen_reg_rtx (XFmode);
16434 rtx op1 = gen_reg_rtx (XFmode);
16436 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16437 emit_insn (gen_nearbyintxf2 (op0, op1));
16438 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16443 (define_expand "round<mode>2"
16444 [(match_operand:X87MODEF 0 "register_operand")
16445 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16446 "(TARGET_USE_FANCY_MATH_387
16447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16448 || TARGET_MIX_SSE_I387)
16449 && flag_unsafe_math_optimizations
16450 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16451 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16452 && !flag_trapping_math && !flag_rounding_math)"
16454 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16455 && !flag_trapping_math && !flag_rounding_math)
16459 operands[1] = force_reg (<MODE>mode, operands[1]);
16460 ix86_expand_round_sse4 (operands[0], operands[1]);
16462 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16463 ix86_expand_round (operands[0], operands[1]);
16465 ix86_expand_rounddf_32 (operands[0], operands[1]);
16469 operands[1] = force_reg (<MODE>mode, operands[1]);
16470 ix86_emit_i387_round (operands[0], operands[1]);
16475 (define_insn "lrintxfdi2"
16476 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16477 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16479 (clobber (match_scratch:XF 2 "=&f"))]
16480 "TARGET_USE_FANCY_MATH_387"
16481 "* return output_fix_trunc (insn, operands, false);"
16482 [(set_attr "type" "fpspc")
16483 (set_attr "mode" "DI")])
16485 (define_insn "lrintxf<mode>2"
16486 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16487 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16489 "TARGET_USE_FANCY_MATH_387"
16490 "* return output_fix_trunc (insn, operands, false);"
16491 [(set_attr "type" "fpspc")
16492 (set_attr "mode" "<MODE>")])
16494 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16495 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16496 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16497 UNSPEC_FIX_NOTRUNC))]
16498 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16500 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16501 [(match_operand:SWI248x 0 "nonimmediate_operand")
16502 (match_operand:X87MODEF 1 "register_operand")]
16503 "(TARGET_USE_FANCY_MATH_387
16504 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16505 || TARGET_MIX_SSE_I387)
16506 && flag_unsafe_math_optimizations)
16507 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16508 && <SWI248x:MODE>mode != HImode
16509 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16510 && !flag_trapping_math && !flag_rounding_math)"
16512 if (optimize_insn_for_size_p ())
16515 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16516 && <SWI248x:MODE>mode != HImode
16517 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16518 && !flag_trapping_math && !flag_rounding_math)
16519 ix86_expand_lround (operands[0], operands[1]);
16521 ix86_emit_i387_round (operands[0], operands[1]);
16525 (define_int_iterator FRNDINT_ROUNDING
16526 [UNSPEC_FRNDINT_ROUNDEVEN
16527 UNSPEC_FRNDINT_FLOOR
16528 UNSPEC_FRNDINT_CEIL
16529 UNSPEC_FRNDINT_TRUNC])
16531 (define_int_iterator FIST_ROUNDING
16535 ;; Base name for define_insn
16536 (define_int_attr rounding_insn
16537 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16538 (UNSPEC_FRNDINT_FLOOR "floor")
16539 (UNSPEC_FRNDINT_CEIL "ceil")
16540 (UNSPEC_FRNDINT_TRUNC "btrunc")
16541 (UNSPEC_FIST_FLOOR "floor")
16542 (UNSPEC_FIST_CEIL "ceil")])
16544 (define_int_attr rounding
16545 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16546 (UNSPEC_FRNDINT_FLOOR "floor")
16547 (UNSPEC_FRNDINT_CEIL "ceil")
16548 (UNSPEC_FRNDINT_TRUNC "trunc")
16549 (UNSPEC_FIST_FLOOR "floor")
16550 (UNSPEC_FIST_CEIL "ceil")])
16552 (define_int_attr ROUNDING
16553 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
16554 (UNSPEC_FRNDINT_FLOOR "FLOOR")
16555 (UNSPEC_FRNDINT_CEIL "CEIL")
16556 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16557 (UNSPEC_FIST_FLOOR "FLOOR")
16558 (UNSPEC_FIST_CEIL "CEIL")])
16560 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16561 (define_insn_and_split "frndintxf2_<rounding>"
16562 [(set (match_operand:XF 0 "register_operand")
16563 (unspec:XF [(match_operand:XF 1 "register_operand")]
16565 (clobber (reg:CC FLAGS_REG))]
16566 "TARGET_USE_FANCY_MATH_387
16567 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16568 && ix86_pre_reload_split ()"
16573 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16578 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16579 operands[2], operands[3]));
16582 [(set_attr "type" "frndint")
16583 (set_attr "i387_cw" "<rounding>")
16584 (set_attr "mode" "XF")])
16586 (define_insn "frndintxf2_<rounding>_i387"
16587 [(set (match_operand:XF 0 "register_operand" "=f")
16588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16590 (use (match_operand:HI 2 "memory_operand" "m"))
16591 (use (match_operand:HI 3 "memory_operand" "m"))]
16592 "TARGET_USE_FANCY_MATH_387
16593 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16594 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16595 [(set_attr "type" "frndint")
16596 (set_attr "i387_cw" "<rounding>")
16597 (set_attr "mode" "XF")])
16599 (define_expand "<rounding_insn>xf2"
16600 [(parallel [(set (match_operand:XF 0 "register_operand")
16601 (unspec:XF [(match_operand:XF 1 "register_operand")]
16603 (clobber (reg:CC FLAGS_REG))])]
16604 "TARGET_USE_FANCY_MATH_387
16605 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16607 (define_expand "<rounding_insn><mode>2"
16608 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16609 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16611 (clobber (reg:CC FLAGS_REG))])]
16612 "(TARGET_USE_FANCY_MATH_387
16613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16614 || TARGET_MIX_SSE_I387)
16615 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16618 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
16619 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
16621 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16622 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16625 emit_insn (gen_sse4_1_round<mode>2
16626 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16628 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16630 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16631 ix86_expand_floorceil (operands[0], operands[1], true);
16632 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16633 ix86_expand_floorceil (operands[0], operands[1], false);
16634 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16635 ix86_expand_trunc (operands[0], operands[1]);
16637 gcc_unreachable ();
16641 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16642 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16643 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16644 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16645 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16646 ix86_expand_truncdf_32 (operands[0], operands[1]);
16648 gcc_unreachable ();
16653 rtx op0 = gen_reg_rtx (XFmode);
16654 rtx op1 = gen_reg_rtx (XFmode);
16656 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16657 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16658 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16663 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16664 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16665 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16666 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16668 (clobber (reg:CC FLAGS_REG))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && flag_unsafe_math_optimizations
16671 && ix86_pre_reload_split ()"
16676 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16678 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16679 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16681 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16682 operands[2], operands[3]));
16685 [(set_attr "type" "fistp")
16686 (set_attr "i387_cw" "<rounding>")
16687 (set_attr "mode" "<MODE>")])
16689 (define_insn "fistdi2_<rounding>"
16690 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16691 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16693 (use (match_operand:HI 2 "memory_operand" "m"))
16694 (use (match_operand:HI 3 "memory_operand" "m"))
16695 (clobber (match_scratch:XF 4 "=&f"))]
16696 "TARGET_USE_FANCY_MATH_387
16697 && flag_unsafe_math_optimizations"
16698 "* return output_fix_trunc (insn, operands, false);"
16699 [(set_attr "type" "fistp")
16700 (set_attr "i387_cw" "<rounding>")
16701 (set_attr "mode" "DI")])
16703 (define_insn "fist<mode>2_<rounding>"
16704 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16705 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16707 (use (match_operand:HI 2 "memory_operand" "m"))
16708 (use (match_operand:HI 3 "memory_operand" "m"))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations"
16711 "* return output_fix_trunc (insn, operands, false);"
16712 [(set_attr "type" "fistp")
16713 (set_attr "i387_cw" "<rounding>")
16714 (set_attr "mode" "<MODE>")])
16716 (define_expand "l<rounding_insn>xf<mode>2"
16717 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16718 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16720 (clobber (reg:CC FLAGS_REG))])]
16721 "TARGET_USE_FANCY_MATH_387
16722 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16723 && flag_unsafe_math_optimizations")
16725 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16726 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16727 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16729 (clobber (reg:CC FLAGS_REG))])]
16730 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16731 && (TARGET_SSE4_1 || !flag_trapping_math)"
16735 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16737 emit_insn (gen_sse4_1_round<MODEF:mode>2
16738 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16740 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16741 (operands[0], tmp));
16743 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16744 ix86_expand_lfloorceil (operands[0], operands[1], true);
16745 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16746 ix86_expand_lfloorceil (operands[0], operands[1], false);
16748 gcc_unreachable ();
16753 (define_insn "fxam<mode>2_i387"
16754 [(set (match_operand:HI 0 "register_operand" "=a")
16756 [(match_operand:X87MODEF 1 "register_operand" "f")]
16758 "TARGET_USE_FANCY_MATH_387"
16759 "fxam\n\tfnstsw\t%0"
16760 [(set_attr "type" "multi")
16761 (set_attr "length" "4")
16762 (set_attr "unit" "i387")
16763 (set_attr "mode" "<MODE>")])
16765 (define_expand "signbittf2"
16766 [(use (match_operand:SI 0 "register_operand"))
16767 (use (match_operand:TF 1 "register_operand"))]
16772 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16773 rtx scratch = gen_reg_rtx (QImode);
16775 emit_insn (gen_ptesttf2 (operands[1], mask));
16776 ix86_expand_setcc (scratch, NE,
16777 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16779 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16783 emit_insn (gen_sse_movmskps (operands[0],
16784 gen_lowpart (V4SFmode, operands[1])));
16785 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16790 (define_expand "signbitxf2"
16791 [(use (match_operand:SI 0 "register_operand"))
16792 (use (match_operand:XF 1 "register_operand"))]
16793 "TARGET_USE_FANCY_MATH_387"
16795 rtx scratch = gen_reg_rtx (HImode);
16797 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16798 emit_insn (gen_andsi3 (operands[0],
16799 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16803 (define_insn "movmsk_df"
16804 [(set (match_operand:SI 0 "register_operand" "=r")
16806 [(match_operand:DF 1 "register_operand" "x")]
16808 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16809 "%vmovmskpd\t{%1, %0|%0, %1}"
16810 [(set_attr "type" "ssemov")
16811 (set_attr "prefix" "maybe_vex")
16812 (set_attr "mode" "DF")])
16814 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16815 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16816 (define_expand "signbitdf2"
16817 [(use (match_operand:SI 0 "register_operand"))
16818 (use (match_operand:DF 1 "register_operand"))]
16819 "TARGET_USE_FANCY_MATH_387
16820 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16822 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16824 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16825 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16829 rtx scratch = gen_reg_rtx (HImode);
16831 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16832 emit_insn (gen_andsi3 (operands[0],
16833 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16838 (define_expand "signbitsf2"
16839 [(use (match_operand:SI 0 "register_operand"))
16840 (use (match_operand:SF 1 "register_operand"))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16844 rtx scratch = gen_reg_rtx (HImode);
16846 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16847 emit_insn (gen_andsi3 (operands[0],
16848 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16852 ;; Block operation instructions
16855 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16858 [(set_attr "length" "1")
16859 (set_attr "length_immediate" "0")
16860 (set_attr "modrm" "0")])
16862 (define_expand "cpymem<mode>"
16863 [(use (match_operand:BLK 0 "memory_operand"))
16864 (use (match_operand:BLK 1 "memory_operand"))
16865 (use (match_operand:SWI48 2 "nonmemory_operand"))
16866 (use (match_operand:SWI48 3 "const_int_operand"))
16867 (use (match_operand:SI 4 "const_int_operand"))
16868 (use (match_operand:SI 5 "const_int_operand"))
16869 (use (match_operand:SI 6 ""))
16870 (use (match_operand:SI 7 ""))
16871 (use (match_operand:SI 8 ""))]
16874 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
16875 operands[2], NULL, operands[3],
16876 operands[4], operands[5],
16877 operands[6], operands[7],
16878 operands[8], false))
16884 ;; Most CPUs don't like single string operations
16885 ;; Handle this case here to simplify previous expander.
16887 (define_expand "strmov"
16888 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16889 (set (match_operand 1 "memory_operand") (match_dup 4))
16890 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16891 (clobber (reg:CC FLAGS_REG))])
16892 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16893 (clobber (reg:CC FLAGS_REG))])]
16896 /* Can't use this for non-default address spaces. */
16897 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16900 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16902 /* If .md ever supports :P for Pmode, these can be directly
16903 in the pattern above. */
16904 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16905 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16907 /* Can't use this if the user has appropriated esi or edi. */
16908 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16909 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16911 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16912 operands[2], operands[3],
16913 operands[5], operands[6]));
16917 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16920 (define_expand "strmov_singleop"
16921 [(parallel [(set (match_operand 1 "memory_operand")
16922 (match_operand 3 "memory_operand"))
16923 (set (match_operand 0 "register_operand")
16925 (set (match_operand 2 "register_operand")
16926 (match_operand 5))])]
16930 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16933 (define_insn "*strmovdi_rex_1"
16934 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16935 (mem:DI (match_operand:P 3 "register_operand" "1")))
16936 (set (match_operand:P 0 "register_operand" "=D")
16937 (plus:P (match_dup 2)
16939 (set (match_operand:P 1 "register_operand" "=S")
16940 (plus:P (match_dup 3)
16943 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16944 && ix86_check_no_addr_space (insn)"
16946 [(set_attr "type" "str")
16947 (set_attr "memory" "both")
16948 (set_attr "mode" "DI")])
16950 (define_insn "*strmovsi_1"
16951 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16952 (mem:SI (match_operand:P 3 "register_operand" "1")))
16953 (set (match_operand:P 0 "register_operand" "=D")
16954 (plus:P (match_dup 2)
16956 (set (match_operand:P 1 "register_operand" "=S")
16957 (plus:P (match_dup 3)
16959 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16960 && ix86_check_no_addr_space (insn)"
16962 [(set_attr "type" "str")
16963 (set_attr "memory" "both")
16964 (set_attr "mode" "SI")])
16966 (define_insn "*strmovhi_1"
16967 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16968 (mem:HI (match_operand:P 3 "register_operand" "1")))
16969 (set (match_operand:P 0 "register_operand" "=D")
16970 (plus:P (match_dup 2)
16972 (set (match_operand:P 1 "register_operand" "=S")
16973 (plus:P (match_dup 3)
16975 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16976 && ix86_check_no_addr_space (insn)"
16978 [(set_attr "type" "str")
16979 (set_attr "memory" "both")
16980 (set_attr "mode" "HI")])
16982 (define_insn "*strmovqi_1"
16983 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16984 (mem:QI (match_operand:P 3 "register_operand" "1")))
16985 (set (match_operand:P 0 "register_operand" "=D")
16986 (plus:P (match_dup 2)
16988 (set (match_operand:P 1 "register_operand" "=S")
16989 (plus:P (match_dup 3)
16991 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16992 && ix86_check_no_addr_space (insn)"
16994 [(set_attr "type" "str")
16995 (set_attr "memory" "both")
16996 (set (attr "prefix_rex")
16998 (match_test "<P:MODE>mode == DImode")
17000 (const_string "*")))
17001 (set_attr "mode" "QI")])
17003 (define_expand "rep_mov"
17004 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17005 (set (match_operand 0 "register_operand")
17007 (set (match_operand 2 "register_operand")
17009 (set (match_operand 1 "memory_operand")
17010 (match_operand 3 "memory_operand"))
17011 (use (match_dup 4))])]
17015 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17018 (define_insn "*rep_movdi_rex64"
17019 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17020 (set (match_operand:P 0 "register_operand" "=D")
17021 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17023 (match_operand:P 3 "register_operand" "0")))
17024 (set (match_operand:P 1 "register_operand" "=S")
17025 (plus:P (ashift:P (match_dup 5) (const_int 3))
17026 (match_operand:P 4 "register_operand" "1")))
17027 (set (mem:BLK (match_dup 3))
17028 (mem:BLK (match_dup 4)))
17029 (use (match_dup 5))]
17031 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17032 && ix86_check_no_addr_space (insn)"
17034 [(set_attr "type" "str")
17035 (set_attr "prefix_rep" "1")
17036 (set_attr "memory" "both")
17037 (set_attr "mode" "DI")])
17039 (define_insn "*rep_movsi"
17040 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17041 (set (match_operand:P 0 "register_operand" "=D")
17042 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17044 (match_operand:P 3 "register_operand" "0")))
17045 (set (match_operand:P 1 "register_operand" "=S")
17046 (plus:P (ashift:P (match_dup 5) (const_int 2))
17047 (match_operand:P 4 "register_operand" "1")))
17048 (set (mem:BLK (match_dup 3))
17049 (mem:BLK (match_dup 4)))
17050 (use (match_dup 5))]
17051 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17052 && ix86_check_no_addr_space (insn)"
17053 "%^rep{%;} movs{l|d}"
17054 [(set_attr "type" "str")
17055 (set_attr "prefix_rep" "1")
17056 (set_attr "memory" "both")
17057 (set_attr "mode" "SI")])
17059 (define_insn "*rep_movqi"
17060 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17061 (set (match_operand:P 0 "register_operand" "=D")
17062 (plus:P (match_operand:P 3 "register_operand" "0")
17063 (match_operand:P 5 "register_operand" "2")))
17064 (set (match_operand:P 1 "register_operand" "=S")
17065 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17066 (set (mem:BLK (match_dup 3))
17067 (mem:BLK (match_dup 4)))
17068 (use (match_dup 5))]
17069 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17070 && ix86_check_no_addr_space (insn)"
17072 [(set_attr "type" "str")
17073 (set_attr "prefix_rep" "1")
17074 (set_attr "memory" "both")
17075 (set_attr "mode" "QI")])
17077 (define_expand "setmem<mode>"
17078 [(use (match_operand:BLK 0 "memory_operand"))
17079 (use (match_operand:SWI48 1 "nonmemory_operand"))
17080 (use (match_operand:QI 2 "nonmemory_operand"))
17081 (use (match_operand 3 "const_int_operand"))
17082 (use (match_operand:SI 4 "const_int_operand"))
17083 (use (match_operand:SI 5 "const_int_operand"))
17084 (use (match_operand:SI 6 ""))
17085 (use (match_operand:SI 7 ""))
17086 (use (match_operand:SI 8 ""))]
17089 if (ix86_expand_set_or_cpymem (operands[0], NULL,
17090 operands[1], operands[2],
17091 operands[3], operands[4],
17092 operands[5], operands[6],
17093 operands[7], operands[8], true))
17099 ;; Most CPUs don't like single string operations
17100 ;; Handle this case here to simplify previous expander.
17102 (define_expand "strset"
17103 [(set (match_operand 1 "memory_operand")
17104 (match_operand 2 "register_operand"))
17105 (parallel [(set (match_operand 0 "register_operand")
17107 (clobber (reg:CC FLAGS_REG))])]
17110 /* Can't use this for non-default address spaces. */
17111 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17114 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17115 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17117 /* If .md ever supports :P for Pmode, this can be directly
17118 in the pattern above. */
17119 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17120 GEN_INT (GET_MODE_SIZE (GET_MODE
17122 /* Can't use this if the user has appropriated eax or edi. */
17123 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17124 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17126 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17132 (define_expand "strset_singleop"
17133 [(parallel [(set (match_operand 1 "memory_operand")
17134 (match_operand 2 "register_operand"))
17135 (set (match_operand 0 "register_operand")
17137 (unspec [(const_int 0)] UNSPEC_STOS)])]
17141 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17144 (define_insn "*strsetdi_rex_1"
17145 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17146 (match_operand:DI 2 "register_operand" "a"))
17147 (set (match_operand:P 0 "register_operand" "=D")
17148 (plus:P (match_dup 1)
17150 (unspec [(const_int 0)] UNSPEC_STOS)]
17152 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17153 && ix86_check_no_addr_space (insn)"
17155 [(set_attr "type" "str")
17156 (set_attr "memory" "store")
17157 (set_attr "mode" "DI")])
17159 (define_insn "*strsetsi_1"
17160 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17161 (match_operand:SI 2 "register_operand" "a"))
17162 (set (match_operand:P 0 "register_operand" "=D")
17163 (plus:P (match_dup 1)
17165 (unspec [(const_int 0)] UNSPEC_STOS)]
17166 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17167 && ix86_check_no_addr_space (insn)"
17169 [(set_attr "type" "str")
17170 (set_attr "memory" "store")
17171 (set_attr "mode" "SI")])
17173 (define_insn "*strsethi_1"
17174 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17175 (match_operand:HI 2 "register_operand" "a"))
17176 (set (match_operand:P 0 "register_operand" "=D")
17177 (plus:P (match_dup 1)
17179 (unspec [(const_int 0)] UNSPEC_STOS)]
17180 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17181 && ix86_check_no_addr_space (insn)"
17183 [(set_attr "type" "str")
17184 (set_attr "memory" "store")
17185 (set_attr "mode" "HI")])
17187 (define_insn "*strsetqi_1"
17188 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17189 (match_operand:QI 2 "register_operand" "a"))
17190 (set (match_operand:P 0 "register_operand" "=D")
17191 (plus:P (match_dup 1)
17193 (unspec [(const_int 0)] UNSPEC_STOS)]
17194 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17195 && ix86_check_no_addr_space (insn)"
17197 [(set_attr "type" "str")
17198 (set_attr "memory" "store")
17199 (set (attr "prefix_rex")
17201 (match_test "<P:MODE>mode == DImode")
17203 (const_string "*")))
17204 (set_attr "mode" "QI")])
17206 (define_expand "rep_stos"
17207 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17208 (set (match_operand 0 "register_operand")
17210 (set (match_operand 2 "memory_operand") (const_int 0))
17211 (use (match_operand 3 "register_operand"))
17212 (use (match_dup 1))])]
17216 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17219 (define_insn "*rep_stosdi_rex64"
17220 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17221 (set (match_operand:P 0 "register_operand" "=D")
17222 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17224 (match_operand:P 3 "register_operand" "0")))
17225 (set (mem:BLK (match_dup 3))
17227 (use (match_operand:DI 2 "register_operand" "a"))
17228 (use (match_dup 4))]
17230 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17231 && ix86_check_no_addr_space (insn)"
17233 [(set_attr "type" "str")
17234 (set_attr "prefix_rep" "1")
17235 (set_attr "memory" "store")
17236 (set_attr "mode" "DI")])
17238 (define_insn "*rep_stossi"
17239 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17240 (set (match_operand:P 0 "register_operand" "=D")
17241 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17243 (match_operand:P 3 "register_operand" "0")))
17244 (set (mem:BLK (match_dup 3))
17246 (use (match_operand:SI 2 "register_operand" "a"))
17247 (use (match_dup 4))]
17248 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17249 && ix86_check_no_addr_space (insn)"
17250 "%^rep{%;} stos{l|d}"
17251 [(set_attr "type" "str")
17252 (set_attr "prefix_rep" "1")
17253 (set_attr "memory" "store")
17254 (set_attr "mode" "SI")])
17256 (define_insn "*rep_stosqi"
17257 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17258 (set (match_operand:P 0 "register_operand" "=D")
17259 (plus:P (match_operand:P 3 "register_operand" "0")
17260 (match_operand:P 4 "register_operand" "1")))
17261 (set (mem:BLK (match_dup 3))
17263 (use (match_operand:QI 2 "register_operand" "a"))
17264 (use (match_dup 4))]
17265 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17266 && ix86_check_no_addr_space (insn)"
17268 [(set_attr "type" "str")
17269 (set_attr "prefix_rep" "1")
17270 (set_attr "memory" "store")
17271 (set (attr "prefix_rex")
17273 (match_test "<P:MODE>mode == DImode")
17275 (const_string "*")))
17276 (set_attr "mode" "QI")])
17278 (define_expand "cmpstrnsi"
17279 [(set (match_operand:SI 0 "register_operand")
17280 (compare:SI (match_operand:BLK 1 "general_operand")
17281 (match_operand:BLK 2 "general_operand")))
17282 (use (match_operand 3 "general_operand"))
17283 (use (match_operand 4 "immediate_operand"))]
17286 rtx addr1, addr2, countreg, align, out;
17288 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17291 /* Can't use this if the user has appropriated ecx, esi or edi. */
17292 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17295 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17296 will have rewritten the length arg to be the minimum of the const string
17297 length and the actual length arg. If both strings are the same and
17298 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17299 will incorrectly base the results on chars past the 0 byte. */
17300 tree t1 = MEM_EXPR (operands[1]);
17301 tree t2 = MEM_EXPR (operands[2]);
17302 if (!((t1 && TREE_CODE (t1) == MEM_REF
17303 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17304 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17305 || (t2 && TREE_CODE (t2) == MEM_REF
17306 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17307 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17310 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17311 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17312 if (addr1 != XEXP (operands[1], 0))
17313 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17314 if (addr2 != XEXP (operands[2], 0))
17315 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17317 countreg = ix86_zero_extend_to_Pmode (operands[3]);
17319 /* %%% Iff we are testing strict equality, we can use known alignment
17320 to good advantage. This may be possible with combine, particularly
17321 once cc0 is dead. */
17322 align = operands[4];
17324 if (CONST_INT_P (operands[3]))
17326 if (operands[3] == const0_rtx)
17328 emit_move_insn (operands[0], const0_rtx);
17331 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17332 operands[1], operands[2]));
17336 emit_insn (gen_cmp_1 (Pmode, countreg, countreg));
17337 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17338 operands[1], operands[2]));
17341 out = gen_lowpart (QImode, operands[0]);
17342 emit_insn (gen_cmpintqi (out));
17343 emit_move_insn (operands[0], gen_rtx_SIGN_EXTEND (SImode, out));
17348 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17350 (define_expand "cmpintqi"
17351 [(set (match_dup 1)
17352 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17354 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17355 (parallel [(set (match_operand:QI 0 "register_operand")
17356 (minus:QI (match_dup 1)
17358 (clobber (reg:CC FLAGS_REG))])]
17361 operands[1] = gen_reg_rtx (QImode);
17362 operands[2] = gen_reg_rtx (QImode);
17365 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17366 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17368 (define_expand "cmpstrnqi_nz_1"
17369 [(parallel [(set (reg:CC FLAGS_REG)
17370 (compare:CC (match_operand 4 "memory_operand")
17371 (match_operand 5 "memory_operand")))
17372 (use (match_operand 2 "register_operand"))
17373 (use (match_operand:SI 3 "immediate_operand"))
17374 (clobber (match_operand 0 "register_operand"))
17375 (clobber (match_operand 1 "register_operand"))
17376 (clobber (match_dup 2))])]
17380 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17383 (define_insn "*cmpstrnqi_nz_1"
17384 [(set (reg:CC FLAGS_REG)
17385 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17386 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17387 (use (match_operand:P 6 "register_operand" "2"))
17388 (use (match_operand:SI 3 "immediate_operand" "i"))
17389 (clobber (match_operand:P 0 "register_operand" "=S"))
17390 (clobber (match_operand:P 1 "register_operand" "=D"))
17391 (clobber (match_operand:P 2 "register_operand" "=c"))]
17392 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17393 && ix86_check_no_addr_space (insn)"
17395 [(set_attr "type" "str")
17396 (set_attr "mode" "QI")
17397 (set (attr "prefix_rex")
17399 (match_test "<P:MODE>mode == DImode")
17401 (const_string "*")))
17402 (set_attr "prefix_rep" "1")])
17404 ;; The same, but the count is not known to not be zero.
17406 (define_expand "cmpstrnqi_1"
17407 [(parallel [(set (reg:CC FLAGS_REG)
17408 (if_then_else:CC (ne (match_operand 2 "register_operand")
17410 (compare:CC (match_operand 4 "memory_operand")
17411 (match_operand 5 "memory_operand"))
17413 (use (match_operand:SI 3 "immediate_operand"))
17414 (use (reg:CC FLAGS_REG))
17415 (clobber (match_operand 0 "register_operand"))
17416 (clobber (match_operand 1 "register_operand"))
17417 (clobber (match_dup 2))])]
17421 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17424 (define_insn "*cmpstrnqi_1"
17425 [(set (reg:CC FLAGS_REG)
17426 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17428 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17429 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17431 (use (match_operand:SI 3 "immediate_operand" "i"))
17432 (use (reg:CC FLAGS_REG))
17433 (clobber (match_operand:P 0 "register_operand" "=S"))
17434 (clobber (match_operand:P 1 "register_operand" "=D"))
17435 (clobber (match_operand:P 2 "register_operand" "=c"))]
17436 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17437 && ix86_check_no_addr_space (insn)"
17439 [(set_attr "type" "str")
17440 (set_attr "mode" "QI")
17441 (set (attr "prefix_rex")
17443 (match_test "<P:MODE>mode == DImode")
17445 (const_string "*")))
17446 (set_attr "prefix_rep" "1")])
17448 (define_expand "strlen<mode>"
17449 [(set (match_operand:P 0 "register_operand")
17450 (unspec:P [(match_operand:BLK 1 "general_operand")
17451 (match_operand:QI 2 "immediate_operand")
17452 (match_operand 3 "immediate_operand")]
17456 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17462 (define_expand "strlenqi_1"
17463 [(parallel [(set (match_operand 0 "register_operand")
17465 (clobber (match_operand 1 "register_operand"))
17466 (clobber (reg:CC FLAGS_REG))])]
17470 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17473 (define_insn "*strlenqi_1"
17474 [(set (match_operand:P 0 "register_operand" "=&c")
17475 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17476 (match_operand:QI 2 "register_operand" "a")
17477 (match_operand:P 3 "immediate_operand" "i")
17478 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17479 (clobber (match_operand:P 1 "register_operand" "=D"))
17480 (clobber (reg:CC FLAGS_REG))]
17481 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17482 && ix86_check_no_addr_space (insn)"
17483 "%^repnz{%;} scasb"
17484 [(set_attr "type" "str")
17485 (set_attr "mode" "QI")
17486 (set (attr "prefix_rex")
17488 (match_test "<P:MODE>mode == DImode")
17490 (const_string "*")))
17491 (set_attr "prefix_rep" "1")])
17493 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17494 ;; handled in combine, but it is not currently up to the task.
17495 ;; When used for their truth value, the cmpstrn* expanders generate
17504 ;; The intermediate three instructions are unnecessary.
17506 ;; This one handles cmpstrn*_nz_1...
17509 (set (reg:CC FLAGS_REG)
17510 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17511 (mem:BLK (match_operand 5 "register_operand"))))
17512 (use (match_operand 6 "register_operand"))
17513 (use (match_operand:SI 3 "immediate_operand"))
17514 (clobber (match_operand 0 "register_operand"))
17515 (clobber (match_operand 1 "register_operand"))
17516 (clobber (match_operand 2 "register_operand"))])
17517 (set (match_operand:QI 7 "register_operand")
17518 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17519 (set (match_operand:QI 8 "register_operand")
17520 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17521 (set (reg FLAGS_REG)
17522 (compare (match_dup 7) (match_dup 8)))
17524 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17526 (set (reg:CC FLAGS_REG)
17527 (compare:CC (mem:BLK (match_dup 4))
17528 (mem:BLK (match_dup 5))))
17529 (use (match_dup 6))
17530 (use (match_dup 3))
17531 (clobber (match_dup 0))
17532 (clobber (match_dup 1))
17533 (clobber (match_dup 2))])])
17535 ;; ...and this one handles cmpstrn*_1.
17538 (set (reg:CC FLAGS_REG)
17539 (if_then_else:CC (ne (match_operand 6 "register_operand")
17541 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17542 (mem:BLK (match_operand 5 "register_operand")))
17544 (use (match_operand:SI 3 "immediate_operand"))
17545 (use (reg:CC FLAGS_REG))
17546 (clobber (match_operand 0 "register_operand"))
17547 (clobber (match_operand 1 "register_operand"))
17548 (clobber (match_operand 2 "register_operand"))])
17549 (set (match_operand:QI 7 "register_operand")
17550 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17551 (set (match_operand:QI 8 "register_operand")
17552 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17553 (set (reg FLAGS_REG)
17554 (compare (match_dup 7) (match_dup 8)))
17556 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17558 (set (reg:CC FLAGS_REG)
17559 (if_then_else:CC (ne (match_dup 6)
17561 (compare:CC (mem:BLK (match_dup 4))
17562 (mem:BLK (match_dup 5)))
17564 (use (match_dup 3))
17565 (use (reg:CC FLAGS_REG))
17566 (clobber (match_dup 0))
17567 (clobber (match_dup 1))
17568 (clobber (match_dup 2))])])
17570 ;; Conditional move instructions.
17572 (define_expand "mov<mode>cc"
17573 [(set (match_operand:SWIM 0 "register_operand")
17574 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17575 (match_operand:SWIM 2 "<general_operand>")
17576 (match_operand:SWIM 3 "<general_operand>")))]
17578 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17580 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17581 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17582 ;; So just document what we're doing explicitly.
17584 (define_expand "x86_mov<mode>cc_0_m1"
17586 [(set (match_operand:SWI48 0 "register_operand")
17587 (if_then_else:SWI48
17588 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17589 [(match_operand 1 "flags_reg_operand")
17593 (clobber (reg:CC FLAGS_REG))])])
17595 (define_insn "*x86_mov<mode>cc_0_m1"
17596 [(set (match_operand:SWI48 0 "register_operand" "=r")
17597 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17598 [(reg FLAGS_REG) (const_int 0)])
17601 (clobber (reg:CC FLAGS_REG))]
17603 "sbb{<imodesuffix>}\t%0, %0"
17604 [(set_attr "type" "alu1")
17605 (set_attr "use_carry" "1")
17606 (set_attr "pent_pair" "pu")
17607 (set_attr "mode" "<MODE>")
17608 (set_attr "length_immediate" "0")])
17610 (define_insn "*x86_mov<mode>cc_0_m1_se"
17611 [(set (match_operand:SWI48 0 "register_operand" "=r")
17612 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17613 [(reg FLAGS_REG) (const_int 0)])
17616 (clobber (reg:CC FLAGS_REG))]
17618 "sbb{<imodesuffix>}\t%0, %0"
17619 [(set_attr "type" "alu1")
17620 (set_attr "use_carry" "1")
17621 (set_attr "pent_pair" "pu")
17622 (set_attr "mode" "<MODE>")
17623 (set_attr "length_immediate" "0")])
17625 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17626 [(set (match_operand:SWI48 0 "register_operand" "=r")
17627 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17628 [(reg FLAGS_REG) (const_int 0)])))
17629 (clobber (reg:CC FLAGS_REG))]
17631 "sbb{<imodesuffix>}\t%0, %0"
17632 [(set_attr "type" "alu1")
17633 (set_attr "use_carry" "1")
17634 (set_attr "pent_pair" "pu")
17635 (set_attr "mode" "<MODE>")
17636 (set_attr "length_immediate" "0")])
17638 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17639 [(set (match_operand:SWI48 0 "register_operand" "=r")
17642 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17643 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17644 (clobber (reg:CC FLAGS_REG))]
17645 "CONST_INT_P (operands[2])
17646 && INTVAL (operands[2]) != -1
17647 && INTVAL (operands[2]) != 2147483647"
17650 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17651 (parallel [(set (match_dup 0)
17652 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17653 (clobber (reg:CC FLAGS_REG))])]
17654 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17656 (define_insn "*mov<mode>cc_noc"
17657 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17658 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17659 [(reg FLAGS_REG) (const_int 0)])
17660 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17661 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17662 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17664 cmov%O2%C1\t{%2, %0|%0, %2}
17665 cmov%O2%c1\t{%3, %0|%0, %3}"
17666 [(set_attr "type" "icmov")
17667 (set_attr "mode" "<MODE>")])
17669 (define_insn "*movsicc_noc_zext"
17670 [(set (match_operand:DI 0 "register_operand" "=r,r")
17671 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17672 [(reg FLAGS_REG) (const_int 0)])
17674 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17676 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17678 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17680 cmov%O2%C1\t{%2, %k0|%k0, %2}
17681 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17682 [(set_attr "type" "icmov")
17683 (set_attr "mode" "SI")])
17685 ;; Don't do conditional moves with memory inputs. This splitter helps
17686 ;; register starved x86_32 by forcing inputs into registers before reload.
17688 [(set (match_operand:SWI248 0 "register_operand")
17689 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17690 [(reg FLAGS_REG) (const_int 0)])
17691 (match_operand:SWI248 2 "nonimmediate_operand")
17692 (match_operand:SWI248 3 "nonimmediate_operand")))]
17693 "!TARGET_64BIT && TARGET_CMOVE
17694 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17695 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17696 && can_create_pseudo_p ()
17697 && optimize_insn_for_speed_p ()"
17698 [(set (match_dup 0)
17699 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17701 if (MEM_P (operands[2]))
17702 operands[2] = force_reg (<MODE>mode, operands[2]);
17703 if (MEM_P (operands[3]))
17704 operands[3] = force_reg (<MODE>mode, operands[3]);
17707 (define_insn "*movqicc_noc"
17708 [(set (match_operand:QI 0 "register_operand" "=r,r")
17709 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17710 [(reg FLAGS_REG) (const_int 0)])
17711 (match_operand:QI 2 "register_operand" "r,0")
17712 (match_operand:QI 3 "register_operand" "0,r")))]
17713 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17715 [(set_attr "type" "icmov")
17716 (set_attr "mode" "QI")])
17719 [(set (match_operand:SWI12 0 "register_operand")
17720 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17721 [(reg FLAGS_REG) (const_int 0)])
17722 (match_operand:SWI12 2 "register_operand")
17723 (match_operand:SWI12 3 "register_operand")))]
17724 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17725 && reload_completed"
17726 [(set (match_dup 0)
17727 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17729 operands[0] = gen_lowpart (SImode, operands[0]);
17730 operands[2] = gen_lowpart (SImode, operands[2]);
17731 operands[3] = gen_lowpart (SImode, operands[3]);
17734 ;; Don't do conditional moves with memory inputs
17736 [(match_scratch:SWI248 4 "r")
17737 (set (match_operand:SWI248 0 "register_operand")
17738 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17739 [(reg FLAGS_REG) (const_int 0)])
17740 (match_operand:SWI248 2 "nonimmediate_operand")
17741 (match_operand:SWI248 3 "nonimmediate_operand")))]
17742 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17743 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17744 && optimize_insn_for_speed_p ()"
17745 [(set (match_dup 4) (match_dup 5))
17747 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17749 if (MEM_P (operands[2]))
17751 operands[5] = operands[2];
17752 operands[2] = operands[4];
17754 else if (MEM_P (operands[3]))
17756 operands[5] = operands[3];
17757 operands[3] = operands[4];
17760 gcc_unreachable ();
17764 [(match_scratch:SI 4 "r")
17765 (set (match_operand:DI 0 "register_operand")
17766 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17767 [(reg FLAGS_REG) (const_int 0)])
17769 (match_operand:SI 2 "nonimmediate_operand"))
17771 (match_operand:SI 3 "nonimmediate_operand"))))]
17773 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17774 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17775 && optimize_insn_for_speed_p ()"
17776 [(set (match_dup 4) (match_dup 5))
17778 (if_then_else:DI (match_dup 1)
17779 (zero_extend:DI (match_dup 2))
17780 (zero_extend:DI (match_dup 3))))]
17782 if (MEM_P (operands[2]))
17784 operands[5] = operands[2];
17785 operands[2] = operands[4];
17787 else if (MEM_P (operands[3]))
17789 operands[5] = operands[3];
17790 operands[3] = operands[4];
17793 gcc_unreachable ();
17796 (define_expand "mov<mode>cc"
17797 [(set (match_operand:X87MODEF 0 "register_operand")
17798 (if_then_else:X87MODEF
17799 (match_operand 1 "comparison_operator")
17800 (match_operand:X87MODEF 2 "register_operand")
17801 (match_operand:X87MODEF 3 "register_operand")))]
17802 "(TARGET_80387 && TARGET_CMOVE)
17803 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17804 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17806 (define_insn "*movxfcc_1"
17807 [(set (match_operand:XF 0 "register_operand" "=f,f")
17808 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17809 [(reg FLAGS_REG) (const_int 0)])
17810 (match_operand:XF 2 "register_operand" "f,0")
17811 (match_operand:XF 3 "register_operand" "0,f")))]
17812 "TARGET_80387 && TARGET_CMOVE"
17814 fcmov%F1\t{%2, %0|%0, %2}
17815 fcmov%f1\t{%3, %0|%0, %3}"
17816 [(set_attr "type" "fcmov")
17817 (set_attr "mode" "XF")])
17819 (define_insn "*movdfcc_1"
17820 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17821 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17822 [(reg FLAGS_REG) (const_int 0)])
17823 (match_operand:DF 2 "nonimmediate_operand"
17825 (match_operand:DF 3 "nonimmediate_operand"
17826 "0 ,f,0 ,rm,0, rm")))]
17827 "TARGET_80387 && TARGET_CMOVE
17828 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17830 fcmov%F1\t{%2, %0|%0, %2}
17831 fcmov%f1\t{%3, %0|%0, %3}
17834 cmov%O2%C1\t{%2, %0|%0, %2}
17835 cmov%O2%c1\t{%3, %0|%0, %3}"
17836 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17837 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17838 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17841 [(set (match_operand:DF 0 "general_reg_operand")
17842 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17843 [(reg FLAGS_REG) (const_int 0)])
17844 (match_operand:DF 2 "nonimmediate_operand")
17845 (match_operand:DF 3 "nonimmediate_operand")))]
17846 "!TARGET_64BIT && reload_completed"
17847 [(set (match_dup 2)
17848 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17850 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17852 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17853 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17856 (define_insn "*movsfcc_1_387"
17857 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17858 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17859 [(reg FLAGS_REG) (const_int 0)])
17860 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17861 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17862 "TARGET_80387 && TARGET_CMOVE
17863 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17865 fcmov%F1\t{%2, %0|%0, %2}
17866 fcmov%f1\t{%3, %0|%0, %3}
17867 cmov%O2%C1\t{%2, %0|%0, %2}
17868 cmov%O2%c1\t{%3, %0|%0, %3}"
17869 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17870 (set_attr "mode" "SF,SF,SI,SI")])
17872 ;; Don't do conditional moves with memory inputs. This splitter helps
17873 ;; register starved x86_32 by forcing inputs into registers before reload.
17875 [(set (match_operand:MODEF 0 "register_operand")
17876 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17877 [(reg FLAGS_REG) (const_int 0)])
17878 (match_operand:MODEF 2 "nonimmediate_operand")
17879 (match_operand:MODEF 3 "nonimmediate_operand")))]
17880 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17881 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17882 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17883 && can_create_pseudo_p ()
17884 && optimize_insn_for_speed_p ()"
17885 [(set (match_dup 0)
17886 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17888 if (MEM_P (operands[2]))
17889 operands[2] = force_reg (<MODE>mode, operands[2]);
17890 if (MEM_P (operands[3]))
17891 operands[3] = force_reg (<MODE>mode, operands[3]);
17894 ;; Don't do conditional moves with memory inputs
17896 [(match_scratch:MODEF 4 "r")
17897 (set (match_operand:MODEF 0 "general_reg_operand")
17898 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17899 [(reg FLAGS_REG) (const_int 0)])
17900 (match_operand:MODEF 2 "nonimmediate_operand")
17901 (match_operand:MODEF 3 "nonimmediate_operand")))]
17902 "(<MODE>mode != DFmode || TARGET_64BIT)
17903 && TARGET_80387 && TARGET_CMOVE
17904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17905 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17906 && optimize_insn_for_speed_p ()"
17907 [(set (match_dup 4) (match_dup 5))
17909 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17911 if (MEM_P (operands[2]))
17913 operands[5] = operands[2];
17914 operands[2] = operands[4];
17916 else if (MEM_P (operands[3]))
17918 operands[5] = operands[3];
17919 operands[3] = operands[4];
17922 gcc_unreachable ();
17925 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17926 ;; the scalar versions to have only XMM registers as operands.
17928 ;; XOP conditional move
17929 (define_insn "*xop_pcmov_<mode>"
17930 [(set (match_operand:MODEF 0 "register_operand" "=x")
17931 (if_then_else:MODEF
17932 (match_operand:MODEF 1 "register_operand" "x")
17933 (match_operand:MODEF 2 "register_operand" "x")
17934 (match_operand:MODEF 3 "register_operand" "x")))]
17936 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17937 [(set_attr "type" "sse4arg")])
17939 ;; These versions of the min/max patterns are intentionally ignorant of
17940 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17941 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17942 ;; are undefined in this condition, we're certain this is correct.
17944 (define_insn "<code><mode>3"
17945 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17947 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17948 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17949 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17951 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17952 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17953 [(set_attr "isa" "noavx,avx")
17954 (set_attr "prefix" "orig,vex")
17955 (set_attr "type" "sseadd")
17956 (set_attr "mode" "<MODE>")])
17958 ;; These versions of the min/max patterns implement exactly the operations
17959 ;; min = (op1 < op2 ? op1 : op2)
17960 ;; max = (!(op1 < op2) ? op1 : op2)
17961 ;; Their operands are not commutative, and thus they may be used in the
17962 ;; presence of -0.0 and NaN.
17964 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17965 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17967 [(match_operand:MODEF 1 "register_operand" "0,v")
17968 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17972 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17973 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17974 [(set_attr "isa" "noavx,avx")
17975 (set_attr "prefix" "orig,maybe_evex")
17976 (set_attr "type" "sseadd")
17977 (set_attr "mode" "<MODE>")])
17979 ;; Make two stack loads independent:
17981 ;; fld %st(0) -> fld bb
17982 ;; fmul bb fmul %st(1), %st
17984 ;; Actually we only match the last two instructions for simplicity.
17987 [(set (match_operand 0 "fp_register_operand")
17988 (match_operand 1 "fp_register_operand"))
17990 (match_operator 2 "binary_fp_operator"
17992 (match_operand 3 "memory_operand")]))]
17993 "REGNO (operands[0]) != REGNO (operands[1])"
17994 [(set (match_dup 0) (match_dup 3))
17997 [(match_dup 5) (match_dup 4)]))]
17999 operands[4] = operands[0];
18000 operands[5] = operands[1];
18002 /* The % modifier is not operational anymore in peephole2's, so we have to
18003 swap the operands manually in the case of addition and multiplication. */
18004 if (COMMUTATIVE_ARITH_P (operands[2]))
18005 std::swap (operands[4], operands[5]);
18009 [(set (match_operand 0 "fp_register_operand")
18010 (match_operand 1 "fp_register_operand"))
18012 (match_operator 2 "binary_fp_operator"
18013 [(match_operand 3 "memory_operand")
18015 "REGNO (operands[0]) != REGNO (operands[1])"
18016 [(set (match_dup 0) (match_dup 3))
18019 [(match_dup 4) (match_dup 5)]))]
18021 operands[4] = operands[0];
18022 operands[5] = operands[1];
18024 /* The % modifier is not operational anymore in peephole2's, so we have to
18025 swap the operands manually in the case of addition and multiplication. */
18026 if (COMMUTATIVE_ARITH_P (operands[2]))
18027 std::swap (operands[4], operands[5]);
18030 ;; Conditional addition patterns
18031 (define_expand "add<mode>cc"
18032 [(match_operand:SWI 0 "register_operand")
18033 (match_operand 1 "ordered_comparison_operator")
18034 (match_operand:SWI 2 "register_operand")
18035 (match_operand:SWI 3 "const_int_operand")]
18037 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18039 ;; min/max patterns
18041 (define_mode_iterator MAXMIN_IMODE
18042 [(SI "TARGET_SSE4_1") (DI "TARGET_AVX512VL")])
18043 (define_code_attr maxmin_rel
18044 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
18046 (define_expand "<code><mode>3"
18048 [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18049 (maxmin:MAXMIN_IMODE
18050 (match_operand:MAXMIN_IMODE 1 "register_operand")
18051 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18052 (clobber (reg:CC FLAGS_REG))])]
18055 (define_insn_and_split "*<code><mode>3_1"
18056 [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18057 (maxmin:MAXMIN_IMODE
18058 (match_operand:MAXMIN_IMODE 1 "register_operand")
18059 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18060 (clobber (reg:CC FLAGS_REG))]
18061 "(TARGET_64BIT || <MODE>mode != DImode) && TARGET_STV
18062 && ix86_pre_reload_split ()"
18065 [(set (match_dup 0)
18066 (if_then_else:MAXMIN_IMODE (match_dup 3)
18070 machine_mode mode = <MODE>mode;
18072 if (!register_operand (operands[2], mode))
18073 operands[2] = force_reg (mode, operands[2]);
18075 enum rtx_code code = <maxmin_rel>;
18076 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], operands[2]);
18077 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
18079 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], operands[2]);
18080 emit_insn (gen_rtx_SET (flags, tmp));
18082 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18085 (define_insn_and_split "*<code>di3_doubleword"
18086 [(set (match_operand:DI 0 "register_operand")
18087 (maxmin:DI (match_operand:DI 1 "register_operand")
18088 (match_operand:DI 2 "nonimmediate_operand")))
18089 (clobber (reg:CC FLAGS_REG))]
18090 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
18091 && ix86_pre_reload_split ()"
18094 [(set (match_dup 0)
18095 (if_then_else:SI (match_dup 6)
18099 (if_then_else:SI (match_dup 6)
18103 if (!register_operand (operands[2], DImode))
18104 operands[2] = force_reg (DImode, operands[2]);
18106 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
18108 rtx cmplo[2] = { operands[1], operands[2] };
18109 rtx cmphi[2] = { operands[4], operands[5] };
18111 enum rtx_code code = <maxmin_rel>;
18116 std::swap (cmplo[0], cmplo[1]);
18117 std::swap (cmphi[0], cmphi[1]);
18118 code = swap_condition (code);
18123 bool uns = (code == GEU);
18124 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
18125 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
18127 emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1]));
18129 rtx tmp = gen_rtx_SCRATCH (SImode);
18130 emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1]));
18132 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
18133 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18139 gcc_unreachable ();
18143 ;; Misc patterns (?)
18145 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18146 ;; Otherwise there will be nothing to keep
18148 ;; [(set (reg ebp) (reg esp))]
18149 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18150 ;; (clobber (eflags)]
18151 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18153 ;; in proper program order.
18155 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
18156 [(set (match_operand:P 0 "register_operand" "=r,r")
18157 (plus:P (match_operand:P 1 "register_operand" "0,r")
18158 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18159 (clobber (reg:CC FLAGS_REG))
18160 (clobber (mem:BLK (scratch)))]
18163 switch (get_attr_type (insn))
18166 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18169 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18170 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18173 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18176 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18177 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18180 [(set (attr "type")
18181 (cond [(and (eq_attr "alternative" "0")
18182 (not (match_test "TARGET_OPT_AGU")))
18183 (const_string "alu")
18184 (match_operand:<MODE> 2 "const0_operand")
18185 (const_string "imov")
18187 (const_string "lea")))
18188 (set (attr "length_immediate")
18189 (cond [(eq_attr "type" "imov")
18191 (and (eq_attr "type" "alu")
18192 (match_operand 2 "const128_operand"))
18195 (const_string "*")))
18196 (set_attr "mode" "<MODE>")])
18198 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
18199 [(set (match_operand:P 0 "register_operand" "=r")
18200 (minus:P (match_operand:P 1 "register_operand" "0")
18201 (match_operand:P 2 "register_operand" "r")))
18202 (clobber (reg:CC FLAGS_REG))
18203 (clobber (mem:BLK (scratch)))]
18205 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18206 [(set_attr "type" "alu")
18207 (set_attr "mode" "<MODE>")])
18209 (define_insn "@allocate_stack_worker_probe_<mode>"
18210 [(set (match_operand:P 0 "register_operand" "=a")
18211 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18212 UNSPECV_STACK_PROBE))
18213 (clobber (reg:CC FLAGS_REG))]
18214 "ix86_target_stack_probe ()"
18215 "call\t___chkstk_ms"
18216 [(set_attr "type" "multi")
18217 (set_attr "length" "5")])
18219 (define_expand "allocate_stack"
18220 [(match_operand 0 "register_operand")
18221 (match_operand 1 "general_operand")]
18222 "ix86_target_stack_probe ()"
18226 #ifndef CHECK_STACK_LIMIT
18227 #define CHECK_STACK_LIMIT 0
18230 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18231 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18235 x = copy_to_mode_reg (Pmode, operands[1]);
18237 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
18240 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18241 stack_pointer_rtx, 0, OPTAB_DIRECT);
18243 if (x != stack_pointer_rtx)
18244 emit_move_insn (stack_pointer_rtx, x);
18246 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18250 (define_expand "probe_stack"
18251 [(match_operand 0 "memory_operand")]
18254 emit_insn (gen_probe_stack_1
18255 (word_mode, operands[0], const0_rtx));
18259 ;; Use OR for stack probes, this is shorter.
18260 (define_insn "@probe_stack_1_<mode>"
18261 [(set (match_operand:W 0 "memory_operand" "=m")
18262 (unspec:W [(match_operand:W 1 "const0_operand")]
18263 UNSPEC_PROBE_STACK))
18264 (clobber (reg:CC FLAGS_REG))]
18266 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18267 [(set_attr "type" "alu1")
18268 (set_attr "mode" "<MODE>")
18269 (set_attr "length_immediate" "1")])
18271 (define_insn "@adjust_stack_and_probe_<mode>"
18272 [(set (match_operand:P 0 "register_operand" "=r")
18273 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18274 UNSPECV_PROBE_STACK_RANGE))
18275 (set (reg:P SP_REG)
18276 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18277 (clobber (reg:CC FLAGS_REG))
18278 (clobber (mem:BLK (scratch)))]
18280 "* return output_adjust_stack_and_probe (operands[0]);"
18281 [(set_attr "type" "multi")])
18283 (define_insn "@probe_stack_range_<mode>"
18284 [(set (match_operand:P 0 "register_operand" "=r")
18285 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18286 (match_operand:P 2 "const_int_operand" "n")]
18287 UNSPECV_PROBE_STACK_RANGE))
18288 (clobber (reg:CC FLAGS_REG))]
18290 "* return output_probe_stack_range (operands[0], operands[2]);"
18291 [(set_attr "type" "multi")])
18293 (define_expand "builtin_setjmp_receiver"
18294 [(label_ref (match_operand 0))]
18295 "!TARGET_64BIT && flag_pic"
18301 rtx_code_label *label_rtx = gen_label_rtx ();
18302 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18303 xops[0] = xops[1] = pic_offset_table_rtx;
18304 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18305 ix86_expand_binary_operator (MINUS, SImode, xops);
18309 emit_insn (gen_set_got (pic_offset_table_rtx));
18313 (define_expand "save_stack_nonlocal"
18314 [(set (match_operand 0 "memory_operand")
18315 (match_operand 1 "register_operand"))]
18319 if ((flag_cf_protection & CF_RETURN))
18321 /* Copy shadow stack pointer to the first slot and stack ppointer
18322 to the second slot. */
18323 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18324 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18325 rtx ssp = gen_reg_rtx (word_mode);
18326 emit_insn ((word_mode == SImode)
18327 ? gen_rdsspsi (ssp)
18328 : gen_rdsspdi (ssp));
18329 emit_move_insn (ssp_slot, ssp);
18332 stack_slot = adjust_address (operands[0], Pmode, 0);
18333 emit_move_insn (stack_slot, operands[1]);
18337 (define_expand "restore_stack_nonlocal"
18338 [(set (match_operand 0 "register_operand" "")
18339 (match_operand 1 "memory_operand" ""))]
18343 if ((flag_cf_protection & CF_RETURN))
18345 /* Restore shadow stack pointer from the first slot and stack
18346 pointer from the second slot. */
18347 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18348 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18350 rtx flags, jump, noadj_label, inc_label, loop_label;
18351 rtx reg_adj, reg_ssp, tmp, clob;
18353 /* Get the current shadow stack pointer. The code below will check if
18354 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18356 reg_ssp = gen_reg_rtx (word_mode);
18357 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18358 emit_insn ((word_mode == SImode)
18359 ? gen_rdsspsi (reg_ssp)
18360 : gen_rdsspdi (reg_ssp));
18362 /* Compare through substraction the saved and the current ssp to decide
18363 if ssp has to be adjusted. */
18364 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18366 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18367 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18370 /* Compare and jump over adjustment code. */
18371 noadj_label = gen_label_rtx ();
18372 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18373 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18374 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18375 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18377 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18378 JUMP_LABEL (jump) = noadj_label;
18380 /* Compute the numebr of frames to adjust. */
18381 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18382 tmp = gen_rtx_SET (reg_adj,
18383 gen_rtx_LSHIFTRT (ptr_mode,
18384 negate_rtx (ptr_mode, reg_adj),
18385 GEN_INT ((word_mode == SImode)
18388 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18389 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18392 /* Check if number of frames <= 255 so no loop is needed. */
18393 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18394 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18395 emit_insn (gen_rtx_SET (flags, tmp));
18397 inc_label = gen_label_rtx ();
18398 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18399 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18400 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18402 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18403 JUMP_LABEL (jump) = inc_label;
18405 rtx reg_255 = gen_reg_rtx (word_mode);
18406 emit_move_insn (reg_255, GEN_INT (255));
18408 /* Adjust the ssp in a loop. */
18409 loop_label = gen_label_rtx ();
18410 emit_label (loop_label);
18411 LABEL_NUSES (loop_label) = 1;
18413 emit_insn ((word_mode == SImode)
18414 ? gen_incsspsi (reg_255)
18415 : gen_incsspdi (reg_255));
18416 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18419 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18420 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18423 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18424 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18425 emit_insn (gen_rtx_SET (flags, tmp));
18427 /* Jump to the loop label. */
18428 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18429 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18430 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18432 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18433 JUMP_LABEL (jump) = loop_label;
18435 emit_label (inc_label);
18436 LABEL_NUSES (inc_label) = 1;
18437 emit_insn ((word_mode == SImode)
18438 ? gen_incsspsi (reg_ssp)
18439 : gen_incsspdi (reg_ssp));
18441 emit_label (noadj_label);
18442 LABEL_NUSES (noadj_label) = 1;
18445 stack_slot = adjust_address (operands[1], Pmode, 0);
18446 emit_move_insn (operands[0], stack_slot);
18451 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18452 ;; Do not split instructions with mask registers.
18454 [(set (match_operand 0 "general_reg_operand")
18455 (match_operator 3 "promotable_binary_operator"
18456 [(match_operand 1 "general_reg_operand")
18457 (match_operand 2 "aligned_operand")]))
18458 (clobber (reg:CC FLAGS_REG))]
18459 "! TARGET_PARTIAL_REG_STALL && reload_completed
18460 && ((GET_MODE (operands[0]) == HImode
18461 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18462 /* ??? next two lines just !satisfies_constraint_K (...) */
18463 || !CONST_INT_P (operands[2])
18464 || satisfies_constraint_K (operands[2])))
18465 || (GET_MODE (operands[0]) == QImode
18466 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18467 [(parallel [(set (match_dup 0)
18468 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18469 (clobber (reg:CC FLAGS_REG))])]
18471 operands[0] = gen_lowpart (SImode, operands[0]);
18472 operands[1] = gen_lowpart (SImode, operands[1]);
18473 if (GET_CODE (operands[3]) != ASHIFT)
18474 operands[2] = gen_lowpart (SImode, operands[2]);
18475 operands[3] = shallow_copy_rtx (operands[3]);
18476 PUT_MODE (operands[3], SImode);
18479 ; Promote the QImode tests, as i386 has encoding of the AND
18480 ; instruction with 32-bit sign-extended immediate and thus the
18481 ; instruction size is unchanged, except in the %eax case for
18482 ; which it is increased by one byte, hence the ! optimize_size.
18484 [(set (match_operand 0 "flags_reg_operand")
18485 (match_operator 2 "compare_operator"
18486 [(and (match_operand 3 "aligned_operand")
18487 (match_operand 4 "const_int_operand"))
18489 (set (match_operand 1 "register_operand")
18490 (and (match_dup 3) (match_dup 4)))]
18491 "! TARGET_PARTIAL_REG_STALL && reload_completed
18492 && optimize_insn_for_speed_p ()
18493 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18494 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18495 /* Ensure that the operand will remain sign-extended immediate. */
18496 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18497 [(parallel [(set (match_dup 0)
18498 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18501 (and:SI (match_dup 3) (match_dup 4)))])]
18504 = gen_int_mode (INTVAL (operands[4])
18505 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18506 operands[1] = gen_lowpart (SImode, operands[1]);
18507 operands[3] = gen_lowpart (SImode, operands[3]);
18510 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18511 ; the TEST instruction with 32-bit sign-extended immediate and thus
18512 ; the instruction size would at least double, which is not what we
18513 ; want even with ! optimize_size.
18515 [(set (match_operand 0 "flags_reg_operand")
18516 (match_operator 1 "compare_operator"
18517 [(and (match_operand:HI 2 "aligned_operand")
18518 (match_operand:HI 3 "const_int_operand"))
18520 "! TARGET_PARTIAL_REG_STALL && reload_completed
18521 && ! TARGET_FAST_PREFIX
18522 && optimize_insn_for_speed_p ()
18523 /* Ensure that the operand will remain sign-extended immediate. */
18524 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18525 [(set (match_dup 0)
18526 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18530 = gen_int_mode (INTVAL (operands[3])
18531 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18532 operands[2] = gen_lowpart (SImode, operands[2]);
18536 [(set (match_operand 0 "register_operand")
18537 (neg (match_operand 1 "register_operand")))
18538 (clobber (reg:CC FLAGS_REG))]
18539 "! TARGET_PARTIAL_REG_STALL && reload_completed
18540 && (GET_MODE (operands[0]) == HImode
18541 || (GET_MODE (operands[0]) == QImode
18542 && (TARGET_PROMOTE_QImode
18543 || optimize_insn_for_size_p ())))"
18544 [(parallel [(set (match_dup 0)
18545 (neg:SI (match_dup 1)))
18546 (clobber (reg:CC FLAGS_REG))])]
18548 operands[0] = gen_lowpart (SImode, operands[0]);
18549 operands[1] = gen_lowpart (SImode, operands[1]);
18552 ;; Do not split instructions with mask regs.
18554 [(set (match_operand 0 "general_reg_operand")
18555 (not (match_operand 1 "general_reg_operand")))]
18556 "! TARGET_PARTIAL_REG_STALL && reload_completed
18557 && (GET_MODE (operands[0]) == HImode
18558 || (GET_MODE (operands[0]) == QImode
18559 && (TARGET_PROMOTE_QImode
18560 || optimize_insn_for_size_p ())))"
18561 [(set (match_dup 0)
18562 (not:SI (match_dup 1)))]
18564 operands[0] = gen_lowpart (SImode, operands[0]);
18565 operands[1] = gen_lowpart (SImode, operands[1]);
18568 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18569 ;; transform a complex memory operation into two memory to register operations.
18571 ;; Don't push memory operands
18573 [(set (match_operand:SWI 0 "push_operand")
18574 (match_operand:SWI 1 "memory_operand"))
18575 (match_scratch:SWI 2 "<r>")]
18576 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18577 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18578 [(set (match_dup 2) (match_dup 1))
18579 (set (match_dup 0) (match_dup 2))])
18581 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18584 [(set (match_operand:SF 0 "push_operand")
18585 (match_operand:SF 1 "memory_operand"))
18586 (match_scratch:SF 2 "r")]
18587 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18588 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18589 [(set (match_dup 2) (match_dup 1))
18590 (set (match_dup 0) (match_dup 2))])
18592 ;; Don't move an immediate directly to memory when the instruction
18593 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18595 [(match_scratch:SWI124 1 "<r>")
18596 (set (match_operand:SWI124 0 "memory_operand")
18598 "optimize_insn_for_speed_p ()
18599 && ((<MODE>mode == HImode
18600 && TARGET_LCP_STALL)
18601 || (!TARGET_USE_MOV0
18602 && TARGET_SPLIT_LONG_MOVES
18603 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18604 && peep2_regno_dead_p (0, FLAGS_REG)"
18605 [(parallel [(set (match_dup 2) (const_int 0))
18606 (clobber (reg:CC FLAGS_REG))])
18607 (set (match_dup 0) (match_dup 1))]
18608 "operands[2] = gen_lowpart (SImode, operands[1]);")
18611 [(match_scratch:SWI124 2 "<r>")
18612 (set (match_operand:SWI124 0 "memory_operand")
18613 (match_operand:SWI124 1 "immediate_operand"))]
18614 "optimize_insn_for_speed_p ()
18615 && ((<MODE>mode == HImode
18616 && TARGET_LCP_STALL)
18617 || (TARGET_SPLIT_LONG_MOVES
18618 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18619 [(set (match_dup 2) (match_dup 1))
18620 (set (match_dup 0) (match_dup 2))])
18622 ;; Don't compare memory with zero, load and use a test instead.
18624 [(set (match_operand 0 "flags_reg_operand")
18625 (match_operator 1 "compare_operator"
18626 [(match_operand:SI 2 "memory_operand")
18628 (match_scratch:SI 3 "r")]
18629 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18630 [(set (match_dup 3) (match_dup 2))
18631 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18633 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18634 ;; Don't split NOTs with a displacement operand, because resulting XOR
18635 ;; will not be pairable anyway.
18637 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18638 ;; represented using a modRM byte. The XOR replacement is long decoded,
18639 ;; so this split helps here as well.
18641 ;; Note: Can't do this as a regular split because we can't get proper
18642 ;; lifetime information then.
18645 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18646 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18647 "optimize_insn_for_speed_p ()
18648 && ((TARGET_NOT_UNPAIRABLE
18649 && (!MEM_P (operands[0])
18650 || !memory_displacement_operand (operands[0], <MODE>mode)))
18651 || (TARGET_NOT_VECTORMODE
18652 && long_memory_operand (operands[0], <MODE>mode)))
18653 && peep2_regno_dead_p (0, FLAGS_REG)"
18654 [(parallel [(set (match_dup 0)
18655 (xor:SWI124 (match_dup 1) (const_int -1)))
18656 (clobber (reg:CC FLAGS_REG))])])
18658 ;; Non pairable "test imm, reg" instructions can be translated to
18659 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18660 ;; byte opcode instead of two, have a short form for byte operands),
18661 ;; so do it for other CPUs as well. Given that the value was dead,
18662 ;; this should not create any new dependencies. Pass on the sub-word
18663 ;; versions if we're concerned about partial register stalls.
18666 [(set (match_operand 0 "flags_reg_operand")
18667 (match_operator 1 "compare_operator"
18668 [(and:SI (match_operand:SI 2 "register_operand")
18669 (match_operand:SI 3 "immediate_operand"))
18671 "ix86_match_ccmode (insn, CCNOmode)
18672 && (REGNO (operands[2]) != AX_REG
18673 || satisfies_constraint_K (operands[3]))
18674 && peep2_reg_dead_p (1, operands[2])"
18676 [(set (match_dup 0)
18677 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18680 (and:SI (match_dup 2) (match_dup 3)))])])
18682 ;; We don't need to handle HImode case, because it will be promoted to SImode
18683 ;; on ! TARGET_PARTIAL_REG_STALL
18686 [(set (match_operand 0 "flags_reg_operand")
18687 (match_operator 1 "compare_operator"
18688 [(and:QI (match_operand:QI 2 "register_operand")
18689 (match_operand:QI 3 "immediate_operand"))
18691 "! TARGET_PARTIAL_REG_STALL
18692 && ix86_match_ccmode (insn, CCNOmode)
18693 && REGNO (operands[2]) != AX_REG
18694 && peep2_reg_dead_p (1, operands[2])"
18696 [(set (match_dup 0)
18697 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18700 (and:QI (match_dup 2) (match_dup 3)))])])
18703 [(set (match_operand 0 "flags_reg_operand")
18704 (match_operator 1 "compare_operator"
18707 (zero_extract:SI (match_operand 2 "QIreg_operand")
18710 (match_operand 3 "const_int_operand"))
18712 "! TARGET_PARTIAL_REG_STALL
18713 && ix86_match_ccmode (insn, CCNOmode)
18714 && REGNO (operands[2]) != AX_REG
18715 && peep2_reg_dead_p (1, operands[2])"
18717 [(set (match_dup 0)
18721 (zero_extract:SI (match_dup 2)
18726 (set (zero_extract:SI (match_dup 2)
18732 (zero_extract:SI (match_dup 2)
18735 (match_dup 3)) 0))])])
18737 ;; Don't do logical operations with memory inputs.
18739 [(match_scratch:SWI 2 "<r>")
18740 (parallel [(set (match_operand:SWI 0 "register_operand")
18741 (match_operator:SWI 3 "arith_or_logical_operator"
18743 (match_operand:SWI 1 "memory_operand")]))
18744 (clobber (reg:CC FLAGS_REG))])]
18745 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18746 [(set (match_dup 2) (match_dup 1))
18747 (parallel [(set (match_dup 0)
18748 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18749 (clobber (reg:CC FLAGS_REG))])])
18752 [(match_scratch:SWI 2 "<r>")
18753 (parallel [(set (match_operand:SWI 0 "register_operand")
18754 (match_operator:SWI 3 "arith_or_logical_operator"
18755 [(match_operand:SWI 1 "memory_operand")
18757 (clobber (reg:CC FLAGS_REG))])]
18758 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18759 [(set (match_dup 2) (match_dup 1))
18760 (parallel [(set (match_dup 0)
18761 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18762 (clobber (reg:CC FLAGS_REG))])])
18764 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18765 ;; the memory address refers to the destination of the load!
18768 [(set (match_operand:SWI 0 "general_reg_operand")
18769 (match_operand:SWI 1 "general_reg_operand"))
18770 (parallel [(set (match_dup 0)
18771 (match_operator:SWI 3 "commutative_operator"
18773 (match_operand:SWI 2 "memory_operand")]))
18774 (clobber (reg:CC FLAGS_REG))])]
18775 "REGNO (operands[0]) != REGNO (operands[1])
18776 && (<MODE>mode != QImode
18777 || any_QIreg_operand (operands[1], QImode))"
18778 [(set (match_dup 0) (match_dup 4))
18779 (parallel [(set (match_dup 0)
18780 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18781 (clobber (reg:CC FLAGS_REG))])]
18782 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18785 [(set (match_operand 0 "mmx_reg_operand")
18786 (match_operand 1 "mmx_reg_operand"))
18788 (match_operator 3 "commutative_operator"
18790 (match_operand 2 "memory_operand")]))]
18791 "REGNO (operands[0]) != REGNO (operands[1])"
18792 [(set (match_dup 0) (match_dup 2))
18794 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18797 [(set (match_operand 0 "sse_reg_operand")
18798 (match_operand 1 "sse_reg_operand"))
18800 (match_operator 3 "commutative_operator"
18802 (match_operand 2 "memory_operand")]))]
18803 "REGNO (operands[0]) != REGNO (operands[1])"
18804 [(set (match_dup 0) (match_dup 2))
18806 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18808 ; Don't do logical operations with memory outputs
18810 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18811 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18812 ; the same decoder scheduling characteristics as the original.
18815 [(match_scratch:SWI 2 "<r>")
18816 (parallel [(set (match_operand:SWI 0 "memory_operand")
18817 (match_operator:SWI 3 "arith_or_logical_operator"
18819 (match_operand:SWI 1 "<nonmemory_operand>")]))
18820 (clobber (reg:CC FLAGS_REG))])]
18821 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18822 [(set (match_dup 2) (match_dup 0))
18823 (parallel [(set (match_dup 2)
18824 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18825 (clobber (reg:CC FLAGS_REG))])
18826 (set (match_dup 0) (match_dup 2))])
18829 [(match_scratch:SWI 2 "<r>")
18830 (parallel [(set (match_operand:SWI 0 "memory_operand")
18831 (match_operator:SWI 3 "arith_or_logical_operator"
18832 [(match_operand:SWI 1 "<nonmemory_operand>")
18834 (clobber (reg:CC FLAGS_REG))])]
18835 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18836 [(set (match_dup 2) (match_dup 0))
18837 (parallel [(set (match_dup 2)
18838 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18839 (clobber (reg:CC FLAGS_REG))])
18840 (set (match_dup 0) (match_dup 2))])
18842 ;; Attempt to use arith or logical operations with memory outputs with
18843 ;; setting of flags.
18845 [(set (match_operand:SWI 0 "register_operand")
18846 (match_operand:SWI 1 "memory_operand"))
18847 (parallel [(set (match_dup 0)
18848 (match_operator:SWI 3 "plusminuslogic_operator"
18850 (match_operand:SWI 2 "<nonmemory_operand>")]))
18851 (clobber (reg:CC FLAGS_REG))])
18852 (set (match_dup 1) (match_dup 0))
18853 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18854 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18855 && peep2_reg_dead_p (4, operands[0])
18856 && !reg_overlap_mentioned_p (operands[0], operands[1])
18857 && !reg_overlap_mentioned_p (operands[0], operands[2])
18858 && (<MODE>mode != QImode
18859 || immediate_operand (operands[2], QImode)
18860 || any_QIreg_operand (operands[2], QImode))
18861 && ix86_match_ccmode (peep2_next_insn (3),
18862 (GET_CODE (operands[3]) == PLUS
18863 || GET_CODE (operands[3]) == MINUS)
18864 ? CCGOCmode : CCNOmode)"
18865 [(parallel [(set (match_dup 4) (match_dup 6))
18866 (set (match_dup 1) (match_dup 5))])]
18868 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18870 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18871 copy_rtx (operands[1]),
18874 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18875 copy_rtx (operands[5]),
18879 ;; Likewise for cmpelim optimized pattern.
18881 [(set (match_operand:SWI 0 "register_operand")
18882 (match_operand:SWI 1 "memory_operand"))
18883 (parallel [(set (reg FLAGS_REG)
18884 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18886 (match_operand:SWI 2 "<nonmemory_operand>")])
18888 (set (match_dup 0) (match_dup 3))])
18889 (set (match_dup 1) (match_dup 0))]
18890 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18891 && peep2_reg_dead_p (3, operands[0])
18892 && !reg_overlap_mentioned_p (operands[0], operands[1])
18893 && !reg_overlap_mentioned_p (operands[0], operands[2])
18894 && ix86_match_ccmode (peep2_next_insn (1),
18895 (GET_CODE (operands[3]) == PLUS
18896 || GET_CODE (operands[3]) == MINUS)
18897 ? CCGOCmode : CCNOmode)"
18898 [(parallel [(set (match_dup 4) (match_dup 6))
18899 (set (match_dup 1) (match_dup 5))])]
18901 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18903 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18904 copy_rtx (operands[1]), operands[2]);
18906 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18910 ;; Likewise for instances where we have a lea pattern.
18912 [(set (match_operand:SWI 0 "register_operand")
18913 (match_operand:SWI 1 "memory_operand"))
18914 (set (match_operand:<LEAMODE> 3 "register_operand")
18915 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18916 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18917 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18918 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18919 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18920 && REGNO (operands[4]) == REGNO (operands[0])
18921 && REGNO (operands[5]) == REGNO (operands[3])
18922 && peep2_reg_dead_p (4, operands[3])
18923 && ((REGNO (operands[0]) == REGNO (operands[3]))
18924 || peep2_reg_dead_p (2, operands[0]))
18925 && !reg_overlap_mentioned_p (operands[0], operands[1])
18926 && !reg_overlap_mentioned_p (operands[3], operands[1])
18927 && !reg_overlap_mentioned_p (operands[0], operands[2])
18928 && (<MODE>mode != QImode
18929 || immediate_operand (operands[2], QImode)
18930 || any_QIreg_operand (operands[2], QImode))
18931 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18932 [(parallel [(set (match_dup 6) (match_dup 8))
18933 (set (match_dup 1) (match_dup 7))])]
18935 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18937 = gen_rtx_PLUS (<MODE>mode,
18938 copy_rtx (operands[1]),
18939 gen_lowpart (<MODE>mode, operands[2]));
18941 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18942 copy_rtx (operands[7]),
18947 [(parallel [(set (match_operand:SWI 0 "register_operand")
18948 (match_operator:SWI 2 "plusminuslogic_operator"
18950 (match_operand:SWI 1 "memory_operand")]))
18951 (clobber (reg:CC FLAGS_REG))])
18952 (set (match_dup 1) (match_dup 0))
18953 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18954 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18955 && COMMUTATIVE_ARITH_P (operands[2])
18956 && peep2_reg_dead_p (3, operands[0])
18957 && !reg_overlap_mentioned_p (operands[0], operands[1])
18958 && ix86_match_ccmode (peep2_next_insn (2),
18959 GET_CODE (operands[2]) == PLUS
18960 ? CCGOCmode : CCNOmode)"
18961 [(parallel [(set (match_dup 3) (match_dup 5))
18962 (set (match_dup 1) (match_dup 4))])]
18964 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18966 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18967 copy_rtx (operands[1]),
18970 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18971 copy_rtx (operands[4]),
18975 ;; Likewise for cmpelim optimized pattern.
18977 [(parallel [(set (reg FLAGS_REG)
18978 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18979 [(match_operand:SWI 0 "register_operand")
18980 (match_operand:SWI 1 "memory_operand")])
18982 (set (match_dup 0) (match_dup 2))])
18983 (set (match_dup 1) (match_dup 0))]
18984 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18985 && COMMUTATIVE_ARITH_P (operands[2])
18986 && peep2_reg_dead_p (2, operands[0])
18987 && !reg_overlap_mentioned_p (operands[0], operands[1])
18988 && ix86_match_ccmode (peep2_next_insn (0),
18989 GET_CODE (operands[2]) == PLUS
18990 ? CCGOCmode : CCNOmode)"
18991 [(parallel [(set (match_dup 3) (match_dup 5))
18992 (set (match_dup 1) (match_dup 4))])]
18994 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18996 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18997 copy_rtx (operands[1]), operands[0]);
18999 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19004 [(set (match_operand:SWI12 0 "register_operand")
19005 (match_operand:SWI12 1 "memory_operand"))
19006 (parallel [(set (match_operand:SI 4 "register_operand")
19007 (match_operator:SI 3 "plusminuslogic_operator"
19009 (match_operand:SI 2 "nonmemory_operand")]))
19010 (clobber (reg:CC FLAGS_REG))])
19011 (set (match_dup 1) (match_dup 0))
19012 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19013 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19014 && REGNO (operands[0]) == REGNO (operands[4])
19015 && peep2_reg_dead_p (4, operands[0])
19016 && (<MODE>mode != QImode
19017 || immediate_operand (operands[2], SImode)
19018 || any_QIreg_operand (operands[2], SImode))
19019 && !reg_overlap_mentioned_p (operands[0], operands[1])
19020 && !reg_overlap_mentioned_p (operands[0], operands[2])
19021 && ix86_match_ccmode (peep2_next_insn (3),
19022 (GET_CODE (operands[3]) == PLUS
19023 || GET_CODE (operands[3]) == MINUS)
19024 ? CCGOCmode : CCNOmode)"
19025 [(parallel [(set (match_dup 5) (match_dup 7))
19026 (set (match_dup 1) (match_dup 6))])]
19028 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
19030 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19031 copy_rtx (operands[1]),
19032 gen_lowpart (<MODE>mode, operands[2]));
19034 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19035 copy_rtx (operands[6]),
19039 ;; peephole2 comes before regcprop, so deal also with a case that
19040 ;; would be cleaned up by regcprop.
19042 [(set (match_operand:SWI 0 "register_operand")
19043 (match_operand:SWI 1 "memory_operand"))
19044 (parallel [(set (match_dup 0)
19045 (match_operator:SWI 3 "plusminuslogic_operator"
19047 (match_operand:SWI 2 "<nonmemory_operand>")]))
19048 (clobber (reg:CC FLAGS_REG))])
19049 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19050 (set (match_dup 1) (match_dup 4))
19051 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
19052 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19053 && peep2_reg_dead_p (3, operands[0])
19054 && peep2_reg_dead_p (5, operands[4])
19055 && !reg_overlap_mentioned_p (operands[0], operands[1])
19056 && !reg_overlap_mentioned_p (operands[0], operands[2])
19057 && !reg_overlap_mentioned_p (operands[4], operands[1])
19058 && (<MODE>mode != QImode
19059 || immediate_operand (operands[2], QImode)
19060 || any_QIreg_operand (operands[2], QImode))
19061 && ix86_match_ccmode (peep2_next_insn (4),
19062 (GET_CODE (operands[3]) == PLUS
19063 || GET_CODE (operands[3]) == MINUS)
19064 ? CCGOCmode : CCNOmode)"
19065 [(parallel [(set (match_dup 5) (match_dup 7))
19066 (set (match_dup 1) (match_dup 6))])]
19068 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
19070 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19071 copy_rtx (operands[1]),
19074 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19075 copy_rtx (operands[6]),
19080 [(set (match_operand:SWI12 0 "register_operand")
19081 (match_operand:SWI12 1 "memory_operand"))
19082 (parallel [(set (match_operand:SI 4 "register_operand")
19083 (match_operator:SI 3 "plusminuslogic_operator"
19085 (match_operand:SI 2 "nonmemory_operand")]))
19086 (clobber (reg:CC FLAGS_REG))])
19087 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
19088 (set (match_dup 1) (match_dup 5))
19089 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19090 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19091 && REGNO (operands[0]) == REGNO (operands[4])
19092 && peep2_reg_dead_p (3, operands[0])
19093 && peep2_reg_dead_p (5, operands[5])
19094 && (<MODE>mode != QImode
19095 || immediate_operand (operands[2], SImode)
19096 || any_QIreg_operand (operands[2], SImode))
19097 && !reg_overlap_mentioned_p (operands[0], operands[1])
19098 && !reg_overlap_mentioned_p (operands[0], operands[2])
19099 && !reg_overlap_mentioned_p (operands[5], operands[1])
19100 && ix86_match_ccmode (peep2_next_insn (4),
19101 (GET_CODE (operands[3]) == PLUS
19102 || GET_CODE (operands[3]) == MINUS)
19103 ? CCGOCmode : CCNOmode)"
19104 [(parallel [(set (match_dup 6) (match_dup 8))
19105 (set (match_dup 1) (match_dup 7))])]
19107 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
19109 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19110 copy_rtx (operands[1]),
19111 gen_lowpart (<MODE>mode, operands[2]));
19113 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19114 copy_rtx (operands[7]),
19118 ;; Likewise for cmpelim optimized pattern.
19120 [(set (match_operand:SWI 0 "register_operand")
19121 (match_operand:SWI 1 "memory_operand"))
19122 (parallel [(set (reg FLAGS_REG)
19123 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19125 (match_operand:SWI 2 "<nonmemory_operand>")])
19127 (set (match_dup 0) (match_dup 3))])
19128 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19129 (set (match_dup 1) (match_dup 4))]
19130 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19131 && peep2_reg_dead_p (3, operands[0])
19132 && peep2_reg_dead_p (4, operands[4])
19133 && !reg_overlap_mentioned_p (operands[0], operands[1])
19134 && !reg_overlap_mentioned_p (operands[0], operands[2])
19135 && !reg_overlap_mentioned_p (operands[4], operands[1])
19136 && ix86_match_ccmode (peep2_next_insn (1),
19137 (GET_CODE (operands[3]) == PLUS
19138 || GET_CODE (operands[3]) == MINUS)
19139 ? CCGOCmode : CCNOmode)"
19140 [(parallel [(set (match_dup 5) (match_dup 7))
19141 (set (match_dup 1) (match_dup 6))])]
19143 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19145 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19146 copy_rtx (operands[1]), operands[2]);
19148 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
19152 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
19153 ;; into x = z; x ^= y; x != z
19155 [(set (match_operand:SWI 0 "register_operand")
19156 (match_operand:SWI 1 "memory_operand"))
19157 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
19158 (parallel [(set (match_operand:SWI 4 "register_operand")
19159 (xor:SWI (match_dup 4)
19160 (match_operand:SWI 2 "<nonmemory_operand>")))
19161 (clobber (reg:CC FLAGS_REG))])
19162 (set (match_dup 1) (match_dup 4))
19163 (set (reg:CCZ FLAGS_REG)
19164 (compare:CCZ (match_operand:SWI 5 "register_operand")
19165 (match_operand:SWI 6 "<nonmemory_operand>")))]
19166 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19167 && (REGNO (operands[4]) == REGNO (operands[0])
19168 || REGNO (operands[4]) == REGNO (operands[3]))
19169 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19170 ? 3 : 0], operands[5])
19171 ? rtx_equal_p (operands[2], operands[6])
19172 : rtx_equal_p (operands[2], operands[5])
19173 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19174 ? 3 : 0], operands[6]))
19175 && peep2_reg_dead_p (4, operands[4])
19176 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
19178 && !reg_overlap_mentioned_p (operands[0], operands[1])
19179 && !reg_overlap_mentioned_p (operands[0], operands[2])
19180 && !reg_overlap_mentioned_p (operands[3], operands[0])
19181 && !reg_overlap_mentioned_p (operands[3], operands[1])
19182 && !reg_overlap_mentioned_p (operands[3], operands[2])
19183 && (<MODE>mode != QImode
19184 || immediate_operand (operands[2], QImode)
19185 || any_QIreg_operand (operands[2], QImode))"
19186 [(parallel [(set (match_dup 7) (match_dup 9))
19187 (set (match_dup 1) (match_dup 8))])]
19189 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
19190 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19193 = gen_rtx_COMPARE (GET_MODE (operands[7]),
19194 copy_rtx (operands[8]),
19199 [(set (match_operand:SWI12 0 "register_operand")
19200 (match_operand:SWI12 1 "memory_operand"))
19201 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
19202 (parallel [(set (match_operand:SI 4 "register_operand")
19203 (xor:SI (match_dup 4)
19204 (match_operand:SI 2 "<nonmemory_operand>")))
19205 (clobber (reg:CC FLAGS_REG))])
19206 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
19207 (set (reg:CCZ FLAGS_REG)
19208 (compare:CCZ (match_operand:SWI12 6 "register_operand")
19209 (match_operand:SWI12 7 "<nonmemory_operand>")))]
19210 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19211 && (REGNO (operands[5]) == REGNO (operands[0])
19212 || REGNO (operands[5]) == REGNO (operands[3]))
19213 && REGNO (operands[5]) == REGNO (operands[4])
19214 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19215 ? 3 : 0], operands[6])
19216 ? (REG_P (operands[2])
19217 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
19218 : rtx_equal_p (operands[2], operands[7]))
19219 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19220 ? 3 : 0], operands[7])
19221 && REG_P (operands[2])
19222 && REGNO (operands[2]) == REGNO (operands[6])))
19223 && peep2_reg_dead_p (4, operands[5])
19224 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
19226 && !reg_overlap_mentioned_p (operands[0], operands[1])
19227 && !reg_overlap_mentioned_p (operands[0], operands[2])
19228 && !reg_overlap_mentioned_p (operands[3], operands[0])
19229 && !reg_overlap_mentioned_p (operands[3], operands[1])
19230 && !reg_overlap_mentioned_p (operands[3], operands[2])
19231 && (<MODE>mode != QImode
19232 || immediate_operand (operands[2], SImode)
19233 || any_QIreg_operand (operands[2], SImode))"
19234 [(parallel [(set (match_dup 8) (match_dup 10))
19235 (set (match_dup 1) (match_dup 9))])]
19237 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
19238 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19239 gen_lowpart (<MODE>mode, operands[2]));
19241 = gen_rtx_COMPARE (GET_MODE (operands[8]),
19242 copy_rtx (operands[9]),
19246 ;; Attempt to optimize away memory stores of values the memory already
19247 ;; has. See PR79593.
19249 [(set (match_operand 0 "register_operand")
19250 (match_operand 1 "memory_operand"))
19251 (set (match_operand 2 "memory_operand") (match_dup 0))]
19252 "!MEM_VOLATILE_P (operands[1])
19253 && !MEM_VOLATILE_P (operands[2])
19254 && rtx_equal_p (operands[1], operands[2])
19255 && !reg_overlap_mentioned_p (operands[0], operands[2])"
19256 [(set (match_dup 0) (match_dup 1))])
19258 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19260 [(set (match_operand 0 "general_reg_operand")
19261 (match_operand 1 "const0_operand"))]
19262 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19263 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19264 && peep2_regno_dead_p (0, FLAGS_REG)"
19265 [(parallel [(set (match_dup 0) (const_int 0))
19266 (clobber (reg:CC FLAGS_REG))])]
19267 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19270 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19272 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19273 && peep2_regno_dead_p (0, FLAGS_REG)"
19274 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19275 (clobber (reg:CC FLAGS_REG))])])
19277 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19279 [(set (match_operand:SWI248 0 "general_reg_operand")
19281 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19282 && peep2_regno_dead_p (0, FLAGS_REG)"
19283 [(parallel [(set (match_dup 0) (const_int -1))
19284 (clobber (reg:CC FLAGS_REG))])]
19286 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19287 operands[0] = gen_lowpart (SImode, operands[0]);
19290 ;; Attempt to convert simple lea to add/shift.
19291 ;; These can be created by move expanders.
19292 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19293 ;; relevant lea instructions were already split.
19296 [(set (match_operand:SWI48 0 "register_operand")
19297 (plus:SWI48 (match_dup 0)
19298 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19300 && peep2_regno_dead_p (0, FLAGS_REG)"
19301 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19302 (clobber (reg:CC FLAGS_REG))])])
19305 [(set (match_operand:SWI48 0 "register_operand")
19306 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19309 && peep2_regno_dead_p (0, FLAGS_REG)"
19310 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19311 (clobber (reg:CC FLAGS_REG))])])
19314 [(set (match_operand:DI 0 "register_operand")
19316 (plus:SI (match_operand:SI 1 "register_operand")
19317 (match_operand:SI 2 "nonmemory_operand"))))]
19318 "TARGET_64BIT && !TARGET_OPT_AGU
19319 && REGNO (operands[0]) == REGNO (operands[1])
19320 && peep2_regno_dead_p (0, FLAGS_REG)"
19321 [(parallel [(set (match_dup 0)
19322 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19323 (clobber (reg:CC FLAGS_REG))])])
19326 [(set (match_operand:DI 0 "register_operand")
19328 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19329 (match_operand:SI 2 "register_operand"))))]
19330 "TARGET_64BIT && !TARGET_OPT_AGU
19331 && REGNO (operands[0]) == REGNO (operands[2])
19332 && peep2_regno_dead_p (0, FLAGS_REG)"
19333 [(parallel [(set (match_dup 0)
19334 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19335 (clobber (reg:CC FLAGS_REG))])])
19338 [(set (match_operand:SWI48 0 "register_operand")
19339 (mult:SWI48 (match_dup 0)
19340 (match_operand:SWI48 1 "const_int_operand")))]
19341 "pow2p_hwi (INTVAL (operands[1]))
19342 && peep2_regno_dead_p (0, FLAGS_REG)"
19343 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19344 (clobber (reg:CC FLAGS_REG))])]
19345 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19348 [(set (match_operand:DI 0 "register_operand")
19350 (mult:SI (match_operand:SI 1 "register_operand")
19351 (match_operand:SI 2 "const_int_operand"))))]
19353 && pow2p_hwi (INTVAL (operands[2]))
19354 && REGNO (operands[0]) == REGNO (operands[1])
19355 && peep2_regno_dead_p (0, FLAGS_REG)"
19356 [(parallel [(set (match_dup 0)
19357 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19358 (clobber (reg:CC FLAGS_REG))])]
19359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19361 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19362 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19363 ;; On many CPUs it is also faster, since special hardware to avoid esp
19364 ;; dependencies is present.
19366 ;; While some of these conversions may be done using splitters, we use
19367 ;; peepholes in order to allow combine_stack_adjustments pass to see
19368 ;; nonobfuscated RTL.
19370 ;; Convert prologue esp subtractions to push.
19371 ;; We need register to push. In order to keep verify_flow_info happy we have
19373 ;; - use scratch and clobber it in order to avoid dependencies
19374 ;; - use already live register
19375 ;; We can't use the second way right now, since there is no reliable way how to
19376 ;; verify that given register is live. First choice will also most likely in
19377 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19378 ;; call clobbered registers are dead. We may want to use base pointer as an
19379 ;; alternative when no register is available later.
19382 [(match_scratch:W 1 "r")
19383 (parallel [(set (reg:P SP_REG)
19384 (plus:P (reg:P SP_REG)
19385 (match_operand:P 0 "const_int_operand")))
19386 (clobber (reg:CC FLAGS_REG))
19387 (clobber (mem:BLK (scratch)))])]
19388 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19389 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19390 && ix86_red_zone_size == 0"
19391 [(clobber (match_dup 1))
19392 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19393 (clobber (mem:BLK (scratch)))])])
19396 [(match_scratch:W 1 "r")
19397 (parallel [(set (reg:P SP_REG)
19398 (plus:P (reg:P SP_REG)
19399 (match_operand:P 0 "const_int_operand")))
19400 (clobber (reg:CC FLAGS_REG))
19401 (clobber (mem:BLK (scratch)))])]
19402 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19403 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19404 && ix86_red_zone_size == 0"
19405 [(clobber (match_dup 1))
19406 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19407 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19408 (clobber (mem:BLK (scratch)))])])
19410 ;; Convert esp subtractions to push.
19412 [(match_scratch:W 1 "r")
19413 (parallel [(set (reg:P SP_REG)
19414 (plus:P (reg:P SP_REG)
19415 (match_operand:P 0 "const_int_operand")))
19416 (clobber (reg:CC FLAGS_REG))])]
19417 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19418 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19419 && ix86_red_zone_size == 0"
19420 [(clobber (match_dup 1))
19421 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19424 [(match_scratch:W 1 "r")
19425 (parallel [(set (reg:P SP_REG)
19426 (plus:P (reg:P SP_REG)
19427 (match_operand:P 0 "const_int_operand")))
19428 (clobber (reg:CC FLAGS_REG))])]
19429 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19430 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19431 && ix86_red_zone_size == 0"
19432 [(clobber (match_dup 1))
19433 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19434 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19436 ;; Convert epilogue deallocator to pop.
19438 [(match_scratch:W 1 "r")
19439 (parallel [(set (reg:P SP_REG)
19440 (plus:P (reg:P SP_REG)
19441 (match_operand:P 0 "const_int_operand")))
19442 (clobber (reg:CC FLAGS_REG))
19443 (clobber (mem:BLK (scratch)))])]
19444 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19445 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19446 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19447 (clobber (mem:BLK (scratch)))])])
19449 ;; Two pops case is tricky, since pop causes dependency
19450 ;; on destination register. We use two registers if available.
19452 [(match_scratch:W 1 "r")
19453 (match_scratch:W 2 "r")
19454 (parallel [(set (reg:P SP_REG)
19455 (plus:P (reg:P SP_REG)
19456 (match_operand:P 0 "const_int_operand")))
19457 (clobber (reg:CC FLAGS_REG))
19458 (clobber (mem:BLK (scratch)))])]
19459 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19460 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19461 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19462 (clobber (mem:BLK (scratch)))])
19463 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19466 [(match_scratch:W 1 "r")
19467 (parallel [(set (reg:P SP_REG)
19468 (plus:P (reg:P SP_REG)
19469 (match_operand:P 0 "const_int_operand")))
19470 (clobber (reg:CC FLAGS_REG))
19471 (clobber (mem:BLK (scratch)))])]
19472 "optimize_insn_for_size_p ()
19473 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19474 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19475 (clobber (mem:BLK (scratch)))])
19476 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19478 ;; Convert esp additions to pop.
19480 [(match_scratch:W 1 "r")
19481 (parallel [(set (reg:P SP_REG)
19482 (plus:P (reg:P SP_REG)
19483 (match_operand:P 0 "const_int_operand")))
19484 (clobber (reg:CC FLAGS_REG))])]
19485 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19486 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19488 ;; Two pops case is tricky, since pop causes dependency
19489 ;; on destination register. We use two registers if available.
19491 [(match_scratch:W 1 "r")
19492 (match_scratch:W 2 "r")
19493 (parallel [(set (reg:P SP_REG)
19494 (plus:P (reg:P SP_REG)
19495 (match_operand:P 0 "const_int_operand")))
19496 (clobber (reg:CC FLAGS_REG))])]
19497 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19498 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19499 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19502 [(match_scratch:W 1 "r")
19503 (parallel [(set (reg:P SP_REG)
19504 (plus:P (reg:P SP_REG)
19505 (match_operand:P 0 "const_int_operand")))
19506 (clobber (reg:CC FLAGS_REG))])]
19507 "optimize_insn_for_size_p ()
19508 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19509 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19510 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19512 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19513 ;; required and register dies. Similarly for 128 to -128.
19515 [(set (match_operand 0 "flags_reg_operand")
19516 (match_operator 1 "compare_operator"
19517 [(match_operand 2 "register_operand")
19518 (match_operand 3 "const_int_operand")]))]
19519 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19520 && incdec_operand (operands[3], GET_MODE (operands[3])))
19521 || (!TARGET_FUSE_CMP_AND_BRANCH
19522 && INTVAL (operands[3]) == 128))
19523 && ix86_match_ccmode (insn, CCGCmode)
19524 && peep2_reg_dead_p (1, operands[2])"
19525 [(parallel [(set (match_dup 0)
19526 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19527 (clobber (match_dup 2))])])
19529 ;; Convert imul by three, five and nine into lea
19532 [(set (match_operand:SWI48 0 "register_operand")
19533 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19534 (match_operand:SWI48 2 "const359_operand")))
19535 (clobber (reg:CC FLAGS_REG))])]
19536 "!TARGET_PARTIAL_REG_STALL
19537 || <MODE>mode == SImode
19538 || optimize_function_for_size_p (cfun)"
19539 [(set (match_dup 0)
19540 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19542 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19546 [(set (match_operand:SWI48 0 "register_operand")
19547 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19548 (match_operand:SWI48 2 "const359_operand")))
19549 (clobber (reg:CC FLAGS_REG))])]
19550 "optimize_insn_for_speed_p ()
19551 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19552 [(set (match_dup 0) (match_dup 1))
19554 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19556 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19558 ;; imul $32bit_imm, mem, reg is vector decoded, while
19559 ;; imul $32bit_imm, reg, reg is direct decoded.
19561 [(match_scratch:SWI48 3 "r")
19562 (parallel [(set (match_operand:SWI48 0 "register_operand")
19563 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19564 (match_operand:SWI48 2 "immediate_operand")))
19565 (clobber (reg:CC FLAGS_REG))])]
19566 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19567 && !satisfies_constraint_K (operands[2])"
19568 [(set (match_dup 3) (match_dup 1))
19569 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19570 (clobber (reg:CC FLAGS_REG))])])
19573 [(match_scratch:SI 3 "r")
19574 (parallel [(set (match_operand:DI 0 "register_operand")
19576 (mult:SI (match_operand:SI 1 "memory_operand")
19577 (match_operand:SI 2 "immediate_operand"))))
19578 (clobber (reg:CC FLAGS_REG))])]
19580 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19581 && !satisfies_constraint_K (operands[2])"
19582 [(set (match_dup 3) (match_dup 1))
19583 (parallel [(set (match_dup 0)
19584 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19585 (clobber (reg:CC FLAGS_REG))])])
19587 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19588 ;; Convert it into imul reg, reg
19589 ;; It would be better to force assembler to encode instruction using long
19590 ;; immediate, but there is apparently no way to do so.
19592 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19594 (match_operand:SWI248 1 "nonimmediate_operand")
19595 (match_operand:SWI248 2 "const_int_operand")))
19596 (clobber (reg:CC FLAGS_REG))])
19597 (match_scratch:SWI248 3 "r")]
19598 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19599 && satisfies_constraint_K (operands[2])"
19600 [(set (match_dup 3) (match_dup 2))
19601 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19602 (clobber (reg:CC FLAGS_REG))])]
19604 if (!rtx_equal_p (operands[0], operands[1]))
19605 emit_move_insn (operands[0], operands[1]);
19608 ;; After splitting up read-modify operations, array accesses with memory
19609 ;; operands might end up in form:
19611 ;; movl 4(%esp), %edx
19613 ;; instead of pre-splitting:
19615 ;; addl 4(%esp), %eax
19617 ;; movl 4(%esp), %edx
19618 ;; leal (%edx,%eax,4), %eax
19621 [(match_scratch:W 5 "r")
19622 (parallel [(set (match_operand 0 "register_operand")
19623 (ashift (match_operand 1 "register_operand")
19624 (match_operand 2 "const_int_operand")))
19625 (clobber (reg:CC FLAGS_REG))])
19626 (parallel [(set (match_operand 3 "register_operand")
19627 (plus (match_dup 0)
19628 (match_operand 4 "x86_64_general_operand")))
19629 (clobber (reg:CC FLAGS_REG))])]
19630 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19631 /* Validate MODE for lea. */
19632 && ((!TARGET_PARTIAL_REG_STALL
19633 && (GET_MODE (operands[0]) == QImode
19634 || GET_MODE (operands[0]) == HImode))
19635 || GET_MODE (operands[0]) == SImode
19636 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19637 && (rtx_equal_p (operands[0], operands[3])
19638 || peep2_reg_dead_p (2, operands[0]))
19639 /* We reorder load and the shift. */
19640 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19641 [(set (match_dup 5) (match_dup 4))
19642 (set (match_dup 0) (match_dup 1))]
19644 machine_mode op1mode = GET_MODE (operands[1]);
19645 machine_mode mode = op1mode == DImode ? DImode : SImode;
19646 int scale = 1 << INTVAL (operands[2]);
19647 rtx index = gen_lowpart (word_mode, operands[1]);
19648 rtx base = gen_lowpart (word_mode, operands[5]);
19649 rtx dest = gen_lowpart (mode, operands[3]);
19651 operands[1] = gen_rtx_PLUS (word_mode, base,
19652 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19653 if (mode != word_mode)
19654 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19656 operands[5] = base;
19657 if (op1mode != word_mode)
19658 operands[5] = gen_lowpart (op1mode, operands[5]);
19660 operands[0] = dest;
19663 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19664 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19665 ;; caught for use by garbage collectors and the like. Using an insn that
19666 ;; maps to SIGILL makes it more likely the program will rightfully die.
19667 ;; Keeping with tradition, "6" is in honor of #UD.
19668 (define_insn "trap"
19669 [(trap_if (const_int 1) (const_int 6))]
19672 #ifdef HAVE_AS_IX86_UD2
19675 return ASM_SHORT "0x0b0f";
19678 [(set_attr "length" "2")])
19681 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19684 #ifdef HAVE_AS_IX86_UD2
19687 return ASM_SHORT "0x0b0f";
19690 [(set_attr "length" "2")])
19692 (define_expand "prefetch"
19693 [(prefetch (match_operand 0 "address_operand")
19694 (match_operand:SI 1 "const_int_operand")
19695 (match_operand:SI 2 "const_int_operand"))]
19696 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19698 bool write = operands[1] != const0_rtx;
19699 int locality = INTVAL (operands[2]);
19701 gcc_assert (IN_RANGE (locality, 0, 3));
19703 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19704 supported by SSE counterpart (non-SSE2 athlon machines) or the
19705 SSE prefetch is not available (K6 machines). Otherwise use SSE
19706 prefetch as it allows specifying of locality. */
19710 if (TARGET_PREFETCHWT1)
19711 operands[2] = GEN_INT (MAX (locality, 2));
19712 else if (TARGET_PRFCHW)
19713 operands[2] = GEN_INT (3);
19714 else if (TARGET_3DNOW && !TARGET_SSE2)
19715 operands[2] = GEN_INT (3);
19716 else if (TARGET_PREFETCH_SSE)
19717 operands[1] = const0_rtx;
19720 gcc_assert (TARGET_3DNOW);
19721 operands[2] = GEN_INT (3);
19726 if (TARGET_PREFETCH_SSE)
19730 gcc_assert (TARGET_3DNOW);
19731 operands[2] = GEN_INT (3);
19736 (define_insn "*prefetch_sse"
19737 [(prefetch (match_operand 0 "address_operand" "p")
19739 (match_operand:SI 1 "const_int_operand"))]
19740 "TARGET_PREFETCH_SSE"
19742 static const char * const patterns[4] = {
19743 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19746 int locality = INTVAL (operands[1]);
19747 gcc_assert (IN_RANGE (locality, 0, 3));
19749 return patterns[locality];
19751 [(set_attr "type" "sse")
19752 (set_attr "atom_sse_attr" "prefetch")
19753 (set (attr "length_address")
19754 (symbol_ref "memory_address_length (operands[0], false)"))
19755 (set_attr "memory" "none")])
19757 (define_insn "*prefetch_3dnow"
19758 [(prefetch (match_operand 0 "address_operand" "p")
19759 (match_operand:SI 1 "const_int_operand" "n")
19761 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19763 if (operands[1] == const0_rtx)
19764 return "prefetch\t%a0";
19766 return "prefetchw\t%a0";
19768 [(set_attr "type" "mmx")
19769 (set (attr "length_address")
19770 (symbol_ref "memory_address_length (operands[0], false)"))
19771 (set_attr "memory" "none")])
19773 (define_insn "*prefetch_prefetchwt1"
19774 [(prefetch (match_operand 0 "address_operand" "p")
19777 "TARGET_PREFETCHWT1"
19778 "prefetchwt1\t%a0";
19779 [(set_attr "type" "sse")
19780 (set (attr "length_address")
19781 (symbol_ref "memory_address_length (operands[0], false)"))
19782 (set_attr "memory" "none")])
19784 (define_expand "stack_protect_set"
19785 [(match_operand 0 "memory_operand")
19786 (match_operand 1 "memory_operand")]
19789 emit_insn (gen_stack_protect_set_1
19790 (ptr_mode, operands[0], operands[1]));
19794 (define_insn "@stack_protect_set_1_<mode>"
19795 [(set (match_operand:PTR 0 "memory_operand" "=m")
19796 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19798 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19799 (clobber (reg:CC FLAGS_REG))]
19802 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
19803 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
19804 return "xor{l}\t%k2, %k2";
19806 [(set_attr "type" "multi")])
19808 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
19809 ;; immediately followed by *mov{s,d}i_internal to the same register,
19810 ;; where we can avoid the xor{l} above. We don't split this, so that
19811 ;; scheduling or anything else doesn't separate the *stack_protect_set*
19812 ;; pattern from the set of the register that overwrites the register
19813 ;; with a new value.
19814 (define_insn "*stack_protect_set_2_<mode>"
19815 [(set (match_operand:PTR 0 "memory_operand" "=m")
19816 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
19818 (set (match_operand:SI 1 "register_operand" "=&r")
19819 (match_operand:SI 2 "general_operand" "g"))
19820 (clobber (reg:CC FLAGS_REG))]
19822 && !reg_overlap_mentioned_p (operands[1], operands[2])"
19824 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
19825 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
19826 if (pic_32bit_operand (operands[2], SImode)
19827 || ix86_use_lea_for_mov (insn, operands + 1))
19828 return "lea{l}\t{%E2, %1|%1, %E2}";
19830 return "mov{l}\t{%2, %1|%1, %2}";
19832 [(set_attr "type" "multi")
19833 (set_attr "length" "24")])
19836 [(parallel [(set (match_operand:PTR 0 "memory_operand")
19837 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
19839 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
19840 (clobber (reg:CC FLAGS_REG))])
19841 (set (match_operand:SI 3 "general_reg_operand")
19842 (match_operand:SI 4))]
19843 "REGNO (operands[2]) == REGNO (operands[3])
19844 && (general_reg_operand (operands[4], SImode)
19845 || memory_operand (operands[4], SImode)
19846 || immediate_operand (operands[4], SImode))
19847 && !reg_overlap_mentioned_p (operands[3], operands[4])"
19848 [(parallel [(set (match_dup 0)
19849 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
19850 (set (match_dup 3) (match_dup 4))
19851 (clobber (reg:CC FLAGS_REG))])])
19853 (define_insn "*stack_protect_set_3"
19854 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
19855 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
19857 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
19858 (match_operand:DI 2 "general_operand" "Z,rem,i"))
19859 (clobber (reg:CC FLAGS_REG))]
19861 && reload_completed
19862 && !reg_overlap_mentioned_p (operands[1], operands[2])"
19864 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
19865 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
19866 if (pic_32bit_operand (operands[2], DImode))
19867 return "lea{q}\t{%E2, %1|%1, %E2}";
19868 else if (which_alternative == 0)
19869 return "mov{l}\t{%k2, %k1|%k1, %k2}";
19870 else if (which_alternative == 2)
19871 return "movabs{q}\t{%2, %1|%1, %2}";
19872 else if (ix86_use_lea_for_mov (insn, operands + 1))
19873 return "lea{q}\t{%E2, %1|%1, %E2}";
19875 return "mov{q}\t{%2, %1|%1, %2}";
19877 [(set_attr "type" "multi")
19878 (set_attr "length" "24")])
19881 [(parallel [(set (match_operand:DI 0 "memory_operand")
19882 (unspec:DI [(match_operand:DI 1 "memory_operand")]
19884 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
19885 (clobber (reg:CC FLAGS_REG))])
19886 (set (match_dup 2) (match_operand:DI 3))]
19888 && (general_reg_operand (operands[3], DImode)
19889 || memory_operand (operands[3], DImode)
19890 || x86_64_zext_immediate_operand (operands[3], DImode)
19891 || x86_64_immediate_operand (operands[3], DImode)
19892 || (CONSTANT_P (operands[3])
19893 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
19894 && !reg_overlap_mentioned_p (operands[2], operands[3])"
19895 [(parallel [(set (match_dup 0)
19896 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
19897 (set (match_dup 2) (match_dup 3))
19898 (clobber (reg:CC FLAGS_REG))])])
19900 (define_expand "stack_protect_test"
19901 [(match_operand 0 "memory_operand")
19902 (match_operand 1 "memory_operand")
19906 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19908 emit_insn (gen_stack_protect_test_1
19909 (ptr_mode, flags, operands[0], operands[1]));
19911 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19912 flags, const0_rtx, operands[2]));
19916 (define_insn "@stack_protect_test_1_<mode>"
19917 [(set (match_operand:CCZ 0 "flags_reg_operand")
19918 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19919 (match_operand:PTR 2 "memory_operand" "m")]
19921 (clobber (match_scratch:PTR 3 "=&r"))]
19924 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
19925 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
19927 [(set_attr "type" "multi")])
19929 (define_insn "sse4_2_crc32<mode>"
19930 [(set (match_operand:SI 0 "register_operand" "=r")
19932 [(match_operand:SI 1 "register_operand" "0")
19933 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19935 "TARGET_SSE4_2 || TARGET_CRC32"
19936 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19937 [(set_attr "type" "sselog1")
19938 (set_attr "prefix_rep" "1")
19939 (set_attr "prefix_extra" "1")
19940 (set (attr "prefix_data16")
19941 (if_then_else (match_operand:HI 2)
19943 (const_string "*")))
19944 (set (attr "prefix_rex")
19945 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19947 (const_string "*")))
19948 (set_attr "mode" "SI")])
19950 (define_insn "sse4_2_crc32di"
19951 [(set (match_operand:DI 0 "register_operand" "=r")
19953 [(match_operand:DI 1 "register_operand" "0")
19954 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19956 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19957 "crc32{q}\t{%2, %0|%0, %2}"
19958 [(set_attr "type" "sselog1")
19959 (set_attr "prefix_rep" "1")
19960 (set_attr "prefix_extra" "1")
19961 (set_attr "mode" "DI")])
19963 (define_insn "rdpmc"
19964 [(set (match_operand:DI 0 "register_operand" "=A")
19965 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19969 [(set_attr "type" "other")
19970 (set_attr "length" "2")])
19972 (define_insn "rdpmc_rex64"
19973 [(set (match_operand:DI 0 "register_operand" "=a")
19974 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19976 (set (match_operand:DI 1 "register_operand" "=d")
19977 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19980 [(set_attr "type" "other")
19981 (set_attr "length" "2")])
19983 (define_insn "rdtsc"
19984 [(set (match_operand:DI 0 "register_operand" "=A")
19985 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19988 [(set_attr "type" "other")
19989 (set_attr "length" "2")])
19991 (define_insn "rdtsc_rex64"
19992 [(set (match_operand:DI 0 "register_operand" "=a")
19993 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19994 (set (match_operand:DI 1 "register_operand" "=d")
19995 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19998 [(set_attr "type" "other")
19999 (set_attr "length" "2")])
20001 (define_insn "rdtscp"
20002 [(set (match_operand:DI 0 "register_operand" "=A")
20003 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20004 (set (match_operand:SI 1 "register_operand" "=c")
20005 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20008 [(set_attr "type" "other")
20009 (set_attr "length" "3")])
20011 (define_insn "rdtscp_rex64"
20012 [(set (match_operand:DI 0 "register_operand" "=a")
20013 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20014 (set (match_operand:DI 1 "register_operand" "=d")
20015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20016 (set (match_operand:SI 2 "register_operand" "=c")
20017 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20020 [(set_attr "type" "other")
20021 (set_attr "length" "3")])
20023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20025 ;; FXSR, XSAVE and XSAVEOPT instructions
20027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20029 (define_insn "fxsave"
20030 [(set (match_operand:BLK 0 "memory_operand" "=m")
20031 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20034 [(set_attr "type" "other")
20035 (set_attr "memory" "store")
20036 (set (attr "length")
20037 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20039 (define_insn "fxsave64"
20040 [(set (match_operand:BLK 0 "memory_operand" "=m")
20041 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20042 "TARGET_64BIT && TARGET_FXSR"
20044 [(set_attr "type" "other")
20045 (set_attr "memory" "store")
20046 (set (attr "length")
20047 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20049 (define_insn "fxrstor"
20050 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20054 [(set_attr "type" "other")
20055 (set_attr "memory" "load")
20056 (set (attr "length")
20057 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20059 (define_insn "fxrstor64"
20060 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20061 UNSPECV_FXRSTOR64)]
20062 "TARGET_64BIT && TARGET_FXSR"
20064 [(set_attr "type" "other")
20065 (set_attr "memory" "load")
20066 (set (attr "length")
20067 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20069 (define_int_iterator ANY_XSAVE
20071 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20072 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20073 (UNSPECV_XSAVES "TARGET_XSAVES")])
20075 (define_int_iterator ANY_XSAVE64
20077 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20078 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20079 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20081 (define_int_attr xsave
20082 [(UNSPECV_XSAVE "xsave")
20083 (UNSPECV_XSAVE64 "xsave64")
20084 (UNSPECV_XSAVEOPT "xsaveopt")
20085 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20086 (UNSPECV_XSAVEC "xsavec")
20087 (UNSPECV_XSAVEC64 "xsavec64")
20088 (UNSPECV_XSAVES "xsaves")
20089 (UNSPECV_XSAVES64 "xsaves64")])
20091 (define_int_iterator ANY_XRSTOR
20093 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20095 (define_int_iterator ANY_XRSTOR64
20097 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20099 (define_int_attr xrstor
20100 [(UNSPECV_XRSTOR "xrstor")
20101 (UNSPECV_XRSTOR64 "xrstor")
20102 (UNSPECV_XRSTORS "xrstors")
20103 (UNSPECV_XRSTORS64 "xrstors")])
20105 (define_insn "<xsave>"
20106 [(set (match_operand:BLK 0 "memory_operand" "=m")
20107 (unspec_volatile:BLK
20108 [(match_operand:DI 1 "register_operand" "A")]
20110 "!TARGET_64BIT && TARGET_XSAVE"
20112 [(set_attr "type" "other")
20113 (set_attr "memory" "store")
20114 (set (attr "length")
20115 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20117 (define_insn "<xsave>_rex64"
20118 [(set (match_operand:BLK 0 "memory_operand" "=m")
20119 (unspec_volatile:BLK
20120 [(match_operand:SI 1 "register_operand" "a")
20121 (match_operand:SI 2 "register_operand" "d")]
20123 "TARGET_64BIT && TARGET_XSAVE"
20125 [(set_attr "type" "other")
20126 (set_attr "memory" "store")
20127 (set (attr "length")
20128 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20130 (define_insn "<xsave>"
20131 [(set (match_operand:BLK 0 "memory_operand" "=m")
20132 (unspec_volatile:BLK
20133 [(match_operand:SI 1 "register_operand" "a")
20134 (match_operand:SI 2 "register_operand" "d")]
20136 "TARGET_64BIT && TARGET_XSAVE"
20138 [(set_attr "type" "other")
20139 (set_attr "memory" "store")
20140 (set (attr "length")
20141 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20143 (define_insn "<xrstor>"
20144 [(unspec_volatile:BLK
20145 [(match_operand:BLK 0 "memory_operand" "m")
20146 (match_operand:DI 1 "register_operand" "A")]
20148 "!TARGET_64BIT && TARGET_XSAVE"
20150 [(set_attr "type" "other")
20151 (set_attr "memory" "load")
20152 (set (attr "length")
20153 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20155 (define_insn "<xrstor>_rex64"
20156 [(unspec_volatile:BLK
20157 [(match_operand:BLK 0 "memory_operand" "m")
20158 (match_operand:SI 1 "register_operand" "a")
20159 (match_operand:SI 2 "register_operand" "d")]
20161 "TARGET_64BIT && TARGET_XSAVE"
20163 [(set_attr "type" "other")
20164 (set_attr "memory" "load")
20165 (set (attr "length")
20166 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20168 (define_insn "<xrstor>64"
20169 [(unspec_volatile:BLK
20170 [(match_operand:BLK 0 "memory_operand" "m")
20171 (match_operand:SI 1 "register_operand" "a")
20172 (match_operand:SI 2 "register_operand" "d")]
20174 "TARGET_64BIT && TARGET_XSAVE"
20176 [(set_attr "type" "other")
20177 (set_attr "memory" "load")
20178 (set (attr "length")
20179 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20181 (define_insn "xsetbv"
20182 [(unspec_volatile:SI
20183 [(match_operand:SI 0 "register_operand" "c")
20184 (match_operand:DI 1 "register_operand" "A")]
20186 "!TARGET_64BIT && TARGET_XSAVE"
20188 [(set_attr "type" "other")])
20190 (define_insn "xsetbv_rex64"
20191 [(unspec_volatile:SI
20192 [(match_operand:SI 0 "register_operand" "c")
20193 (match_operand:SI 1 "register_operand" "a")
20194 (match_operand:SI 2 "register_operand" "d")]
20196 "TARGET_64BIT && TARGET_XSAVE"
20198 [(set_attr "type" "other")])
20200 (define_insn "xgetbv"
20201 [(set (match_operand:DI 0 "register_operand" "=A")
20202 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20204 "!TARGET_64BIT && TARGET_XSAVE"
20206 [(set_attr "type" "other")])
20208 (define_insn "xgetbv_rex64"
20209 [(set (match_operand:DI 0 "register_operand" "=a")
20210 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20212 (set (match_operand:DI 1 "register_operand" "=d")
20213 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20214 "TARGET_64BIT && TARGET_XSAVE"
20216 [(set_attr "type" "other")])
20218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20220 ;; Floating-point instructions for atomic compound assignments
20222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20224 ; Clobber all floating-point registers on environment save and restore
20225 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20226 (define_insn "fnstenv"
20227 [(set (match_operand:BLK 0 "memory_operand" "=m")
20228 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20229 (clobber (reg:XF ST0_REG))
20230 (clobber (reg:XF ST1_REG))
20231 (clobber (reg:XF ST2_REG))
20232 (clobber (reg:XF ST3_REG))
20233 (clobber (reg:XF ST4_REG))
20234 (clobber (reg:XF ST5_REG))
20235 (clobber (reg:XF ST6_REG))
20236 (clobber (reg:XF ST7_REG))]
20239 [(set_attr "type" "other")
20240 (set_attr "memory" "store")
20241 (set (attr "length")
20242 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20244 (define_insn "fldenv"
20245 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20247 (clobber (reg:XF ST0_REG))
20248 (clobber (reg:XF ST1_REG))
20249 (clobber (reg:XF ST2_REG))
20250 (clobber (reg:XF ST3_REG))
20251 (clobber (reg:XF ST4_REG))
20252 (clobber (reg:XF ST5_REG))
20253 (clobber (reg:XF ST6_REG))
20254 (clobber (reg:XF ST7_REG))]
20257 [(set_attr "type" "other")
20258 (set_attr "memory" "load")
20259 (set (attr "length")
20260 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20262 (define_insn "fnstsw"
20263 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20264 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20267 [(set_attr "type" "other,other")
20268 (set_attr "memory" "none,store")
20269 (set (attr "length")
20270 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20272 (define_insn "fnclex"
20273 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20276 [(set_attr "type" "other")
20277 (set_attr "memory" "none")
20278 (set_attr "length" "2")])
20280 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20282 ;; LWP instructions
20284 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20286 (define_expand "lwp_llwpcb"
20287 [(unspec_volatile [(match_operand 0 "register_operand")]
20288 UNSPECV_LLWP_INTRINSIC)]
20291 (define_insn "*lwp_llwpcb<mode>_1"
20292 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20293 UNSPECV_LLWP_INTRINSIC)]
20296 [(set_attr "type" "lwp")
20297 (set_attr "mode" "<MODE>")
20298 (set_attr "length" "5")])
20300 (define_expand "lwp_slwpcb"
20301 [(set (match_operand 0 "register_operand")
20302 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20304 "emit_insn (gen_lwp_slwpcb_1 (Pmode, operands[0])); DONE;")
20306 (define_insn "@lwp_slwpcb<mode>_1"
20307 [(set (match_operand:P 0 "register_operand" "=r")
20308 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20311 [(set_attr "type" "lwp")
20312 (set_attr "mode" "<MODE>")
20313 (set_attr "length" "5")])
20315 (define_expand "lwp_lwpval<mode>3"
20316 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20317 (match_operand:SI 2 "nonimmediate_operand")
20318 (match_operand:SI 3 "const_int_operand")]
20319 UNSPECV_LWPVAL_INTRINSIC)]
20321 ;; Avoid unused variable warning.
20322 "(void) operands[0];")
20324 (define_insn "*lwp_lwpval<mode>3_1"
20325 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20326 (match_operand:SI 1 "nonimmediate_operand" "rm")
20327 (match_operand:SI 2 "const_int_operand" "i")]
20328 UNSPECV_LWPVAL_INTRINSIC)]
20330 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20331 [(set_attr "type" "lwp")
20332 (set_attr "mode" "<MODE>")
20333 (set (attr "length")
20334 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20336 (define_expand "lwp_lwpins<mode>3"
20337 [(set (reg:CCC FLAGS_REG)
20338 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20339 (match_operand:SI 2 "nonimmediate_operand")
20340 (match_operand:SI 3 "const_int_operand")]
20341 UNSPECV_LWPINS_INTRINSIC))
20342 (set (match_operand:QI 0 "nonimmediate_operand")
20343 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20346 (define_insn "*lwp_lwpins<mode>3_1"
20347 [(set (reg:CCC FLAGS_REG)
20348 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20349 (match_operand:SI 1 "nonimmediate_operand" "rm")
20350 (match_operand:SI 2 "const_int_operand" "i")]
20351 UNSPECV_LWPINS_INTRINSIC))]
20353 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20354 [(set_attr "type" "lwp")
20355 (set_attr "mode" "<MODE>")
20356 (set (attr "length")
20357 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20359 (define_int_iterator RDFSGSBASE
20363 (define_int_iterator WRFSGSBASE
20367 (define_int_attr fsgs
20368 [(UNSPECV_RDFSBASE "fs")
20369 (UNSPECV_RDGSBASE "gs")
20370 (UNSPECV_WRFSBASE "fs")
20371 (UNSPECV_WRGSBASE "gs")])
20373 (define_insn "rd<fsgs>base<mode>"
20374 [(set (match_operand:SWI48 0 "register_operand" "=r")
20375 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20376 "TARGET_64BIT && TARGET_FSGSBASE"
20378 [(set_attr "type" "other")
20379 (set_attr "prefix_extra" "2")])
20381 (define_insn "wr<fsgs>base<mode>"
20382 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20384 "TARGET_64BIT && TARGET_FSGSBASE"
20386 [(set_attr "type" "other")
20387 (set_attr "prefix_extra" "2")])
20389 (define_insn "ptwrite<mode>"
20390 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
20394 [(set_attr "type" "other")
20395 (set_attr "prefix_extra" "2")])
20397 (define_insn "rdrand<mode>_1"
20398 [(set (match_operand:SWI248 0 "register_operand" "=r")
20399 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20400 (set (reg:CCC FLAGS_REG)
20401 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20404 [(set_attr "type" "other")
20405 (set_attr "prefix_extra" "1")])
20407 (define_insn "rdseed<mode>_1"
20408 [(set (match_operand:SWI248 0 "register_operand" "=r")
20409 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20410 (set (reg:CCC FLAGS_REG)
20411 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20414 [(set_attr "type" "other")
20415 (set_attr "prefix_extra" "1")])
20417 (define_expand "pause"
20418 [(set (match_dup 0)
20419 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20422 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20423 MEM_VOLATILE_P (operands[0]) = 1;
20426 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20427 ;; They have the same encoding.
20428 (define_insn "*pause"
20429 [(set (match_operand:BLK 0)
20430 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20433 [(set_attr "length" "2")
20434 (set_attr "memory" "unknown")])
20436 ;; CET instructions
20437 (define_insn "rdssp<mode>"
20438 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20439 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20440 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20441 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20442 [(set_attr "length" "6")
20443 (set_attr "type" "other")])
20445 (define_insn "incssp<mode>"
20446 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20448 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20449 "incssp<mskmodesuffix>\t%0"
20450 [(set_attr "length" "4")
20451 (set_attr "type" "other")])
20453 (define_insn "saveprevssp"
20454 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20457 [(set_attr "length" "5")
20458 (set_attr "type" "other")])
20460 (define_expand "rstorssp"
20461 [(unspec_volatile [(match_operand 0 "memory_operand")]
20465 (define_insn "*rstorssp<mode>"
20466 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20470 [(set_attr "length" "5")
20471 (set_attr "type" "other")])
20473 (define_insn "wrss<mode>"
20474 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20475 (match_operand:SWI48x 1 "memory_operand" "m")]
20478 "wrss<mskmodesuffix>\t%0, %1"
20479 [(set_attr "length" "3")
20480 (set_attr "type" "other")])
20482 (define_insn "wruss<mode>"
20483 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20484 (match_operand:SWI48x 1 "memory_operand" "m")]
20487 "wruss<mskmodesuffix>\t%0, %1"
20488 [(set_attr "length" "4")
20489 (set_attr "type" "other")])
20491 (define_insn "setssbsy"
20492 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20495 [(set_attr "length" "4")
20496 (set_attr "type" "other")])
20498 (define_expand "clrssbsy"
20499 [(unspec_volatile [(match_operand 0 "memory_operand")]
20503 (define_insn "*clrssbsy<mode>"
20504 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20508 [(set_attr "length" "4")
20509 (set_attr "type" "other")])
20511 (define_insn "nop_endbr"
20512 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20513 "(flag_cf_protection & CF_BRANCH)"
20515 return TARGET_64BIT ? "endbr64" : "endbr32";
20517 [(set_attr "length" "4")
20518 (set_attr "length_immediate" "0")
20519 (set_attr "modrm" "0")])
20522 (define_expand "xbegin"
20523 [(set (match_operand:SI 0 "register_operand")
20524 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20527 rtx_code_label *label = gen_label_rtx ();
20529 /* xbegin is emitted as jump_insn, so reload won't be able
20530 to reload its operand. Force the value into AX hard register. */
20531 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20532 emit_move_insn (ax_reg, constm1_rtx);
20534 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20536 emit_label (label);
20537 LABEL_NUSES (label) = 1;
20539 emit_move_insn (operands[0], ax_reg);
20544 (define_insn "xbegin_1"
20546 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20548 (label_ref (match_operand 1))
20550 (set (match_operand:SI 0 "register_operand" "+a")
20551 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20554 [(set_attr "type" "other")
20555 (set_attr "length" "6")])
20557 (define_insn "xend"
20558 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20561 [(set_attr "type" "other")
20562 (set_attr "length" "3")])
20564 (define_insn "xabort"
20565 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20569 [(set_attr "type" "other")
20570 (set_attr "length" "3")])
20572 (define_expand "xtest"
20573 [(set (match_operand:QI 0 "register_operand")
20574 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20577 emit_insn (gen_xtest_1 ());
20579 ix86_expand_setcc (operands[0], NE,
20580 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20584 (define_insn "xtest_1"
20585 [(set (reg:CCZ FLAGS_REG)
20586 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20589 [(set_attr "type" "other")
20590 (set_attr "length" "3")])
20592 (define_insn "clwb"
20593 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20597 [(set_attr "type" "sse")
20598 (set_attr "atom_sse_attr" "fence")
20599 (set_attr "memory" "unknown")])
20601 (define_insn "clflushopt"
20602 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20603 UNSPECV_CLFLUSHOPT)]
20604 "TARGET_CLFLUSHOPT"
20606 [(set_attr "type" "sse")
20607 (set_attr "atom_sse_attr" "fence")
20608 (set_attr "memory" "unknown")])
20610 ;; MONITORX and MWAITX
20611 (define_insn "mwaitx"
20612 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20613 (match_operand:SI 1 "register_operand" "a")
20614 (match_operand:SI 2 "register_operand" "b")]
20617 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20618 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20619 ;; we only need to set up 32bit registers.
20621 [(set_attr "length" "3")])
20623 (define_insn "@monitorx_<mode>"
20624 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20625 (match_operand:SI 1 "register_operand" "c")
20626 (match_operand:SI 2 "register_operand" "d")]
20629 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20630 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20631 ;; zero extended to 64bit, we only need to set up 32bit registers.
20633 [(set (attr "length")
20634 (symbol_ref ("(Pmode != word_mode) + 3")))])
20637 (define_insn "@clzero_<mode>"
20638 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20642 [(set_attr "length" "3")
20643 (set_attr "memory" "unknown")])
20645 ;; RDPKRU and WRPKRU
20647 (define_expand "rdpkru"
20649 [(set (match_operand:SI 0 "register_operand")
20650 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20651 (set (match_dup 2) (const_int 0))])]
20654 operands[1] = force_reg (SImode, const0_rtx);
20655 operands[2] = gen_reg_rtx (SImode);
20658 (define_insn "*rdpkru"
20659 [(set (match_operand:SI 0 "register_operand" "=a")
20660 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20662 (set (match_operand:SI 1 "register_operand" "=d")
20666 [(set_attr "type" "other")])
20668 (define_expand "wrpkru"
20669 [(unspec_volatile:SI
20670 [(match_operand:SI 0 "register_operand")
20671 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20674 operands[1] = force_reg (SImode, const0_rtx);
20675 operands[2] = force_reg (SImode, const0_rtx);
20678 (define_insn "*wrpkru"
20679 [(unspec_volatile:SI
20680 [(match_operand:SI 0 "register_operand" "a")
20681 (match_operand:SI 1 "register_operand" "d")
20682 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20685 [(set_attr "type" "other")])
20687 (define_insn "rdpid"
20688 [(set (match_operand:SI 0 "register_operand" "=r")
20689 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20690 "!TARGET_64BIT && TARGET_RDPID"
20692 [(set_attr "type" "other")])
20694 (define_insn "rdpid_rex64"
20695 [(set (match_operand:DI 0 "register_operand" "=r")
20696 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20697 "TARGET_64BIT && TARGET_RDPID"
20699 [(set_attr "type" "other")])
20701 ;; Intirinsics for > i486
20703 (define_insn "wbinvd"
20704 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20707 [(set_attr "type" "other")])
20709 (define_insn "wbnoinvd"
20710 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20713 [(set_attr "type" "other")])
20715 ;; MOVDIRI and MOVDIR64B
20717 (define_insn "movdiri<mode>"
20718 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20719 (match_operand:SWI48 1 "register_operand" "r")]
20722 "movdiri\t{%1, %0|%0, %1}"
20723 [(set_attr "type" "other")])
20725 (define_insn "@movdir64b_<mode>"
20726 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20727 (match_operand:XI 1 "memory_operand")]
20728 UNSPECV_MOVDIR64B)]
20730 "movdir64b\t{%1, %0|%0, %1}"
20731 [(set_attr "type" "other")])
20733 ;; ENQCMD and ENQCMDS
20735 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20736 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20738 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20739 [(set (reg:CCZ FLAGS_REG)
20740 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20741 (match_operand:XI 1 "memory_operand" "m")]
20744 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20745 [(set_attr "type" "other")])
20749 (define_insn "umwait"
20750 [(set (reg:CCC FLAGS_REG)
20751 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20752 (match_operand:DI 1 "register_operand" "A")]
20754 "!TARGET_64BIT && TARGET_WAITPKG"
20756 [(set_attr "length" "3")])
20758 (define_insn "umwait_rex64"
20759 [(set (reg:CCC FLAGS_REG)
20760 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20761 (match_operand:SI 1 "register_operand" "a")
20762 (match_operand:SI 2 "register_operand" "d")]
20764 "TARGET_64BIT && TARGET_WAITPKG"
20766 [(set_attr "length" "3")])
20768 (define_insn "@umonitor_<mode>"
20769 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20773 [(set (attr "length")
20774 (symbol_ref ("(Pmode != word_mode) + 3")))])
20776 (define_insn "tpause"
20777 [(set (reg:CCC FLAGS_REG)
20778 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20779 (match_operand:DI 1 "register_operand" "A")]
20781 "!TARGET_64BIT && TARGET_WAITPKG"
20783 [(set_attr "length" "3")])
20785 (define_insn "tpause_rex64"
20786 [(set (reg:CCC FLAGS_REG)
20787 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20788 (match_operand:SI 1 "register_operand" "a")
20789 (match_operand:SI 2 "register_operand" "d")]
20791 "TARGET_64BIT && TARGET_WAITPKG"
20793 [(set_attr "length" "3")])
20795 (define_insn "cldemote"
20796 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20800 [(set_attr "type" "other")
20801 (set_attr "memory" "unknown")])
20803 (define_insn "speculation_barrier"
20804 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20807 [(set_attr "type" "other")
20808 (set_attr "length" "3")])
20812 (include "sync.md")