1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 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
119 ;; For SSE/MMX support:
132 ;; Different from generic us_truncate RTX
133 ;; as it does unsigned saturation of signed source.
136 ;; For AVX/AVX512F support
141 ;; Generic math support
142 UNSPEC_IEEE_MIN ; not commutative
143 UNSPEC_IEEE_MAX ; not commutative
145 ;; x87 Floating point
158 UNSPEC_FRNDINT_ROUNDEVEN
165 ;; x87 Double output FP
190 ;; For LZCNT suppoprt
202 UNSPEC_INTERRUPT_RETURN
204 ;; For MOVDIRI and MOVDIR64B support
208 ;; For insn_callee_abi:
211 ;; For PUSH2/POP2 support
217 (define_c_enum "unspecv" [
221 UNSPECV_PROBE_STACK_RANGE
224 UNSPECV_SPLIT_STACK_RETURN
230 UNSPECV_LLWP_INTRINSIC
231 UNSPECV_SLWP_INTRINSIC
232 UNSPECV_LWPVAL_INTRINSIC
233 UNSPECV_LWPINS_INTRINSIC
259 ;; For atomic compound assignments.
265 ;; For RDRAND support
268 ;; For RDSEED support
282 ;; For CLFLUSHOPT support
285 ;; For MONITORX and MWAITX support
289 ;; For CLZERO support
292 ;; For RDPKRU and WRPKRU support
309 ;; For TSXLDTRK support
313 ;; For WAITPKG support
324 ;; For CLDEMOTE support
327 ;; For Speculation Barrier support
328 UNSPECV_SPECULATION_BARRIER
332 ;; For ENQCMD and ENQCMDS support
336 ;; For SERIALIZE support
339 ;; For patchable area support
340 UNSPECV_PATCHABLE_AREA
342 ;; For HRESET support
345 ;; For PREFETCHI support
348 ;; For USER_MSR support
353 ;; Constants to represent rounding modes in the ROUND instruction
355 [(ROUND_ROUNDEVEN 0x0)
363 ;; Constants to represent AVX512F embeded rounding
365 [(ROUND_NEAREST_INT 0)
373 ;; Constants to represent pcomtrue/pcomfalse variants
383 ;; Constants used in the XOP pperm instruction
385 [(PPERM_SRC 0x00) /* copy source */
386 (PPERM_INVERT 0x20) /* invert source */
387 (PPERM_REVERSE 0x40) /* bit reverse source */
388 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
389 (PPERM_ZERO 0x80) /* all 0's */
390 (PPERM_ONES 0xa0) /* all 1's */
391 (PPERM_SIGN 0xc0) /* propagate sign bit */
392 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
393 (PPERM_SRC1 0x00) /* use first source byte */
394 (PPERM_SRC2 0x10) /* use second source byte */
397 ;; Registers by name.
491 (FIRST_PSEUDO_REG 92)
494 ;; Insn callee abi index.
500 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
503 ;; In C guard expressions, put expressions which may be compile-time
504 ;; constants first. This allows for better optimization. For
505 ;; example, write "TARGET_64BIT && reload_completed", not
506 ;; "reload_completed && TARGET_64BIT".
510 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
511 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
512 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
513 (const (symbol_ref "ix86_schedule")))
515 ;; A basic instruction type. Refinements due to arguments to be
516 ;; provided in other attributes.
519 alu,alu1,negnot,imov,imovx,lea,
520 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
521 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
522 push,pop,call,callv,leave,
524 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
525 fxch,fistp,fisttp,frndint,
526 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
527 ssemul,sseimul,ssediv,sselog,sselog1,
528 sseishft,sseishft1,ssecmp,ssecomi,
529 ssecvt,ssecvt1,sseicvt,sseins,
530 sseshuf,sseshuf1,ssemuladd,sse4arg,
532 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
533 (const_string "other"))
535 ;; Main data type used by the insn
537 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
538 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
539 (const_string "unknown"))
541 ;; The CPU unit operations uses.
542 (define_attr "unit" "integer,i387,sse,mmx,unknown"
543 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
544 fxch,fistp,fisttp,frndint")
545 (const_string "i387")
546 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
547 ssemul,sseimul,ssediv,sselog,sselog1,
548 sseishft,sseishft1,ssecmp,ssecomi,
549 ssecvt,ssecvt1,sseicvt,sseins,
550 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
552 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
554 (eq_attr "type" "other")
555 (const_string "unknown")]
556 (const_string "integer")))
558 ;; Used to control the "enabled" attribute on a per-instruction basis.
559 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
560 x64_avx,x64_avx512bw,x64_avx512dq,aes,
561 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
562 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
563 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
564 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
565 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
566 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
567 (const_string "base"))
569 ;; The (bounding maximum) length of an instruction immediate.
570 (define_attr "length_immediate" ""
571 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
572 bitmanip,imulx,msklog,mskmov")
574 (ior (eq_attr "type" "sse4arg")
575 (eq_attr "isa" "fma4"))
577 (eq_attr "unit" "i387,sse,mmx")
579 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
580 rotate,rotatex,rotate1,imul,icmp,push,pop")
581 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
582 (eq_attr "type" "imov,test")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
584 (eq_attr "type" "call")
585 (if_then_else (match_operand 0 "constant_call_address_operand")
588 (eq_attr "type" "callv")
589 (if_then_else (match_operand 1 "constant_call_address_operand")
592 ;; We don't know the size before shorten_branches. Expect
593 ;; the instruction to fit for better scheduling.
594 (eq_attr "type" "ibr")
597 (symbol_ref "/* Update immediate_length and other attributes! */
598 gcc_unreachable (),1")))
600 ;; The (bounding maximum) length of an instruction address.
601 (define_attr "length_address" ""
602 (cond [(eq_attr "type" "str,other,multi,fxch")
604 (and (eq_attr "type" "call")
605 (match_operand 0 "constant_call_address_operand"))
607 (and (eq_attr "type" "callv")
608 (match_operand 1 "constant_call_address_operand"))
611 (symbol_ref "ix86_attr_length_address_default (insn)")))
613 ;; Set when length prefix is used.
614 (define_attr "prefix_data16" ""
615 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
617 (eq_attr "mode" "HI")
619 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
624 ;; Set when string REP prefix is used.
625 (define_attr "prefix_rep" ""
626 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
628 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
633 ;; Set when 0f opcode prefix is used.
634 (define_attr "prefix_0f" ""
636 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
637 (eq_attr "unit" "sse,mmx"))
641 ;; Set when REX opcode prefix is used.
642 (define_attr "prefix_rex" ""
643 (cond [(not (match_test "TARGET_64BIT"))
645 (and (eq_attr "mode" "DI")
646 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
647 (eq_attr "unit" "!mmx")))
649 (and (eq_attr "mode" "QI")
650 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
652 (match_test "x86_extended_reg_mentioned_p (insn)")
654 (and (eq_attr "type" "imovx")
655 (match_operand:QI 1 "ext_QIreg_operand"))
660 ;; There are also additional prefixes in 3DNOW, SSSE3.
661 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
662 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
663 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
664 (define_attr "prefix_extra" ""
665 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
670 ;; Prefix used: original, VEX or maybe VEX.
671 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
672 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
674 (eq_attr "mode" "XI,V16SF,V8DF")
675 (const_string "evex")
676 (eq_attr "type" "ssemuladd")
677 (if_then_else (eq_attr "isa" "fma4")
679 (const_string "maybe_evex"))
680 (eq_attr "type" "sse4arg")
683 (const_string "orig")))
685 ;; VEX W bit is used.
686 (define_attr "prefix_vex_w" "" (const_int 0))
688 ;; The length of VEX prefix
689 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
690 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
691 ;; still prefix_0f 1, with prefix_extra 1.
692 (define_attr "length_vex" ""
693 (if_then_else (and (eq_attr "prefix_0f" "1")
694 (eq_attr "prefix_extra" "0"))
695 (if_then_else (eq_attr "prefix_vex_w" "1")
696 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
697 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
698 (if_then_else (eq_attr "prefix_vex_w" "1")
699 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
700 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
702 ;; 4-bytes evex prefix and 1 byte opcode.
703 (define_attr "length_evex" "" (const_int 5))
705 ;; Set when modrm byte is used.
706 (define_attr "modrm" ""
707 (cond [(eq_attr "type" "str,leave")
709 (eq_attr "unit" "i387")
711 (and (eq_attr "type" "incdec")
712 (and (not (match_test "TARGET_64BIT"))
713 (ior (match_operand:SI 1 "register_operand")
714 (match_operand:HI 1 "register_operand"))))
716 (and (eq_attr "type" "push")
717 (not (match_operand 1 "memory_operand")))
719 (and (eq_attr "type" "pop")
720 (not (match_operand 0 "memory_operand")))
722 (and (eq_attr "type" "imov")
723 (and (not (eq_attr "mode" "DI"))
724 (ior (and (match_operand 0 "register_operand")
725 (match_operand 1 "immediate_operand"))
726 (ior (and (match_operand 0 "ax_reg_operand")
727 (match_operand 1 "memory_displacement_only_operand"))
728 (and (match_operand 0 "memory_displacement_only_operand")
729 (match_operand 1 "ax_reg_operand"))))))
731 (and (eq_attr "type" "call")
732 (match_operand 0 "constant_call_address_operand"))
734 (and (eq_attr "type" "callv")
735 (match_operand 1 "constant_call_address_operand"))
737 (and (eq_attr "type" "alu,alu1,icmp,test")
738 (match_operand 0 "ax_reg_operand"))
739 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
743 ;; The (bounding maximum) length of an instruction in bytes.
744 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
745 ;; Later we may want to split them and compute proper length as for
747 (define_attr "length" ""
748 (cond [(eq_attr "type" "other,multi,fistp,frndint")
750 (eq_attr "type" "fcmp")
752 (eq_attr "unit" "i387")
754 (plus (attr "prefix_data16")
755 (attr "length_address")))
756 (ior (eq_attr "prefix" "evex")
757 (and (ior (eq_attr "prefix" "maybe_evex")
758 (eq_attr "prefix" "maybe_vex"))
759 (match_test "TARGET_AVX512F")))
760 (plus (attr "length_evex")
761 (plus (attr "length_immediate")
763 (attr "length_address"))))
764 (ior (eq_attr "prefix" "vex")
765 (and (ior (eq_attr "prefix" "maybe_vex")
766 (eq_attr "prefix" "maybe_evex"))
767 (match_test "TARGET_AVX")))
768 (plus (attr "length_vex")
769 (plus (attr "length_immediate")
771 (attr "length_address"))))]
772 (plus (plus (attr "modrm")
773 (plus (attr "prefix_0f")
774 (plus (attr "prefix_rex")
775 (plus (attr "prefix_extra")
777 (plus (attr "prefix_rep")
778 (plus (attr "prefix_data16")
779 (plus (attr "length_immediate")
780 (attr "length_address")))))))
782 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
783 ;; `store' if there is a simple memory reference therein, or `unknown'
784 ;; if the instruction is complex.
786 (define_attr "memory" "none,load,store,both,unknown"
787 (cond [(eq_attr "type" "other,multi,str,lwp")
788 (const_string "unknown")
789 (eq_attr "type" "lea,fcmov,fpspc")
790 (const_string "none")
791 (eq_attr "type" "fistp,leave")
792 (const_string "both")
793 (eq_attr "type" "frndint")
794 (const_string "load")
795 (eq_attr "type" "push")
796 (if_then_else (match_operand 1 "memory_operand")
797 (const_string "both")
798 (const_string "store"))
799 (eq_attr "type" "pop")
800 (if_then_else (match_operand 0 "memory_operand")
801 (const_string "both")
802 (const_string "load"))
803 (eq_attr "type" "setcc")
804 (if_then_else (match_operand 0 "memory_operand")
805 (const_string "store")
806 (const_string "none"))
807 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
808 (if_then_else (ior (match_operand 0 "memory_operand")
809 (match_operand 1 "memory_operand"))
810 (const_string "load")
811 (const_string "none"))
812 (eq_attr "type" "ibr")
813 (if_then_else (match_operand 0 "memory_operand")
814 (const_string "load")
815 (const_string "none"))
816 (eq_attr "type" "call")
817 (if_then_else (match_operand 0 "constant_call_address_operand")
818 (const_string "none")
819 (const_string "load"))
820 (eq_attr "type" "callv")
821 (if_then_else (match_operand 1 "constant_call_address_operand")
822 (const_string "none")
823 (const_string "load"))
824 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
825 (match_operand 1 "memory_operand"))
826 (const_string "both")
827 (and (match_operand 0 "memory_operand")
828 (match_operand 1 "memory_operand"))
829 (const_string "both")
830 (match_operand 0 "memory_operand")
831 (const_string "store")
832 (match_operand 1 "memory_operand")
833 (const_string "load")
835 "!alu1,negnot,ishift1,rotate1,
836 imov,imovx,icmp,test,bitmanip,
838 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
839 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
840 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
841 (match_operand 2 "memory_operand"))
842 (const_string "load")
843 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
844 (match_operand 3 "memory_operand"))
845 (const_string "load")
847 (const_string "none")))
849 ;; Indicates if an instruction has both an immediate and a displacement.
851 (define_attr "imm_disp" "false,true,unknown"
852 (cond [(eq_attr "type" "other,multi")
853 (const_string "unknown")
854 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
855 (and (match_operand 0 "memory_displacement_operand")
856 (match_operand 1 "immediate_operand")))
857 (const_string "true")
858 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
859 (and (match_operand 0 "memory_displacement_operand")
860 (match_operand 2 "immediate_operand")))
861 (const_string "true")
863 (const_string "false")))
865 ;; Indicates if an FP operation has an integer source.
867 (define_attr "fp_int_src" "false,true"
868 (const_string "false"))
870 ;; Defines rounding mode of an FP operation.
872 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
873 (const_string "any"))
875 ;; Define attribute to indicate AVX insns with partial XMM register update.
876 (define_attr "avx_partial_xmm_update" "false,true"
877 (const_string "false"))
879 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
880 (define_attr "use_carry" "0,1" (const_string "0"))
882 ;; Define attribute to indicate unaligned ssemov insns
883 (define_attr "movu" "0,1" (const_string "0"))
885 ;; Define attribute to indicate gpr32 insns.
886 (define_attr "gpr32" "0, 1" (const_string "1"))
888 ;; Define instruction set of MMX instructions
889 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
890 (const_string "base"))
892 (define_attr "enabled" ""
893 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
894 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
895 (eq_attr "isa" "x64_sse2")
896 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
897 (eq_attr "isa" "x64_sse4")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
899 (eq_attr "isa" "x64_sse4_noavx")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
901 (eq_attr "isa" "x64_avx")
902 (symbol_ref "TARGET_64BIT && TARGET_AVX")
903 (eq_attr "isa" "x64_avx512bw")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
905 (eq_attr "isa" "x64_avx512dq")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
907 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
908 (eq_attr "isa" "sse_noavx")
909 (symbol_ref "TARGET_SSE && !TARGET_AVX")
910 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
911 (eq_attr "isa" "sse2_noavx")
912 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
913 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
914 (eq_attr "isa" "sse3_noavx")
915 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
916 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
917 (eq_attr "isa" "sse4_noavx")
918 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
919 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
920 (eq_attr "isa" "avx_noavx512f")
921 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
922 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
923 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
924 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
925 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
926 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
927 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
928 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
929 (eq_attr "isa" "fma_or_avx512vl")
930 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
931 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
932 (eq_attr "isa" "avx512f_512")
933 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
934 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
935 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
936 (eq_attr "isa" "avx512bw_512")
937 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
939 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
940 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
941 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
942 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
943 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
944 (eq_attr "isa" "avx512vnnivl")
945 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
946 (eq_attr "isa" "avx512fp16")
947 (symbol_ref "TARGET_AVX512FP16")
948 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
949 (eq_attr "isa" "avx512ifmavl")
950 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
951 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
952 (eq_attr "isa" "avx512bf16vl")
953 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
954 (eq_attr "isa" "vpclmulqdqvl")
955 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
957 (eq_attr "mmx_isa" "native")
958 (symbol_ref "!TARGET_MMX_WITH_SSE")
959 (eq_attr "mmx_isa" "sse")
960 (symbol_ref "TARGET_MMX_WITH_SSE")
961 (eq_attr "mmx_isa" "sse_noavx")
962 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
963 (eq_attr "mmx_isa" "avx")
964 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
968 (define_attr "preferred_for_size" "" (const_int 1))
969 (define_attr "preferred_for_speed" "" (const_int 1))
971 ;; Describe a user's asm statement.
972 (define_asm_attributes
973 [(set_attr "length" "128")
974 (set_attr "type" "multi")])
976 (define_code_iterator plusminus [plus minus])
977 (define_code_iterator plusminusmult [plus minus mult])
978 (define_code_iterator plusminusmultdiv [plus minus mult div])
980 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
982 ;; Base name for insn mnemonic.
983 (define_code_attr plusminus_mnemonic
984 [(plus "add") (ss_plus "adds") (us_plus "addus")
985 (minus "sub") (ss_minus "subs") (us_minus "subus")])
987 (define_code_iterator multdiv [mult div])
989 (define_code_attr multdiv_mnemonic
990 [(mult "mul") (div "div")])
992 ;; Mark commutative operators as such in constraints.
993 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
994 (minus "") (ss_minus "") (us_minus "")
995 (mult "%") (div "")])
997 ;; Mapping of max and min
998 (define_code_iterator maxmin [smax smin umax umin])
1000 ;; Mapping of signed max and min
1001 (define_code_iterator smaxmin [smax smin])
1003 ;; Mapping of unsigned max and min
1004 (define_code_iterator umaxmin [umax umin])
1006 ;; Base name for integer and FP insn mnemonic
1007 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1008 (umax "maxu") (umin "minu")])
1009 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1011 (define_int_iterator IEEE_MAXMIN
1015 (define_int_attr ieee_maxmin
1016 [(UNSPEC_IEEE_MAX "max")
1017 (UNSPEC_IEEE_MIN "min")])
1019 ;; Mapping of logic operators
1020 (define_code_iterator any_logic [and ior xor])
1021 (define_code_iterator any_or [ior xor])
1022 (define_code_iterator fpint_logic [and xor])
1024 ;; Base name for insn mnemonic.
1025 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1027 ;; Mapping of logic-shift operators
1028 (define_code_iterator any_lshift [ashift lshiftrt])
1030 ;; Mapping of shift-right operators
1031 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1033 ;; Mapping of all shift operators
1034 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1036 ;; Base name for insn mnemonic.
1037 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
1038 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1040 ;; Mapping of rotate operators
1041 (define_code_iterator any_rotate [rotate rotatert])
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1046 ;; Mapping of abs neg operators
1047 (define_code_iterator absneg [abs neg])
1049 ;; Mapping of abs neg operators to logic operation
1050 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1052 ;; Base name for x87 insn mnemonic.
1053 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1055 ;; Mapping of extend operators
1056 (define_code_iterator any_extend [sign_extend zero_extend])
1058 ;; Mapping of highpart multiply operators
1059 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1061 ;; Prefix for insn menmonic.
1062 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1063 (smul_highpart "i") (umul_highpart "")
1064 (div "i") (udiv "")])
1065 ;; Prefix for define_insn
1066 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1067 (smul_highpart "s") (umul_highpart "u")])
1068 (define_code_attr u [(sign_extend "") (zero_extend "u")
1069 (div "") (udiv "u")])
1070 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1071 (div "false") (udiv "true")])
1073 ;; Used in signed and unsigned truncations.
1074 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1075 ;; Instruction suffix for truncations.
1076 (define_code_attr trunsuffix
1077 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1079 ;; Instruction suffix for SSE sign and zero extensions.
1080 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1082 ;; Used in signed and unsigned fix.
1083 (define_code_iterator any_fix [fix unsigned_fix])
1084 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1085 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1086 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1088 ;; Used in signed and unsigned float.
1089 (define_code_iterator any_float [float unsigned_float])
1090 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1091 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1092 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1094 ;; Base name for expression
1095 (define_code_attr insn
1096 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1097 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1098 (sign_extend "extend") (zero_extend "zero_extend")
1099 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1100 (rotate "rotl") (rotatert "rotr")
1101 (mult "mul") (div "div")])
1103 ;; All integer modes.
1104 (define_mode_iterator SWI1248x [QI HI SI DI])
1106 ;; All integer modes without QImode.
1107 (define_mode_iterator SWI248x [HI SI DI])
1109 ;; All integer modes without QImode and HImode.
1110 (define_mode_iterator SWI48x [SI DI])
1112 ;; All integer modes without SImode and DImode.
1113 (define_mode_iterator SWI12 [QI HI])
1115 ;; All integer modes without DImode.
1116 (define_mode_iterator SWI124 [QI HI SI])
1118 ;; All integer modes without QImode and DImode.
1119 (define_mode_iterator SWI24 [HI SI])
1121 ;; Single word integer modes.
1122 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1124 ;; Single word integer modes without QImode.
1125 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1127 ;; Single word integer modes without QImode and HImode.
1128 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1130 ;; All math-dependant single and double word integer modes.
1131 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1132 (HI "TARGET_HIMODE_MATH")
1133 SI DI (TI "TARGET_64BIT")])
1135 ;; Math-dependant single word integer modes.
1136 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1137 (HI "TARGET_HIMODE_MATH")
1138 SI (DI "TARGET_64BIT")])
1140 ;; Math-dependant integer modes without DImode.
1141 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1142 (HI "TARGET_HIMODE_MATH")
1145 ;; Math-dependant integer modes with DImode.
1146 (define_mode_iterator SWIM1248x
1147 [(QI "TARGET_QIMODE_MATH")
1148 (HI "TARGET_HIMODE_MATH")
1151 ;; Math-dependant single word integer modes without QImode.
1152 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1153 SI (DI "TARGET_64BIT")])
1155 ;; Double word integer modes.
1156 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1157 (TI "TARGET_64BIT")])
1159 ;; SWI and DWI together.
1160 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1162 ;; SWI48 and DWI together.
1163 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1165 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1166 ;; compile time constant, it is faster to use <MODE_SIZE> than
1167 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1168 ;; command line options just use GET_MODE_SIZE macro.
1169 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1170 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1171 (XF "GET_MODE_SIZE (XFmode)")
1172 (V16QI "16") (V32QI "32") (V64QI "64")
1173 (V8HI "16") (V16HI "32") (V32HI "64")
1174 (V4SI "16") (V8SI "32") (V16SI "64")
1175 (V2DI "16") (V4DI "32") (V8DI "64")
1176 (V1TI "16") (V2TI "32") (V4TI "64")
1177 (V2DF "16") (V4DF "32") (V8DF "64")
1178 (V4SF "16") (V8SF "32") (V16SF "64")
1179 (V8HF "16") (V16HF "32") (V32HF "64")
1180 (V4HF "8") (V2HF "4")
1181 (V8BF "16") (V16BF "32") (V32BF "64")
1182 (V4BF "8") (V2BF "4")])
1184 ;; Double word integer modes as mode attribute.
1185 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1186 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1188 ;; Half sized integer modes.
1189 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1190 (define_mode_attr half [(TI "di") (DI "si")])
1192 ;; LEA mode corresponding to an integer mode
1193 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1195 ;; Half mode for double word integer modes.
1196 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1197 (DI "TARGET_64BIT")])
1199 ;; Instruction suffix for integer modes.
1200 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1202 ;; Instruction suffix for masks.
1203 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1205 ;; Pointer size prefix for integer modes (Intel asm dialect)
1206 (define_mode_attr iptrsize [(QI "BYTE")
1211 ;; Register class for integer modes.
1212 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1214 ;; Immediate operand constraint for integer modes.
1215 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1217 ;; General operand constraint for word modes.
1218 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1220 ;; Memory operand constraint for word modes.
1221 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1223 ;; Immediate operand constraint for double integer modes.
1224 (define_mode_attr di [(SI "nF") (DI "Wd")])
1226 ;; Immediate operand constraint for shifts.
1227 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1228 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1230 ;; Print register name in the specified mode.
1231 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1233 ;; General operand predicate for integer modes.
1234 (define_mode_attr general_operand
1235 [(QI "general_operand")
1236 (HI "general_operand")
1237 (SI "x86_64_general_operand")
1238 (DI "x86_64_general_operand")
1239 (TI "x86_64_general_operand")])
1241 ;; General operand predicate for integer modes, where for TImode
1242 ;; we need both words of the operand to be general operands.
1243 (define_mode_attr general_hilo_operand
1244 [(QI "general_operand")
1245 (HI "general_operand")
1246 (SI "x86_64_general_operand")
1247 (DI "x86_64_general_operand")
1248 (TI "x86_64_hilo_general_operand")])
1250 ;; General sign extend operand predicate for integer modes,
1251 ;; which disallows VOIDmode operands and thus it is suitable
1252 ;; for use inside sign_extend.
1253 (define_mode_attr general_sext_operand
1254 [(QI "sext_operand")
1256 (SI "x86_64_sext_operand")
1257 (DI "x86_64_sext_operand")])
1259 ;; General sign/zero extend operand predicate for integer modes.
1260 (define_mode_attr general_szext_operand
1261 [(QI "general_operand")
1262 (HI "general_operand")
1263 (SI "x86_64_szext_general_operand")
1264 (DI "x86_64_szext_general_operand")
1265 (TI "x86_64_hilo_general_operand")])
1267 (define_mode_attr nonmemory_szext_operand
1268 [(QI "nonmemory_operand")
1269 (HI "nonmemory_operand")
1270 (SI "x86_64_szext_nonmemory_operand")
1271 (DI "x86_64_szext_nonmemory_operand")])
1273 ;; Immediate operand predicate for integer modes.
1274 (define_mode_attr immediate_operand
1275 [(QI "immediate_operand")
1276 (HI "immediate_operand")
1277 (SI "x86_64_immediate_operand")
1278 (DI "x86_64_immediate_operand")])
1280 ;; Nonmemory operand predicate for integer modes.
1281 (define_mode_attr nonmemory_operand
1282 [(QI "nonmemory_operand")
1283 (HI "nonmemory_operand")
1284 (SI "x86_64_nonmemory_operand")
1285 (DI "x86_64_nonmemory_operand")])
1287 ;; Operand predicate for shifts.
1288 (define_mode_attr shift_operand
1289 [(QI "nonimmediate_operand")
1290 (HI "nonimmediate_operand")
1291 (SI "nonimmediate_operand")
1292 (DI "shiftdi_operand")
1293 (TI "register_operand")])
1295 ;; Operand predicate for shift argument.
1296 (define_mode_attr shift_immediate_operand
1297 [(QI "const_1_to_31_operand")
1298 (HI "const_1_to_31_operand")
1299 (SI "const_1_to_31_operand")
1300 (DI "const_1_to_63_operand")])
1302 ;; Input operand predicate for arithmetic left shifts.
1303 (define_mode_attr ashl_input_operand
1304 [(QI "nonimmediate_operand")
1305 (HI "nonimmediate_operand")
1306 (SI "nonimmediate_operand")
1307 (DI "ashldi_input_operand")
1308 (TI "reg_or_pm1_operand")])
1310 ;; SSE and x87 SFmode and DFmode floating point modes
1311 (define_mode_iterator MODEF [SF DF])
1313 ;; SSE floating point modes
1314 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1316 ;; All x87 floating point modes
1317 (define_mode_iterator X87MODEF [SF DF XF])
1319 ;; All x87 floating point modes plus HFmode
1320 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1322 ;; All SSE floating point modes
1323 (define_mode_iterator SSEMODEF [HF SF DF TF])
1324 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1326 ;; SSE instruction suffix for various modes
1327 (define_mode_attr ssemodesuffix
1328 [(HF "sh") (SF "ss") (DF "sd")
1329 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1330 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1331 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1332 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1333 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1334 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1336 ;; SSE vector suffix for floating point modes
1337 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1339 ;; SSE vector mode corresponding to a scalar mode
1340 (define_mode_attr ssevecmode
1341 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1342 (define_mode_attr ssevecmodelower
1343 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1345 ;; AVX512F vector mode corresponding to a scalar mode
1346 (define_mode_attr avx512fvecmode
1347 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1349 ;; Instruction suffix for REX 64bit operators.
1350 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1351 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1353 ;; This mode iterator allows :P to be used for patterns that operate on
1354 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1355 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1357 ;; This mode iterator allows :W to be used for patterns that operate on
1358 ;; word_mode sized quantities.
1359 (define_mode_iterator W
1360 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1362 ;; This mode iterator allows :PTR to be used for patterns that operate on
1363 ;; ptr_mode sized quantities.
1364 (define_mode_iterator PTR
1365 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1367 ;; Scheduling descriptions
1369 (include "pentium.md")
1372 (include "athlon.md")
1373 (include "bdver1.md")
1374 (include "bdver3.md")
1375 (include "btver2.md")
1376 (include "znver.md")
1377 (include "znver4.md")
1378 (include "geode.md")
1382 (include "core2.md")
1383 (include "haswell.md")
1384 (include "lujiazui.md")
1385 (include "yongfeng.md")
1388 ;; Operand and operator predicates and constraints
1390 (include "predicates.md")
1391 (include "constraints.md")
1394 ;; Compare and branch/compare and store instructions.
1396 (define_expand "cbranch<mode>4"
1397 [(set (reg:CC FLAGS_REG)
1398 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1399 (match_operand:SWIM1248x 2 "<general_operand>")))
1400 (set (pc) (if_then_else
1401 (match_operator 0 "ordered_comparison_operator"
1402 [(reg:CC FLAGS_REG) (const_int 0)])
1403 (label_ref (match_operand 3))
1407 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1408 operands[1] = force_reg (<MODE>mode, operands[1]);
1409 ix86_expand_branch (GET_CODE (operands[0]),
1410 operands[1], operands[2], operands[3]);
1414 (define_expand "cbranchti4"
1415 [(set (reg:CC FLAGS_REG)
1416 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1417 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1418 (set (pc) (if_then_else
1419 (match_operator 0 "ix86_timode_comparison_operator"
1420 [(reg:CC FLAGS_REG) (const_int 0)])
1421 (label_ref (match_operand 3))
1423 "TARGET_64BIT || TARGET_SSE4_1"
1425 ix86_expand_branch (GET_CODE (operands[0]),
1426 operands[1], operands[2], operands[3]);
1430 (define_expand "cbranchoi4"
1431 [(set (reg:CC FLAGS_REG)
1432 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1433 (match_operand:OI 2 "nonimmediate_operand")))
1434 (set (pc) (if_then_else
1435 (match_operator 0 "bt_comparison_operator"
1436 [(reg:CC FLAGS_REG) (const_int 0)])
1437 (label_ref (match_operand 3))
1441 ix86_expand_branch (GET_CODE (operands[0]),
1442 operands[1], operands[2], operands[3]);
1446 (define_expand "cbranchxi4"
1447 [(set (reg:CC FLAGS_REG)
1448 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1449 (match_operand:XI 2 "nonimmediate_operand")))
1450 (set (pc) (if_then_else
1451 (match_operator 0 "bt_comparison_operator"
1452 [(reg:CC FLAGS_REG) (const_int 0)])
1453 (label_ref (match_operand 3))
1455 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1462 (define_expand "cstore<mode>4"
1463 [(set (reg:CC FLAGS_REG)
1464 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1465 (match_operand:SDWIM 3 "<general_operand>")))
1466 (set (match_operand:QI 0 "register_operand")
1467 (match_operator 1 "ordered_comparison_operator"
1468 [(reg:CC FLAGS_REG) (const_int 0)]))]
1471 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1473 if (GET_CODE (operands[1]) != EQ
1474 && GET_CODE (operands[1]) != NE)
1477 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1478 operands[2] = force_reg (<MODE>mode, operands[2]);
1479 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1480 operands[2], operands[3]);
1484 (define_expand "@cmp<mode>_1"
1485 [(set (reg:CC FLAGS_REG)
1486 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1487 (match_operand:SWI48 1 "<general_operand>")))])
1489 (define_mode_iterator SWI1248_AVX512BWDQ_64
1490 [(QI "TARGET_AVX512DQ") HI
1491 (SI "TARGET_AVX512BW")
1492 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1494 (define_insn "*cmp<mode>_ccz_1"
1495 [(set (reg FLAGS_REG)
1496 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1497 "nonimmediate_operand" "<r>,?m<r>,$k")
1498 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1499 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1501 test{<imodesuffix>}\t%0, %0
1502 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1503 kortest<mskmodesuffix>\t%0, %0"
1504 [(set_attr "type" "test,icmp,msklog")
1505 (set_attr "length_immediate" "0,1,*")
1506 (set_attr "prefix" "*,*,vex")
1507 (set_attr "mode" "<MODE>")])
1509 (define_insn "*cmp<mode>_ccno_1"
1510 [(set (reg FLAGS_REG)
1511 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1512 (match_operand:SWI 1 "const0_operand")))]
1513 "ix86_match_ccmode (insn, CCNOmode)"
1515 test{<imodesuffix>}\t%0, %0
1516 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1517 [(set_attr "type" "test,icmp")
1518 (set_attr "length_immediate" "0,1")
1519 (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmp<mode>_1"
1522 [(set (reg FLAGS_REG)
1523 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1524 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1525 "ix86_match_ccmode (insn, CCmode)"
1526 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1527 [(set_attr "type" "icmp")
1528 (set_attr "mode" "<MODE>")])
1530 (define_insn "*cmp<mode>_minus_1"
1531 [(set (reg FLAGS_REG)
1533 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1534 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1536 "ix86_match_ccmode (insn, CCGOCmode)"
1537 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1538 [(set_attr "type" "icmp")
1539 (set_attr "mode" "<MODE>")])
1541 (define_insn "*cmpqi_ext<mode>_1_mem_rex64"
1542 [(set (reg FLAGS_REG)
1544 (match_operand:QI 0 "norex_memory_operand" "Bn")
1546 (match_operator:SWI248 2 "extract_operator"
1547 [(match_operand 1 "int248_register_operand" "Q")
1549 (const_int 8)]) 0)))]
1550 "TARGET_64BIT && reload_completed
1551 && ix86_match_ccmode (insn, CCmode)"
1552 "cmp{b}\t{%h1, %0|%0, %h1}"
1553 [(set_attr "type" "icmp")
1554 (set_attr "mode" "QI")])
1556 (define_insn "*cmpqi_ext<mode>_1"
1557 [(set (reg FLAGS_REG)
1559 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1561 (match_operator:SWI248 2 "extract_operator"
1562 [(match_operand 1 "int248_register_operand" "Q,Q")
1564 (const_int 8)]) 0)))]
1565 "ix86_match_ccmode (insn, CCmode)"
1566 "cmp{b}\t{%h1, %0|%0, %h1}"
1567 [(set_attr "isa" "*,nox64")
1568 (set_attr "type" "icmp")
1569 (set_attr "mode" "QI")])
1572 [(set (match_operand:QI 0 "register_operand")
1573 (match_operand:QI 1 "norex_memory_operand"))
1574 (set (match_operand 3 "flags_reg_operand")
1575 (match_operator 4 "compare_operator"
1578 (match_operator:SWI248 5 "extract_operator"
1579 [(match_operand 2 "int248_register_operand")
1581 (const_int 8)]) 0)]))]
1583 && peep2_reg_dead_p (2, operands[0])"
1591 (const_int 8)]) 0)]))])
1593 (define_insn "*cmpqi_ext<mode>_2"
1594 [(set (reg FLAGS_REG)
1597 (match_operator:SWI248 2 "extract_operator"
1598 [(match_operand 0 "int248_register_operand" "Q")
1601 (match_operand:QI 1 "const0_operand")))]
1602 "ix86_match_ccmode (insn, CCNOmode)"
1604 [(set_attr "type" "test")
1605 (set_attr "length_immediate" "0")
1606 (set_attr "mode" "QI")])
1608 (define_expand "cmpqi_ext_3"
1609 [(set (reg:CC FLAGS_REG)
1613 (match_operand:HI 0 "register_operand")
1616 (match_operand:QI 1 "const_int_operand")))])
1618 (define_insn "*cmpqi_ext<mode>_3_mem_rex64"
1619 [(set (reg FLAGS_REG)
1622 (match_operator:SWI248 2 "extract_operator"
1623 [(match_operand 0 "int248_register_operand" "Q")
1626 (match_operand:QI 1 "norex_memory_operand" "Bn")))]
1627 "TARGET_64BIT && reload_completed
1628 && ix86_match_ccmode (insn, CCmode)"
1629 "cmp{b}\t{%1, %h0|%h0, %1}"
1630 [(set_attr "type" "icmp")
1631 (set_attr "mode" "QI")])
1633 (define_insn "*cmpqi_ext<mode>_3"
1634 [(set (reg FLAGS_REG)
1637 (match_operator:SWI248 2 "extract_operator"
1638 [(match_operand 0 "int248_register_operand" "Q,Q")
1641 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1642 "ix86_match_ccmode (insn, CCmode)"
1643 "cmp{b}\t{%1, %h0|%h0, %1}"
1644 [(set_attr "isa" "*,nox64")
1645 (set_attr "type" "icmp")
1646 (set_attr "mode" "QI")])
1649 [(set (match_operand:QI 0 "register_operand")
1650 (match_operand:QI 1 "norex_memory_operand"))
1651 (set (match_operand 3 "flags_reg_operand")
1652 (match_operator 4 "compare_operator"
1654 (match_operator:SWI248 5 "extract_operator"
1655 [(match_operand 2 "int248_register_operand")
1660 && peep2_reg_dead_p (2, operands[0])"
1670 (define_insn "*cmpqi_ext<mode>_4"
1671 [(set (reg FLAGS_REG)
1674 (match_operator:SWI248 2 "extract_operator"
1675 [(match_operand 0 "int248_register_operand" "Q")
1679 (match_operator:SWI248 3 "extract_operator"
1680 [(match_operand 1 "int248_register_operand" "Q")
1682 (const_int 8)]) 0)))]
1683 "ix86_match_ccmode (insn, CCmode)"
1684 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1685 [(set_attr "type" "icmp")
1686 (set_attr "mode" "QI")])
1688 (define_insn_and_split "*cmp<dwi>_doubleword"
1689 [(set (reg:CCZ FLAGS_REG)
1690 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1691 (match_operand:<DWI> 1 "general_operand")))]
1692 "ix86_pre_reload_split ()"
1695 [(parallel [(set (reg:CCZ FLAGS_REG)
1696 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1698 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1700 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1701 /* Placing the SUBREG pieces in pseudos helps reload. */
1702 for (int i = 0; i < 4; i++)
1703 if (SUBREG_P (operands[i]))
1704 operands[i] = force_reg (<MODE>mode, operands[i]);
1706 operands[4] = gen_reg_rtx (<MODE>mode);
1708 /* Special case comparisons against -1. */
1709 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1711 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1712 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1716 if (operands[1] == const0_rtx)
1717 emit_move_insn (operands[4], operands[0]);
1718 else if (operands[0] == const0_rtx)
1719 emit_move_insn (operands[4], operands[1]);
1720 else if (operands[1] == constm1_rtx)
1721 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1722 else if (operands[0] == constm1_rtx)
1723 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1726 if (CONST_SCALAR_INT_P (operands[1])
1727 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1728 operands[1] = force_reg (<MODE>mode, operands[1]);
1729 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1732 if (operands[3] == const0_rtx)
1733 operands[5] = operands[2];
1734 else if (operands[2] == const0_rtx)
1735 operands[5] = operands[3];
1738 operands[5] = gen_reg_rtx (<MODE>mode);
1739 if (operands[3] == constm1_rtx)
1740 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1741 else if (operands[2] == constm1_rtx)
1742 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1745 if (CONST_SCALAR_INT_P (operands[3])
1746 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1747 operands[3] = force_reg (<MODE>mode, operands[3]);
1748 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1753 ;; These implement float point compares.
1754 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1755 ;; which would allow mix and match FP modes on the compares. Which is what
1756 ;; the old patterns did, but with many more of them.
1758 (define_expand "cbranchxf4"
1759 [(set (reg:CC FLAGS_REG)
1760 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1761 (match_operand:XF 2 "nonmemory_operand")))
1762 (set (pc) (if_then_else
1763 (match_operator 0 "ix86_fp_comparison_operator"
1766 (label_ref (match_operand 3))
1770 ix86_expand_branch (GET_CODE (operands[0]),
1771 operands[1], operands[2], operands[3]);
1775 (define_expand "cstorexf4"
1776 [(set (reg:CC FLAGS_REG)
1777 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1778 (match_operand:XF 3 "nonmemory_operand")))
1779 (set (match_operand:QI 0 "register_operand")
1780 (match_operator 1 "ix86_fp_comparison_operator"
1785 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1786 operands[2], operands[3]);
1790 (define_expand "cbranchhf4"
1791 [(set (reg:CC FLAGS_REG)
1792 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1793 (match_operand:HF 2 "cmp_fp_expander_operand")))
1794 (set (pc) (if_then_else
1795 (match_operator 0 "ix86_fp_comparison_operator"
1798 (label_ref (match_operand 3))
1802 ix86_expand_branch (GET_CODE (operands[0]),
1803 operands[1], operands[2], operands[3]);
1807 (define_expand "cbranch<mode>4"
1808 [(set (reg:CC FLAGS_REG)
1809 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1810 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1811 (set (pc) (if_then_else
1812 (match_operator 0 "ix86_fp_comparison_operator"
1815 (label_ref (match_operand 3))
1817 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1819 ix86_expand_branch (GET_CODE (operands[0]),
1820 operands[1], operands[2], operands[3]);
1824 (define_expand "cbranchbf4"
1825 [(set (reg:CC FLAGS_REG)
1826 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1827 (match_operand:BF 2 "cmp_fp_expander_operand")))
1828 (set (pc) (if_then_else
1829 (match_operator 0 "comparison_operator"
1832 (label_ref (match_operand 3))
1834 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1836 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1837 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1838 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1839 SFmode, NULL_RTX, NULL,
1840 as_a <rtx_code_label *> (operands[3]),
1841 /* Unfortunately this isn't propagated. */
1842 profile_probability::even ());
1846 (define_expand "cstorehf4"
1847 [(set (reg:CC FLAGS_REG)
1848 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1849 (match_operand:HF 3 "cmp_fp_expander_operand")))
1850 (set (match_operand:QI 0 "register_operand")
1851 (match_operator 1 "ix86_fp_comparison_operator"
1856 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1857 operands[2], operands[3]);
1861 (define_expand "cstorebf4"
1862 [(set (reg:CC FLAGS_REG)
1863 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1864 (match_operand:BF 3 "cmp_fp_expander_operand")))
1865 (set (match_operand:QI 0 "register_operand")
1866 (match_operator 1 "comparison_operator"
1869 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1871 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1872 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1873 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1874 op1, op2, SFmode, 0, 1);
1875 if (!rtx_equal_p (res, operands[0]))
1876 emit_move_insn (operands[0], res);
1880 (define_expand "cstore<mode>4"
1881 [(set (reg:CC FLAGS_REG)
1882 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1883 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1884 (set (match_operand:QI 0 "register_operand")
1885 (match_operator 1 "ix86_fp_comparison_operator"
1888 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1890 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1891 operands[2], operands[3]);
1895 (define_expand "cbranchcc4"
1896 [(set (pc) (if_then_else
1897 (match_operator 0 "comparison_operator"
1898 [(match_operand 1 "flags_reg_operand")
1899 (match_operand 2 "const0_operand")])
1900 (label_ref (match_operand 3))
1904 ix86_expand_branch (GET_CODE (operands[0]),
1905 operands[1], operands[2], operands[3]);
1909 (define_expand "cstorecc4"
1910 [(set (match_operand:QI 0 "register_operand")
1911 (match_operator 1 "comparison_operator"
1912 [(match_operand 2 "flags_reg_operand")
1913 (match_operand 3 "const0_operand")]))]
1916 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1917 operands[2], operands[3]);
1921 ;; FP compares, step 1:
1922 ;; Set the FP condition codes and move fpsr to ax.
1924 ;; We may not use "#" to split and emit these
1925 ;; due to reg-stack pops killing fpsr.
1927 (define_insn "*cmpxf_i387"
1928 [(set (match_operand:HI 0 "register_operand" "=a")
1931 (match_operand:XF 1 "register_operand" "f")
1932 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1935 "* return output_fp_compare (insn, operands, false, false);"
1936 [(set_attr "type" "multi")
1937 (set_attr "unit" "i387")
1938 (set_attr "mode" "XF")])
1940 (define_insn "*cmp<mode>_i387"
1941 [(set (match_operand:HI 0 "register_operand" "=a")
1944 (match_operand:MODEF 1 "register_operand" "f")
1945 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1948 "* return output_fp_compare (insn, operands, false, false);"
1949 [(set_attr "type" "multi")
1950 (set_attr "unit" "i387")
1951 (set_attr "mode" "<MODE>")])
1953 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1954 [(set (match_operand:HI 0 "register_operand" "=a")
1957 (match_operand:X87MODEF 1 "register_operand" "f")
1959 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1962 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1963 || optimize_function_for_size_p (cfun))"
1964 "* return output_fp_compare (insn, operands, false, false);"
1965 [(set_attr "type" "multi")
1966 (set_attr "unit" "i387")
1967 (set_attr "fp_int_src" "true")
1968 (set_attr "mode" "<SWI24:MODE>")])
1970 (define_insn "*cmpu<mode>_i387"
1971 [(set (match_operand:HI 0 "register_operand" "=a")
1975 (match_operand:X87MODEF 1 "register_operand" "f")
1976 (match_operand:X87MODEF 2 "register_operand" "f"))]
1980 "* return output_fp_compare (insn, operands, false, true);"
1981 [(set_attr "type" "multi")
1982 (set_attr "unit" "i387")
1983 (set_attr "mode" "<MODE>")])
1985 ;; FP compares, step 2:
1986 ;; Get ax into flags, general case.
1988 (define_insn "x86_sahf_1"
1989 [(set (reg:CC FLAGS_REG)
1990 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1994 #ifndef HAVE_AS_IX86_SAHF
1996 return ASM_BYTE "0x9e";
2001 [(set_attr "length" "1")
2002 (set_attr "athlon_decode" "vector")
2003 (set_attr "amdfam10_decode" "direct")
2004 (set_attr "bdver1_decode" "direct")
2005 (set_attr "mode" "SI")])
2007 ;; Pentium Pro can do both steps in one go.
2008 ;; (these instructions set flags directly)
2010 (define_subst_attr "unord" "unord_subst" "" "u")
2011 (define_subst_attr "unordered" "unord_subst" "false" "true")
2013 (define_subst "unord_subst"
2014 [(set (match_operand:CCFP 0)
2015 (match_operand:CCFP 1))]
2022 (define_insn "*cmpi<unord>xf_i387"
2023 [(set (reg:CCFP FLAGS_REG)
2025 (match_operand:XF 0 "register_operand" "f")
2026 (match_operand:XF 1 "register_operand" "f")))]
2027 "TARGET_80387 && TARGET_CMOVE"
2028 "* return output_fp_compare (insn, operands, true, <unordered>);"
2029 [(set_attr "type" "fcmp")
2030 (set_attr "mode" "XF")
2031 (set_attr "athlon_decode" "vector")
2032 (set_attr "amdfam10_decode" "direct")
2033 (set_attr "bdver1_decode" "double")
2034 (set_attr "znver1_decode" "double")])
2036 (define_insn "*cmpi<unord><MODEF:mode>"
2037 [(set (reg:CCFP FLAGS_REG)
2039 (match_operand:MODEF 0 "register_operand" "f,v")
2040 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
2041 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
2042 || (TARGET_80387 && TARGET_CMOVE)"
2044 * return output_fp_compare (insn, operands, true, <unordered>);
2045 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2046 [(set_attr "type" "fcmp,ssecomi")
2047 (set_attr "prefix" "orig,maybe_vex")
2048 (set_attr "mode" "<MODEF:MODE>")
2049 (set_attr "prefix_rep" "*,0")
2050 (set (attr "prefix_data16")
2051 (cond [(eq_attr "alternative" "0")
2053 (eq_attr "mode" "DF")
2056 (const_string "0")))
2057 (set_attr "athlon_decode" "vector")
2058 (set_attr "amdfam10_decode" "direct")
2059 (set_attr "bdver1_decode" "double")
2060 (set_attr "znver1_decode" "double")
2061 (set (attr "enabled")
2063 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2065 (eq_attr "alternative" "0")
2066 (symbol_ref "TARGET_MIX_SSE_I387")
2067 (symbol_ref "true"))
2069 (eq_attr "alternative" "0")
2071 (symbol_ref "false"))))])
2073 (define_insn "*cmpi<unord>hf"
2074 [(set (reg:CCFP FLAGS_REG)
2076 (match_operand:HF 0 "register_operand" "v")
2077 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2079 "v<unord>comish\t{%1, %0|%0, %1}"
2080 [(set_attr "type" "ssecomi")
2081 (set_attr "prefix" "evex")
2082 (set_attr "mode" "HF")])
2085 (define_insn "x86_stc"
2086 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2089 [(set_attr "length" "1")
2090 (set_attr "length_immediate" "0")
2091 (set_attr "modrm" "0")])
2093 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2095 [(match_scratch:QI 0 "r")
2096 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2097 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2098 [(set (match_dup 0) (const_int 1))
2100 [(set (reg:CCC FLAGS_REG)
2101 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2103 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2105 ;; Complement carry flag.
2106 (define_insn "*x86_cmc"
2107 [(set (reg:CCC FLAGS_REG)
2108 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2109 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2112 [(set_attr "length" "1")
2113 (set_attr "length_immediate" "0")
2114 (set_attr "use_carry" "1")
2115 (set_attr "modrm" "0")])
2117 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2119 [(match_scratch:QI 0 "r")
2120 (set (reg:CCC FLAGS_REG)
2121 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2122 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2123 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2124 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2126 [(set (reg:CCC FLAGS_REG)
2127 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2129 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2131 ;; Push/pop instructions.
2133 (define_insn_and_split "*pushv1ti2"
2134 [(set (match_operand:V1TI 0 "push_operand" "=<")
2135 (match_operand:V1TI 1 "register_operand" "v"))]
2136 "TARGET_64BIT && TARGET_STV"
2138 "&& reload_completed"
2139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2140 (set (match_dup 0) (match_dup 1))]
2142 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2143 /* Preserve memory attributes. */
2144 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2146 [(set_attr "type" "multi")
2147 (set_attr "mode" "TI")])
2149 (define_insn "*push<mode>2"
2150 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2151 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2154 [(set_attr "type" "multi")
2155 (set_attr "mode" "<MODE>")])
2158 [(set (match_operand:DWI 0 "push_operand")
2159 (match_operand:DWI 1 "general_gr_operand"))]
2162 "ix86_split_long_move (operands); DONE;")
2164 (define_insn "*pushdi2_rex64"
2165 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2166 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2172 [(set_attr "type" "push,multi,multi")
2173 (set_attr "mode" "DI")])
2175 ;; Convert impossible pushes of immediate to existing instructions.
2176 ;; First try to get scratch register and go through it. In case this
2177 ;; fails, push sign extended lower part first and then overwrite
2178 ;; upper part by 32bit move.
2181 [(match_scratch:DI 2 "r")
2182 (set (match_operand:DI 0 "push_operand")
2183 (match_operand:DI 1 "immediate_operand"))]
2185 && !symbolic_operand (operands[1], DImode)
2186 && !x86_64_immediate_operand (operands[1], DImode)"
2187 [(set (match_dup 2) (match_dup 1))
2188 (set (match_dup 0) (match_dup 2))])
2191 [(set (match_operand:DI 0 "push_operand")
2192 (match_operand:DI 1 "immediate_operand"))]
2193 "TARGET_64BIT && epilogue_completed
2194 && !symbolic_operand (operands[1], DImode)
2195 && !x86_64_immediate_operand (operands[1], DImode)"
2196 [(set (match_dup 0) (match_dup 1))
2197 (set (match_dup 2) (match_dup 3))]
2199 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2201 operands[1] = gen_lowpart (DImode, operands[2]);
2202 operands[2] = gen_rtx_MEM (SImode,
2203 plus_constant (Pmode, stack_pointer_rtx, 4));
2206 ;; For TARGET_64BIT we always round up to 8 bytes.
2207 (define_insn "*pushsi2_rex64"
2208 [(set (match_operand:SI 0 "push_operand" "=X,X")
2209 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2214 [(set_attr "type" "push,multi")
2215 (set_attr "mode" "DI")])
2217 (define_insn "*pushsi2"
2218 [(set (match_operand:SI 0 "push_operand" "=<,<")
2219 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2224 [(set_attr "type" "push,multi")
2225 (set_attr "mode" "SI")])
2228 [(set (match_operand:SWI48DWI 0 "push_operand")
2229 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2230 "TARGET_SSE && reload_completed"
2231 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2232 (set (match_dup 0) (match_dup 1))]
2234 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2235 /* Preserve memory attributes. */
2236 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2239 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2240 ;; "push a byte/word". But actually we use push{l,q}, which has
2241 ;; the effect of rounding the amount pushed up to a word.
2243 (define_insn "*push<mode>2"
2244 [(set (match_operand:SWI12 0 "push_operand" "=X")
2245 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2247 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2248 [(set_attr "type" "push")
2250 (if_then_else (match_test "TARGET_64BIT")
2252 (const_string "SI")))])
2254 (define_insn "*push<mode>2_prologue"
2255 [(set (match_operand:W 0 "push_operand" "=<")
2256 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2257 (clobber (mem:BLK (scratch)))]
2259 "push{<imodesuffix>}\t%1"
2260 [(set_attr "type" "push")
2261 (set_attr "mode" "<MODE>")])
2263 (define_insn "*pop<mode>1"
2264 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2265 (match_operand:W 1 "pop_operand" ">"))]
2267 "pop{<imodesuffix>}\t%0"
2268 [(set_attr "type" "pop")
2269 (set_attr "mode" "<MODE>")])
2271 (define_insn "*pop<mode>1_epilogue"
2272 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2273 (match_operand:W 1 "pop_operand" ">"))
2274 (clobber (mem:BLK (scratch)))]
2276 "pop{<imodesuffix>}\t%0"
2277 [(set_attr "type" "pop")
2278 (set_attr "mode" "<MODE>")])
2280 (define_insn "*pushfl<mode>2"
2281 [(set (match_operand:W 0 "push_operand" "=<")
2282 (match_operand:W 1 "flags_reg_operand"))]
2284 "pushf{<imodesuffix>}"
2285 [(set_attr "type" "push")
2286 (set_attr "mode" "<MODE>")])
2288 (define_insn "*popfl<mode>1"
2289 [(set (match_operand:W 0 "flags_reg_operand")
2290 (match_operand:W 1 "pop_operand" ">"))]
2292 "popf{<imodesuffix>}"
2293 [(set_attr "type" "pop")
2294 (set_attr "mode" "<MODE>")])
2297 ;; Reload patterns to support multi-word load/store
2298 ;; with non-offsetable address.
2299 (define_expand "reload_noff_store"
2300 [(parallel [(match_operand 0 "memory_operand" "=m")
2301 (match_operand 1 "register_operand" "r")
2302 (match_operand:DI 2 "register_operand" "=&r")])]
2305 rtx mem = operands[0];
2306 rtx addr = XEXP (mem, 0);
2308 emit_move_insn (operands[2], addr);
2309 mem = replace_equiv_address_nv (mem, operands[2]);
2311 emit_insn (gen_rtx_SET (mem, operands[1]));
2315 (define_expand "reload_noff_load"
2316 [(parallel [(match_operand 0 "register_operand" "=r")
2317 (match_operand 1 "memory_operand" "m")
2318 (match_operand:DI 2 "register_operand" "=r")])]
2321 rtx mem = operands[1];
2322 rtx addr = XEXP (mem, 0);
2324 emit_move_insn (operands[2], addr);
2325 mem = replace_equiv_address_nv (mem, operands[2]);
2327 emit_insn (gen_rtx_SET (operands[0], mem));
2331 ;; Move instructions.
2333 (define_expand "movxi"
2334 [(set (match_operand:XI 0 "nonimmediate_operand")
2335 (match_operand:XI 1 "general_operand"))]
2336 "TARGET_AVX512F && TARGET_EVEX512"
2337 "ix86_expand_vector_move (XImode, operands); DONE;")
2339 (define_expand "movoi"
2340 [(set (match_operand:OI 0 "nonimmediate_operand")
2341 (match_operand:OI 1 "general_operand"))]
2343 "ix86_expand_vector_move (OImode, operands); DONE;")
2345 (define_expand "movti"
2346 [(set (match_operand:TI 0 "nonimmediate_operand")
2347 (match_operand:TI 1 "general_operand"))]
2348 "TARGET_64BIT || TARGET_SSE"
2351 ix86_expand_move (TImode, operands);
2353 ix86_expand_vector_move (TImode, operands);
2357 ;; This expands to what emit_move_complex would generate if we didn't
2358 ;; have a movti pattern. Having this avoids problems with reload on
2359 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2360 ;; to have around all the time.
2361 (define_expand "movcdi"
2362 [(set (match_operand:CDI 0 "nonimmediate_operand")
2363 (match_operand:CDI 1 "general_operand"))]
2366 if (push_operand (operands[0], CDImode))
2367 emit_move_complex_push (CDImode, operands[0], operands[1]);
2369 emit_move_complex_parts (operands[0], operands[1]);
2373 (define_expand "mov<mode>"
2374 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2375 (match_operand:SWI1248x 1 "general_operand"))]
2377 "ix86_expand_move (<MODE>mode, operands); DONE;")
2379 (define_insn "*mov<mode>_xor"
2380 [(set (match_operand:SWI48 0 "register_operand" "=r")
2381 (match_operand:SWI48 1 "const0_operand"))
2382 (clobber (reg:CC FLAGS_REG))]
2385 [(set_attr "type" "alu1")
2386 (set_attr "mode" "SI")
2387 (set_attr "length_immediate" "0")])
2389 (define_insn "*mov<mode>_and"
2390 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2391 (match_operand:SWI248 1 "const0_operand"))
2392 (clobber (reg:CC FLAGS_REG))]
2394 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2395 [(set_attr "type" "alu1")
2396 (set_attr "mode" "<MODE>")
2397 (set_attr "length_immediate" "1")])
2399 (define_insn "*mov<mode>_or"
2400 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2401 (match_operand:SWI248 1 "constm1_operand"))
2402 (clobber (reg:CC FLAGS_REG))]
2404 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2405 [(set_attr "type" "alu1")
2406 (set_attr "mode" "<MODE>")
2407 (set_attr "length_immediate" "1")])
2409 (define_insn "*movxi_internal_avx512f"
2410 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2411 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2412 "TARGET_AVX512F && TARGET_EVEX512
2413 && (register_operand (operands[0], XImode)
2414 || register_operand (operands[1], XImode))"
2416 switch (get_attr_type (insn))
2419 return standard_sse_constant_opcode (insn, operands);
2422 return ix86_output_ssemov (insn, operands);
2428 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2429 (set_attr "prefix" "evex")
2430 (set_attr "mode" "XI")])
2432 (define_insn "*movoi_internal_avx"
2433 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2434 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2436 && (register_operand (operands[0], OImode)
2437 || register_operand (operands[1], OImode))"
2439 switch (get_attr_type (insn))
2442 return standard_sse_constant_opcode (insn, operands);
2445 return ix86_output_ssemov (insn, operands);
2451 [(set_attr "isa" "*,avx2,*,*")
2452 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2453 (set_attr "prefix" "vex")
2454 (set_attr "mode" "OI")])
2456 (define_insn "*movti_internal"
2457 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2458 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2460 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2462 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2463 && (register_operand (operands[0], TImode)
2464 || register_operand (operands[1], TImode)))"
2466 switch (get_attr_type (insn))
2472 return standard_sse_constant_opcode (insn, operands);
2475 return ix86_output_ssemov (insn, operands);
2482 (cond [(eq_attr "alternative" "0,1,6,7")
2483 (const_string "x64")
2484 (eq_attr "alternative" "3")
2485 (const_string "sse2")
2487 (const_string "*")))
2489 (cond [(eq_attr "alternative" "0,1,6,7")
2490 (const_string "multi")
2491 (eq_attr "alternative" "2,3")
2492 (const_string "sselog1")
2494 (const_string "ssemov")))
2495 (set (attr "prefix")
2496 (if_then_else (eq_attr "type" "sselog1,ssemov")
2497 (const_string "maybe_vex")
2498 (const_string "orig")))
2500 (cond [(eq_attr "alternative" "0,1")
2502 (match_test "TARGET_AVX")
2504 (ior (not (match_test "TARGET_SSE2"))
2505 (match_test "optimize_function_for_size_p (cfun)"))
2506 (const_string "V4SF")
2507 (and (eq_attr "alternative" "5")
2508 (match_test "TARGET_SSE_TYPELESS_STORES"))
2509 (const_string "V4SF")
2511 (const_string "TI")))
2512 (set (attr "preferred_for_speed")
2513 (cond [(eq_attr "alternative" "6")
2514 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2515 (eq_attr "alternative" "7")
2516 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2518 (symbol_ref "true")))])
2521 [(set (match_operand:TI 0 "sse_reg_operand")
2522 (match_operand:TI 1 "general_reg_operand"))]
2523 "TARGET_64BIT && TARGET_SSE4_1
2524 && reload_completed"
2527 (vec_duplicate:V2DI (match_dup 3))
2531 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2532 operands[3] = gen_highpart (DImode, operands[1]);
2534 emit_move_insn (gen_lowpart (DImode, operands[0]),
2535 gen_lowpart (DImode, operands[1]));
2538 (define_insn "*movdi_internal"
2539 [(set (match_operand:DI 0 "nonimmediate_operand"
2540 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2541 (match_operand:DI 1 "general_operand"
2542 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,r ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2543 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2544 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2546 switch (get_attr_type (insn))
2549 return "kmovq\t{%1, %0|%0, %1}";
2552 if (operands[1] == const0_rtx)
2553 return "kxorq\t%0, %0, %0";
2554 else if (operands[1] == constm1_rtx)
2555 return "kxnorq\t%0, %0, %0";
2562 return "pxor\t%0, %0";
2565 /* Handle broken assemblers that require movd instead of movq. */
2566 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2567 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2568 return "movd\t{%1, %0|%0, %1}";
2569 return "movq\t{%1, %0|%0, %1}";
2572 return standard_sse_constant_opcode (insn, operands);
2575 return ix86_output_ssemov (insn, operands);
2578 if (SSE_REG_P (operands[0]))
2579 return "movq2dq\t{%1, %0|%0, %1}";
2581 return "movdq2q\t{%1, %0|%0, %1}";
2584 return "lea{q}\t{%E1, %0|%0, %E1}";
2587 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2588 if (get_attr_mode (insn) == MODE_SI)
2589 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2590 else if (which_alternative == 4)
2591 return "movabs{q}\t{%1, %0|%0, %1}";
2592 else if (ix86_use_lea_for_mov (insn, operands))
2593 return "lea{q}\t{%E1, %0|%0, %E1}";
2595 return "mov{q}\t{%1, %0|%0, %1}";
2602 (cond [(eq_attr "alternative" "0,1,17,18")
2603 (const_string "nox64")
2604 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2605 (const_string "x64")
2606 (eq_attr "alternative" "19,20")
2607 (const_string "x64_sse2")
2608 (eq_attr "alternative" "21,22")
2609 (const_string "sse2")
2611 (const_string "*")))
2613 (cond [(eq_attr "alternative" "0,1,17,18")
2614 (const_string "multi")
2615 (eq_attr "alternative" "6")
2616 (const_string "mmx")
2617 (eq_attr "alternative" "7,8,9,10,11")
2618 (const_string "mmxmov")
2619 (eq_attr "alternative" "12")
2620 (const_string "sselog1")
2621 (eq_attr "alternative" "13,14,15,16,19,20")
2622 (const_string "ssemov")
2623 (eq_attr "alternative" "21,22")
2624 (const_string "ssecvt")
2625 (eq_attr "alternative" "23,24,25,26")
2626 (const_string "mskmov")
2627 (eq_attr "alternative" "27")
2628 (const_string "msklog")
2629 (and (match_operand 0 "register_operand")
2630 (match_operand 1 "pic_32bit_operand"))
2631 (const_string "lea")
2633 (const_string "imov")))
2636 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2638 (const_string "*")))
2639 (set (attr "length_immediate")
2641 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2643 (const_string "*")))
2644 (set (attr "prefix_rex")
2646 (eq_attr "alternative" "10,11,19,20")
2648 (const_string "*")))
2649 (set (attr "prefix")
2650 (if_then_else (eq_attr "type" "sselog1,ssemov")
2651 (const_string "maybe_vex")
2652 (const_string "orig")))
2653 (set (attr "prefix_data16")
2654 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2656 (const_string "*")))
2658 (cond [(eq_attr "alternative" "2")
2660 (eq_attr "alternative" "12")
2661 (cond [(match_test "TARGET_AVX")
2663 (ior (not (match_test "TARGET_SSE2"))
2664 (match_test "optimize_function_for_size_p (cfun)"))
2665 (const_string "V4SF")
2667 (const_string "TI"))
2668 (eq_attr "alternative" "13")
2669 (cond [(match_test "TARGET_AVX512VL")
2671 (match_test "TARGET_AVX512F")
2673 (match_test "TARGET_AVX")
2675 (ior (not (match_test "TARGET_SSE2"))
2676 (match_test "optimize_function_for_size_p (cfun)"))
2677 (const_string "V4SF")
2679 (const_string "TI"))
2681 (and (eq_attr "alternative" "14,15,16")
2682 (not (match_test "TARGET_SSE2")))
2683 (const_string "V2SF")
2685 (const_string "DI")))
2686 (set (attr "preferred_for_speed")
2687 (cond [(eq_attr "alternative" "10,17,19")
2688 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2689 (eq_attr "alternative" "11,18,20")
2690 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2692 (symbol_ref "true")))
2693 (set (attr "enabled")
2694 (cond [(eq_attr "alternative" "15")
2696 (match_test "TARGET_STV && TARGET_SSE2")
2697 (symbol_ref "false")
2699 (eq_attr "alternative" "16")
2701 (match_test "TARGET_STV && TARGET_SSE2")
2703 (symbol_ref "false"))
2705 (const_string "*")))])
2708 [(set (match_operand:<DWI> 0 "general_reg_operand")
2709 (match_operand:<DWI> 1 "sse_reg_operand"))]
2711 && reload_completed"
2715 (parallel [(const_int 1)])))]
2717 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2718 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2720 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2721 gen_lowpart (<MODE>mode, operands[1]));
2725 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2726 (match_operand:DWI 1 "general_gr_operand"))]
2729 "ix86_split_long_move (operands); DONE;")
2732 [(set (match_operand:DI 0 "sse_reg_operand")
2733 (match_operand:DI 1 "general_reg_operand"))]
2734 "!TARGET_64BIT && TARGET_SSE4_1
2735 && reload_completed"
2738 (vec_duplicate:V4SI (match_dup 3))
2742 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2743 operands[3] = gen_highpart (SImode, operands[1]);
2745 emit_move_insn (gen_lowpart (SImode, operands[0]),
2746 gen_lowpart (SImode, operands[1]));
2749 ;; movabsq $0x0012345678000000, %rax is longer
2750 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2752 [(set (match_operand:DI 0 "register_operand")
2753 (match_operand:DI 1 "const_int_operand"))]
2755 && optimize_insn_for_size_p ()
2756 && LEGACY_INT_REG_P (operands[0])
2757 && !x86_64_immediate_operand (operands[1], DImode)
2758 && !x86_64_zext_immediate_operand (operands[1], DImode)
2759 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2760 & ~(HOST_WIDE_INT) 0xffffffff)
2761 && peep2_regno_dead_p (0, FLAGS_REG)"
2762 [(set (match_dup 0) (match_dup 1))
2763 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2764 (clobber (reg:CC FLAGS_REG))])]
2766 int shift = ctz_hwi (UINTVAL (operands[1]));
2767 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2768 operands[2] = gen_int_mode (shift, QImode);
2771 (define_insn "*movsi_internal"
2772 [(set (match_operand:SI 0 "nonimmediate_operand"
2773 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2774 (match_operand:SI 1 "general_operand"
2775 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2776 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2777 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2779 switch (get_attr_type (insn))
2782 return standard_sse_constant_opcode (insn, operands);
2785 return "kmovd\t{%1, %0|%0, %1}";
2788 if (operands[1] == const0_rtx)
2789 return "kxord\t%0, %0, %0";
2790 else if (operands[1] == constm1_rtx)
2791 return "kxnord\t%0, %0, %0";
2795 return ix86_output_ssemov (insn, operands);
2798 return "pxor\t%0, %0";
2801 switch (get_attr_mode (insn))
2804 return "movq\t{%1, %0|%0, %1}";
2806 return "movd\t{%1, %0|%0, %1}";
2813 return "lea{l}\t{%E1, %0|%0, %E1}";
2816 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2817 if (ix86_use_lea_for_mov (insn, operands))
2818 return "lea{l}\t{%E1, %0|%0, %E1}";
2820 return "mov{l}\t{%1, %0|%0, %1}";
2827 (cond [(eq_attr "alternative" "12,13")
2828 (const_string "sse2")
2830 (const_string "*")))
2832 (cond [(eq_attr "alternative" "2")
2833 (const_string "mmx")
2834 (eq_attr "alternative" "3,4,5,6,7")
2835 (const_string "mmxmov")
2836 (eq_attr "alternative" "8")
2837 (const_string "sselog1")
2838 (eq_attr "alternative" "9,10,11,12,13")
2839 (const_string "ssemov")
2840 (eq_attr "alternative" "14,15,16")
2841 (const_string "mskmov")
2842 (eq_attr "alternative" "17")
2843 (const_string "msklog")
2844 (and (match_operand 0 "register_operand")
2845 (match_operand 1 "pic_32bit_operand"))
2846 (const_string "lea")
2848 (const_string "imov")))
2849 (set (attr "prefix")
2850 (if_then_else (eq_attr "type" "sselog1,ssemov")
2851 (const_string "maybe_vex")
2852 (const_string "orig")))
2853 (set (attr "prefix_data16")
2854 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2856 (const_string "*")))
2858 (cond [(eq_attr "alternative" "2,3")
2860 (eq_attr "alternative" "8")
2861 (cond [(match_test "TARGET_AVX")
2863 (ior (not (match_test "TARGET_SSE2"))
2864 (match_test "optimize_function_for_size_p (cfun)"))
2865 (const_string "V4SF")
2867 (const_string "TI"))
2868 (eq_attr "alternative" "9")
2869 (cond [(match_test "TARGET_AVX512VL")
2871 (match_test "TARGET_AVX512F")
2873 (match_test "TARGET_AVX")
2875 (ior (not (match_test "TARGET_SSE2"))
2876 (match_test "optimize_function_for_size_p (cfun)"))
2877 (const_string "V4SF")
2879 (const_string "TI"))
2881 (and (eq_attr "alternative" "10,11")
2882 (not (match_test "TARGET_SSE2")))
2885 (const_string "SI")))
2886 (set (attr "preferred_for_speed")
2887 (cond [(eq_attr "alternative" "6,12")
2888 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2889 (eq_attr "alternative" "7,13")
2890 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2892 (symbol_ref "true")))])
2894 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2896 [(set (match_operand:SWI248 0 "general_reg_operand")
2897 (match_operand:SWI248 1 "const_int_operand"))]
2898 "optimize_insn_for_size_p () && optimize_size > 1
2899 && operands[1] != const0_rtx
2900 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2901 && !ix86_red_zone_used
2902 && REGNO (operands[0]) != SP_REG"
2903 [(set (match_dup 2) (match_dup 1))
2904 (set (match_dup 0) (match_dup 3))]
2906 if (GET_MODE (operands[0]) != word_mode)
2907 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2909 operands[2] = gen_rtx_MEM (word_mode,
2910 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2911 operands[3] = gen_rtx_MEM (word_mode,
2912 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2915 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2916 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2918 [(set (match_operand:SWI248 0 "memory_operand")
2919 (match_operand:SWI248 1 "const_int_operand"))]
2920 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2921 && optimize_insn_for_size_p () && optimize_size > 1
2922 && peep2_regno_dead_p (0, FLAGS_REG)"
2923 [(parallel [(set (match_dup 0) (match_dup 1))
2924 (clobber (reg:CC FLAGS_REG))])])
2926 (define_insn "*movhi_internal"
2927 [(set (match_operand:HI 0 "nonimmediate_operand"
2928 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2929 (match_operand:HI 1 "general_operand"
2930 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2931 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2932 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2934 switch (get_attr_type (insn))
2937 /* movzwl is faster than movw on p2 due to partial word stalls,
2938 though not as fast as an aligned movl. */
2939 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2942 switch (which_alternative)
2945 return "kmovw\t{%k1, %0|%0, %k1}";
2947 return "kmovw\t{%1, %k0|%k0, %1}";
2950 return "kmovw\t{%1, %0|%0, %1}";
2956 return ix86_output_ssemov (insn, operands);
2959 if (satisfies_constraint_C (operands[1]))
2960 return standard_sse_constant_opcode (insn, operands);
2962 if (SSE_REG_P (operands[0]))
2963 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2965 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2968 if (operands[1] == const0_rtx)
2969 return "kxorw\t%0, %0, %0";
2970 else if (operands[1] == constm1_rtx)
2971 return "kxnorw\t%0, %0, %0";
2975 if (get_attr_mode (insn) == MODE_SI)
2976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2978 return "mov{w}\t{%1, %0|%0, %1}";
2982 (cond [(eq_attr "alternative" "9,10,11,12,13")
2983 (const_string "sse2")
2984 (eq_attr "alternative" "14")
2985 (const_string "sse4_noavx")
2986 (eq_attr "alternative" "15")
2987 (const_string "avx")
2989 (const_string "*")))
2991 (if_then_else (eq_attr "alternative" "14")
2993 (const_string "1")))
2995 (cond [(eq_attr "alternative" "4,5,6,7")
2996 (const_string "mskmov")
2997 (eq_attr "alternative" "8")
2998 (const_string "msklog")
2999 (eq_attr "alternative" "13,14,15")
3000 (if_then_else (match_test "TARGET_AVX512FP16")
3001 (const_string "ssemov")
3002 (const_string "sselog1"))
3003 (eq_attr "alternative" "11")
3004 (const_string "sselog1")
3005 (eq_attr "alternative" "9,10,12")
3006 (const_string "ssemov")
3007 (match_test "optimize_function_for_size_p (cfun)")
3008 (const_string "imov")
3009 (and (eq_attr "alternative" "0")
3010 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3011 (not (match_test "TARGET_HIMODE_MATH"))))
3012 (const_string "imov")
3013 (and (eq_attr "alternative" "1,2")
3014 (match_operand:HI 1 "aligned_operand"))
3015 (const_string "imov")
3016 (and (match_test "TARGET_MOVX")
3017 (eq_attr "alternative" "0,2"))
3018 (const_string "imovx")
3020 (const_string "imov")))
3021 (set (attr "prefix")
3022 (cond [(eq_attr "alternative" "4,5,6,7,8")
3023 (const_string "vex")
3024 (eq_attr "alternative" "9,10,11,12,13,14,15")
3025 (const_string "maybe_evex")
3027 (const_string "orig")))
3029 (cond [(eq_attr "alternative" "9,10")
3030 (if_then_else (match_test "TARGET_AVX512FP16")
3032 (const_string "SI"))
3033 (eq_attr "alternative" "13,14,15")
3034 (if_then_else (match_test "TARGET_AVX512FP16")
3036 (const_string "TI"))
3037 (eq_attr "alternative" "11")
3038 (cond [(match_test "TARGET_AVX")
3040 (ior (not (match_test "TARGET_SSE2"))
3041 (match_test "optimize_function_for_size_p (cfun)"))
3042 (const_string "V4SF")
3044 (const_string "TI"))
3045 (eq_attr "alternative" "12")
3046 (cond [(match_test "TARGET_AVX512VL")
3048 (match_test "TARGET_AVX512FP16")
3050 (match_test "TARGET_AVX512F")
3052 (match_test "TARGET_AVX")
3054 (ior (not (match_test "TARGET_SSE2"))
3055 (match_test "optimize_function_for_size_p (cfun)"))
3056 (const_string "V4SF")
3058 (const_string "TI"))
3059 (eq_attr "type" "imovx")
3061 (and (eq_attr "alternative" "1,2")
3062 (match_operand:HI 1 "aligned_operand"))
3064 (and (eq_attr "alternative" "0")
3065 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3066 (not (match_test "TARGET_HIMODE_MATH"))))
3069 (const_string "HI")))
3070 (set (attr "preferred_for_speed")
3071 (cond [(eq_attr "alternative" "9")
3072 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3073 (eq_attr "alternative" "10")
3074 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3076 (symbol_ref "true")))])
3078 ;; Situation is quite tricky about when to choose full sized (SImode) move
3079 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3080 ;; partial register dependency machines (such as AMD Athlon), where QImode
3081 ;; moves issue extra dependency and for partial register stalls machines
3082 ;; that don't use QImode patterns (and QImode move cause stall on the next
3085 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3086 ;; register stall machines with, where we use QImode instructions, since
3087 ;; partial register stall can be caused there. Then we use movzx.
3089 (define_insn "*movqi_internal"
3090 [(set (match_operand:QI 0 "nonimmediate_operand"
3091 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3092 (match_operand:QI 1 "general_operand"
3093 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3094 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3095 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3102 switch (get_attr_type (insn))
3105 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3106 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3109 switch (which_alternative)
3112 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3115 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3119 gcc_assert (TARGET_AVX512DQ);
3122 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3128 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3130 snprintf (buf, sizeof (buf), ops, suffix);
3131 output_asm_insn (buf, operands);
3135 if (operands[1] == const0_rtx)
3137 if (get_attr_mode (insn) == MODE_HI)
3138 return "kxorw\t%0, %0, %0";
3140 return "kxorb\t%0, %0, %0";
3142 else if (operands[1] == constm1_rtx)
3144 gcc_assert (TARGET_AVX512DQ);
3145 return "kxnorb\t%0, %0, %0";
3150 if (get_attr_mode (insn) == MODE_SI)
3151 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3153 return "mov{b}\t{%1, %0|%0, %1}";
3157 (cond [(eq_attr "alternative" "1,2")
3158 (const_string "x64")
3159 (eq_attr "alternative" "12,13,15")
3160 (const_string "avx512dq")
3162 (const_string "*")))
3164 (cond [(eq_attr "alternative" "9,10,11,12,13")
3165 (const_string "mskmov")
3166 (eq_attr "alternative" "14,15")
3167 (const_string "msklog")
3168 (and (eq_attr "alternative" "7")
3169 (not (match_operand:QI 1 "aligned_operand")))
3170 (const_string "imovx")
3171 (match_test "optimize_function_for_size_p (cfun)")
3172 (const_string "imov")
3173 (and (eq_attr "alternative" "5")
3174 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3175 (not (match_test "TARGET_QIMODE_MATH"))))
3176 (const_string "imov")
3177 (eq_attr "alternative" "5,7")
3178 (const_string "imovx")
3179 (and (match_test "TARGET_MOVX")
3180 (eq_attr "alternative" "4"))
3181 (const_string "imovx")
3183 (const_string "imov")))
3184 (set (attr "prefix")
3185 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3186 (const_string "vex")
3187 (const_string "orig")))
3189 (cond [(eq_attr "alternative" "5,6,7")
3191 (eq_attr "alternative" "8")
3193 (and (eq_attr "alternative" "9,10,11,14")
3194 (not (match_test "TARGET_AVX512DQ")))
3196 (eq_attr "type" "imovx")
3198 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3200 (and (eq_attr "type" "imov")
3201 (and (eq_attr "alternative" "3")
3202 (match_test "optimize_function_for_size_p (cfun)")))
3204 ;; For -Os, movl where one or both operands are NON_Q_REGS
3205 ;; and both are LEGACY_REGS is shorter than movb.
3206 ;; Otherwise movb and movl sizes are the same, so decide purely
3207 ;; based on speed factors.
3208 (and (eq_attr "type" "imov")
3209 (and (eq_attr "alternative" "1")
3210 (match_test "optimize_function_for_size_p (cfun)")))
3212 (and (eq_attr "type" "imov")
3213 (and (eq_attr "alternative" "0,1,2,3")
3214 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3215 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3217 ;; Avoid partial register stalls when not using QImode arithmetic
3218 (and (eq_attr "type" "imov")
3219 (and (eq_attr "alternative" "0,1,2,3")
3220 (and (match_test "TARGET_PARTIAL_REG_STALL")
3221 (not (match_test "TARGET_QIMODE_MATH")))))
3224 (const_string "QI")))])
3226 /* Reload dislikes loading 0/-1 directly into mask registers.
3227 Try to tidy things up here. */
3229 [(set (match_operand:SWI 0 "general_reg_operand")
3230 (match_operand:SWI 1 "immediate_operand"))
3231 (set (match_operand:SWI 2 "mask_reg_operand")
3233 "peep2_reg_dead_p (2, operands[0])
3234 && (const0_operand (operands[1], <MODE>mode)
3235 || (constm1_operand (operands[1], <MODE>mode)
3236 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3237 [(set (match_dup 2) (match_dup 1))])
3239 ;; Stores and loads of ax to arbitrary constant address.
3240 ;; We fake an second form of instruction to force reload to load address
3241 ;; into register when rax is not available
3242 (define_insn "*movabs<mode>_1"
3243 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3244 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3245 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3247 /* Recover the full memory rtx. */
3248 operands[0] = SET_DEST (PATTERN (insn));
3249 switch (which_alternative)
3252 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3254 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3259 [(set_attr "type" "imov")
3260 (set_attr "modrm" "0,*")
3261 (set_attr "length_address" "8,0")
3262 (set_attr "length_immediate" "0,*")
3263 (set_attr "memory" "store")
3264 (set_attr "mode" "<MODE>")])
3266 (define_insn "*movabs<mode>_2"
3267 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3268 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3269 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3271 /* Recover the full memory rtx. */
3272 operands[1] = SET_SRC (PATTERN (insn));
3273 switch (which_alternative)
3276 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3278 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3283 [(set_attr "type" "imov")
3284 (set_attr "modrm" "0,*")
3285 (set_attr "length_address" "8,0")
3286 (set_attr "length_immediate" "0")
3287 (set_attr "memory" "load")
3288 (set_attr "mode" "<MODE>")])
3290 (define_insn "swap<mode>"
3291 [(set (match_operand:SWI48 0 "register_operand" "+r")
3292 (match_operand:SWI48 1 "register_operand" "+r"))
3296 "xchg{<imodesuffix>}\t%1, %0"
3297 [(set_attr "type" "imov")
3298 (set_attr "mode" "<MODE>")
3299 (set_attr "pent_pair" "np")
3300 (set_attr "athlon_decode" "vector")
3301 (set_attr "amdfam10_decode" "double")
3302 (set_attr "bdver1_decode" "double")])
3304 (define_insn "*swap<mode>"
3305 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3306 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3311 xchg{<imodesuffix>}\t%1, %0
3313 [(set_attr "type" "imov")
3314 (set_attr "mode" "<MODE>,SI")
3315 (set (attr "preferred_for_size")
3316 (cond [(eq_attr "alternative" "0")
3317 (symbol_ref "false")]
3318 (symbol_ref "true")))
3319 ;; Potential partial reg stall on alternative 1.
3320 (set (attr "preferred_for_speed")
3321 (cond [(eq_attr "alternative" "1")
3322 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3323 (symbol_ref "true")))
3324 (set_attr "pent_pair" "np")
3325 (set_attr "athlon_decode" "vector")
3326 (set_attr "amdfam10_decode" "double")
3327 (set_attr "bdver1_decode" "double")])
3330 [(set (match_operand:SWI 0 "general_reg_operand")
3331 (match_operand:SWI 1 "general_reg_operand"))
3333 (match_operand:SWI 2 "general_reg_operand"))
3334 (set (match_dup 2) (match_dup 0))]
3335 "peep2_reg_dead_p (3, operands[0])
3336 && optimize_insn_for_size_p ()"
3337 [(parallel [(set (match_dup 1) (match_dup 2))
3338 (set (match_dup 2) (match_dup 1))])])
3340 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3342 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3343 (match_operand:SWI 1 "general_reg_operand"))
3344 (set (match_dup 1) (match_dup 0))])]
3345 "((REGNO (operands[0]) != AX_REG
3346 && REGNO (operands[1]) != AX_REG)
3347 || optimize_size < 2
3348 || !optimize_insn_for_size_p ())
3349 && peep2_reg_dead_p (1, operands[0])"
3350 [(set (match_dup 1) (match_dup 0))])
3352 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3354 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3355 (match_operand:SWI 1 "general_reg_operand"))
3356 (set (match_dup 1) (match_dup 0))])]
3357 "((REGNO (operands[0]) != AX_REG
3358 && REGNO (operands[1]) != AX_REG)
3359 || optimize_size < 2
3360 || !optimize_insn_for_size_p ())
3361 && peep2_reg_dead_p (1, operands[1])"
3362 [(set (match_dup 0) (match_dup 1))])
3364 ;; Convert moves to/from AX_REG into xchg with -Oz.
3366 [(set (match_operand:SWI48 0 "general_reg_operand")
3367 (match_operand:SWI48 1 "general_reg_operand"))]
3369 && ((REGNO (operands[0]) == AX_REG)
3370 != (REGNO (operands[1]) == AX_REG))
3371 && optimize_insn_for_size_p ()
3372 && peep2_reg_dead_p (1, operands[1])"
3373 [(parallel [(set (match_dup 0) (match_dup 1))
3374 (set (match_dup 1) (match_dup 0))])])
3376 (define_expand "movstrict<mode>"
3377 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3378 (match_operand:SWI12 1 "general_operand"))]
3381 gcc_assert (SUBREG_P (operands[0]));
3382 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3383 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3387 (define_insn "*movstrict<mode>_1"
3388 [(set (strict_low_part
3389 (match_operand:SWI12 0 "register_operand" "+<r>"))
3390 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3392 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3393 [(set_attr "type" "imov")
3394 (set_attr "mode" "<MODE>")])
3396 (define_insn "*movstrict<mode>_xor"
3397 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3398 (match_operand:SWI12 1 "const0_operand"))
3399 (clobber (reg:CC FLAGS_REG))]
3401 "xor{<imodesuffix>}\t%0, %0"
3402 [(set_attr "type" "alu1")
3403 (set_attr "mode" "<MODE>")
3404 (set_attr "length_immediate" "0")])
3406 (define_expand "extv<mode>"
3407 [(set (match_operand:SWI24 0 "register_operand")
3408 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3409 (match_operand:QI 2 "const_int_operand")
3410 (match_operand:QI 3 "const_int_operand")))]
3413 /* Handle extractions from %ah et al. */
3414 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3417 unsigned int regno = reg_or_subregno (operands[1]);
3419 /* Be careful to expand only with registers having upper parts. */
3420 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3421 operands[1] = copy_to_reg (operands[1]);
3424 (define_insn "*extv<mode>"
3425 [(set (match_operand:SWI24 0 "register_operand" "=R")
3426 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3430 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3431 [(set_attr "type" "imovx")
3432 (set_attr "mode" "SI")])
3434 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3435 (define_insn_and_split "*extv<mode>_1_0"
3436 [(set (match_operand:SWI48 0 "register_operand" "=r")
3437 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3440 (clobber (reg:CC FLAGS_REG))]
3444 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3445 (clobber (reg:CC FLAGS_REG))])
3446 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3447 (clobber (reg:CC FLAGS_REG))])])
3449 (define_expand "extzv<mode>"
3450 [(set (match_operand:SWI248 0 "register_operand")
3451 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3452 (match_operand:QI 2 "const_int_operand")
3453 (match_operand:QI 3 "const_int_operand")))]
3456 if (ix86_expand_pextr (operands))
3459 /* Handle extractions from %ah et al. */
3460 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3463 unsigned int regno = reg_or_subregno (operands[1]);
3465 /* Be careful to expand only with registers having upper parts. */
3466 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3467 operands[1] = copy_to_reg (operands[1]);
3470 (define_insn "*extzv<mode>"
3471 [(set (match_operand:SWI248 0 "register_operand" "=R")
3472 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3476 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3477 [(set_attr "type" "imovx")
3478 (set_attr "mode" "SI")])
3480 (define_insn "*extzvqi_mem_rex64"
3481 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3483 (match_operator:SWI248 2 "extract_operator"
3484 [(match_operand 1 "int248_register_operand" "Q")
3486 (const_int 8)]) 0))]
3487 "TARGET_64BIT && reload_completed"
3488 "mov{b}\t{%h1, %0|%0, %h1}"
3489 [(set_attr "type" "imov")
3490 (set_attr "mode" "QI")])
3492 (define_insn "*extzvqi"
3493 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3495 (match_operator:SWI248 2 "extract_operator"
3496 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3498 (const_int 8)]) 0))]
3501 switch (get_attr_type (insn))
3504 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3506 return "mov{b}\t{%h1, %0|%0, %h1}";
3509 [(set_attr "isa" "*,*,nox64")
3511 (if_then_else (and (match_operand:QI 0 "register_operand")
3512 (ior (not (match_operand:QI 0 "QIreg_operand"))
3513 (match_test "TARGET_MOVX")))
3514 (const_string "imovx")
3515 (const_string "imov")))
3517 (if_then_else (eq_attr "type" "imovx")
3519 (const_string "QI")))])
3522 [(set (match_operand:QI 0 "register_operand")
3524 (match_operator:SWI248 3 "extract_operator"
3525 [(match_operand 1 "int248_register_operand")
3528 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3530 && peep2_reg_dead_p (2, operands[0])"
3536 (const_int 8)]) 0))])
3538 (define_expand "insv<mode>"
3539 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3540 (match_operand:QI 1 "const_int_operand")
3541 (match_operand:QI 2 "const_int_operand"))
3542 (match_operand:SWI248 3 "register_operand"))]
3547 if (ix86_expand_pinsr (operands))
3550 /* Handle insertions to %ah et al. */
3551 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3554 unsigned int regno = reg_or_subregno (operands[0]);
3556 /* Be careful to expand only with registers having upper parts. */
3557 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3558 dst = copy_to_reg (operands[0]);
3562 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3564 /* Fix up the destination if needed. */
3565 if (dst != operands[0])
3566 emit_move_insn (operands[0], dst);
3571 (define_insn "*insvqi_1_mem_rex64"
3572 [(set (zero_extract:SWI248
3573 (match_operand 0 "int248_register_operand" "+Q")
3577 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3578 "TARGET_64BIT && reload_completed"
3579 "mov{b}\t{%1, %h0|%h0, %1}"
3580 [(set_attr "type" "imov")
3581 (set_attr "mode" "QI")])
3583 (define_insn "@insv<mode>_1"
3584 [(set (zero_extract:SWI248
3585 (match_operand 0 "int248_register_operand" "+Q,Q")
3588 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3591 if (CONST_INT_P (operands[1]))
3592 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3593 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3595 [(set_attr "isa" "*,nox64")
3596 (set_attr "type" "imov")
3597 (set_attr "mode" "QI")])
3599 (define_insn "*insvqi_1"
3600 [(set (zero_extract:SWI248
3601 (match_operand 0 "int248_register_operand" "+Q,Q")
3605 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3607 "mov{b}\t{%1, %h0|%h0, %1}"
3608 [(set_attr "isa" "*,nox64")
3609 (set_attr "type" "imov")
3610 (set_attr "mode" "QI")])
3613 [(set (match_operand:QI 0 "register_operand")
3614 (match_operand:QI 1 "norex_memory_operand"))
3615 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3618 (subreg:SWI248 (match_dup 0) 0))]
3620 && peep2_reg_dead_p (2, operands[0])"
3621 [(set (zero_extract:SWI248 (match_dup 2)
3624 (subreg:SWI248 (match_dup 1) 0))])
3626 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3628 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3630 (clobber (reg:CC FLAGS_REG))])
3631 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3635 "REGNO (operands[0]) == REGNO (operands[1])"
3636 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3638 (clobber (reg:CC FLAGS_REG))])])
3640 ;; Combine movl followed by movb.
3642 [(set (match_operand:SWI48 0 "general_reg_operand")
3643 (match_operand:SWI48 1 "const_int_operand"))
3644 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3647 (match_operand:SWI248 3 "const_int_operand"))]
3648 "REGNO (operands[0]) == REGNO (operands[2])"
3649 [(set (match_operand:SWI48 0 "general_reg_operand")
3652 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3653 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3654 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3657 (define_insn "*insvqi_2"
3658 [(set (zero_extract:SWI248
3659 (match_operand 0 "int248_register_operand" "+Q")
3662 (match_operator:SWI248 2 "extract_operator"
3663 [(match_operand 1 "int248_register_operand" "Q")
3667 "mov{b}\t{%h1, %h0|%h0, %h1}"
3668 [(set_attr "type" "imov")
3669 (set_attr "mode" "QI")])
3671 (define_insn "*insvqi_3"
3672 [(set (zero_extract:SWI248
3673 (match_operand 0 "int248_register_operand" "+Q")
3677 (match_operand:SWI248 1 "register_operand" "Q")
3680 "mov{b}\t{%h1, %h0|%h0, %h1}"
3681 [(set_attr "type" "imov")
3682 (set_attr "mode" "QI")])
3684 (define_code_iterator any_or_plus [plus ior xor])
3686 (define_insn_and_split "*insvti_highpart_1"
3687 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3690 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3691 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3694 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3697 && CONST_WIDE_INT_P (operands[3])
3698 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3699 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3700 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3702 "&& reload_completed"
3705 operands[4] = gen_lowpart (DImode, operands[1]);
3706 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3710 (define_insn_and_split "*insvti_lowpart_1"
3711 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3714 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3715 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3717 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3719 && CONST_WIDE_INT_P (operands[3])
3720 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3721 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3722 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3724 "&& reload_completed"
3727 operands[4] = gen_highpart (DImode, operands[1]);
3728 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3732 (define_insn_and_split "*insvdi_lowpart_1"
3733 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3736 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3737 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3739 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3741 && CONST_INT_P (operands[3])
3742 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3744 "&& reload_completed"
3747 operands[4] = gen_highpart (SImode, operands[1]);
3748 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3752 ;; Floating point push instructions.
3754 (define_insn "*pushtf"
3755 [(set (match_operand:TF 0 "push_operand" "=<,<")
3756 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3757 "TARGET_64BIT || TARGET_SSE"
3759 /* This insn should be already split before reg-stack. */
3762 [(set_attr "isa" "*,x64")
3763 (set_attr "type" "multi")
3764 (set_attr "unit" "sse,*")
3765 (set_attr "mode" "TF,DI")])
3767 ;; %%% Kill this when call knows how to work this out.
3769 [(set (match_operand:TF 0 "push_operand")
3770 (match_operand:TF 1 "sse_reg_operand"))]
3771 "TARGET_SSE && reload_completed"
3772 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3773 (set (match_dup 0) (match_dup 1))]
3775 /* Preserve memory attributes. */
3776 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3779 (define_insn "*pushxf"
3780 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3781 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3784 /* This insn should be already split before reg-stack. */
3787 [(set_attr "isa" "*,*,*,nox64,x64")
3788 (set_attr "type" "multi")
3789 (set_attr "unit" "i387,*,*,*,*")
3791 (cond [(eq_attr "alternative" "1,2,3,4")
3792 (if_then_else (match_test "TARGET_64BIT")
3794 (const_string "SI"))
3796 (const_string "XF")))
3797 (set (attr "preferred_for_size")
3798 (cond [(eq_attr "alternative" "1")
3799 (symbol_ref "false")]
3800 (symbol_ref "true")))])
3802 ;; %%% Kill this when call knows how to work this out.
3804 [(set (match_operand:XF 0 "push_operand")
3805 (match_operand:XF 1 "fp_register_operand"))]
3807 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3808 (set (match_dup 0) (match_dup 1))]
3810 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3811 /* Preserve memory attributes. */
3812 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3815 (define_insn "*pushdf"
3816 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3817 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3820 /* This insn should be already split before reg-stack. */
3823 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3824 (set_attr "type" "multi")
3825 (set_attr "unit" "i387,*,*,*,*,sse")
3826 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3827 (set (attr "preferred_for_size")
3828 (cond [(eq_attr "alternative" "1")
3829 (symbol_ref "false")]
3830 (symbol_ref "true")))
3831 (set (attr "preferred_for_speed")
3832 (cond [(eq_attr "alternative" "1")
3833 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3834 (symbol_ref "true")))])
3836 ;; %%% Kill this when call knows how to work this out.
3838 [(set (match_operand:DF 0 "push_operand")
3839 (match_operand:DF 1 "any_fp_register_operand"))]
3841 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3842 (set (match_dup 0) (match_dup 1))]
3844 /* Preserve memory attributes. */
3845 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3848 (define_mode_iterator HFBF [HF BF])
3850 (define_insn "*push<mode>_rex64"
3851 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3852 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3855 /* Anything else should be already split before reg-stack. */
3856 gcc_assert (which_alternative == 0);
3857 return "push{q}\t%q1";
3859 [(set_attr "isa" "*,sse4")
3860 (set_attr "type" "push,multi")
3861 (set_attr "mode" "DI,TI")])
3863 (define_insn "*push<mode>"
3864 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3865 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3868 /* Anything else should be already split before reg-stack. */
3869 gcc_assert (which_alternative == 0);
3870 return "push{l}\t%k1";
3872 [(set_attr "isa" "*,sse4")
3873 (set_attr "type" "push,multi")
3874 (set_attr "mode" "SI,TI")])
3876 (define_insn "push2_di"
3877 [(set (match_operand:TI 0 "push_operand" "=<")
3878 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3879 (match_operand:DI 2 "register_operand" "r")]
3881 "TARGET_APX_PUSH2POP2"
3883 [(set_attr "mode" "TI")
3884 (set_attr "type" "multi")
3885 (set_attr "prefix" "evex")])
3887 (define_insn "pop2_di"
3888 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3889 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3890 UNSPEC_APXPOP2_LOW))
3891 (set (match_operand:DI 2 "register_operand" "=r")
3892 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3893 "TARGET_APX_PUSH2POP2"
3895 [(set_attr "mode" "TI")
3896 (set_attr "prefix" "evex")])
3898 (define_insn "*pushsf_rex64"
3899 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3900 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3903 /* Anything else should be already split before reg-stack. */
3904 if (which_alternative != 1)
3906 return "push{q}\t%q1";
3908 [(set_attr "type" "multi,push,multi")
3909 (set_attr "unit" "i387,*,*")
3910 (set_attr "mode" "SF,DI,SF")])
3912 (define_insn "*pushsf"
3913 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3914 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3917 /* Anything else should be already split before reg-stack. */
3918 if (which_alternative != 1)
3920 return "push{l}\t%1";
3922 [(set_attr "type" "multi,push,multi")
3923 (set_attr "unit" "i387,*,*")
3924 (set_attr "mode" "SF,SI,SF")])
3926 (define_mode_iterator MODESH [SF HF BF])
3927 ;; %%% Kill this when call knows how to work this out.
3929 [(set (match_operand:MODESH 0 "push_operand")
3930 (match_operand:MODESH 1 "any_fp_register_operand"))]
3932 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3933 (set (match_dup 0) (match_dup 1))]
3935 rtx op = XEXP (operands[0], 0);
3936 if (GET_CODE (op) == PRE_DEC)
3938 gcc_assert (!TARGET_64BIT);
3943 op = XEXP (XEXP (op, 1), 1);
3944 gcc_assert (CONST_INT_P (op));
3947 /* Preserve memory attributes. */
3948 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3952 [(set (match_operand:SF 0 "push_operand")
3953 (match_operand:SF 1 "memory_operand"))]
3955 && find_constant_src (insn)"
3956 [(set (match_dup 0) (match_dup 2))]
3957 "operands[2] = find_constant_src (curr_insn);")
3960 [(set (match_operand 0 "push_operand")
3961 (match_operand 1 "general_gr_operand"))]
3963 && (GET_MODE (operands[0]) == TFmode
3964 || GET_MODE (operands[0]) == XFmode
3965 || GET_MODE (operands[0]) == DFmode)"
3967 "ix86_split_long_move (operands); DONE;")
3969 ;; Floating point move instructions.
3971 (define_expand "movtf"
3972 [(set (match_operand:TF 0 "nonimmediate_operand")
3973 (match_operand:TF 1 "nonimmediate_operand"))]
3974 "TARGET_64BIT || TARGET_SSE"
3975 "ix86_expand_move (TFmode, operands); DONE;")
3977 (define_expand "mov<mode>"
3978 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3979 (match_operand:X87MODEFH 1 "general_operand"))]
3981 "ix86_expand_move (<MODE>mode, operands); DONE;")
3983 (define_insn "*movtf_internal"
3984 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3985 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3986 "(TARGET_64BIT || TARGET_SSE)
3987 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3988 && (lra_in_progress || reload_completed
3989 || !CONST_DOUBLE_P (operands[1])
3990 || (standard_sse_constant_p (operands[1], TFmode) == 1
3991 && !memory_operand (operands[0], TFmode))
3992 || (!TARGET_MEMORY_MISMATCH_STALL
3993 && memory_operand (operands[0], TFmode)))"
3995 switch (get_attr_type (insn))
3998 return standard_sse_constant_opcode (insn, operands);
4001 return ix86_output_ssemov (insn, operands);
4010 [(set_attr "isa" "*,*,*,x64,x64")
4011 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
4012 (set (attr "prefix")
4013 (if_then_else (eq_attr "type" "sselog1,ssemov")
4014 (const_string "maybe_vex")
4015 (const_string "orig")))
4017 (cond [(eq_attr "alternative" "3,4")
4019 (match_test "TARGET_AVX")
4021 (ior (not (match_test "TARGET_SSE2"))
4022 (match_test "optimize_function_for_size_p (cfun)"))
4023 (const_string "V4SF")
4024 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4025 (const_string "V4SF")
4026 (and (eq_attr "alternative" "2")
4027 (match_test "TARGET_SSE_TYPELESS_STORES"))
4028 (const_string "V4SF")
4030 (const_string "TI")))])
4033 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
4034 (match_operand:TF 1 "general_gr_operand"))]
4037 "ix86_split_long_move (operands); DONE;")
4039 ;; Possible store forwarding (partial memory) stall
4040 ;; in alternatives 4, 6, 7 and 8.
4041 (define_insn "*movxf_internal"
4042 [(set (match_operand:XF 0 "nonimmediate_operand"
4043 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
4044 (match_operand:XF 1 "general_operand"
4045 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
4046 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4047 && (lra_in_progress || reload_completed
4048 || !CONST_DOUBLE_P (operands[1])
4049 || ((optimize_function_for_size_p (cfun)
4050 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4051 && standard_80387_constant_p (operands[1]) > 0
4052 && !memory_operand (operands[0], XFmode))
4053 || (!TARGET_MEMORY_MISMATCH_STALL
4054 && memory_operand (operands[0], XFmode))
4055 || !TARGET_HARD_XF_REGS)"
4057 switch (get_attr_type (insn))
4060 if (which_alternative == 2)
4061 return standard_80387_constant_opcode (operands[1]);
4062 return output_387_reg_move (insn, operands);
4072 (cond [(eq_attr "alternative" "7,10")
4073 (const_string "nox64")
4074 (eq_attr "alternative" "8,11")
4075 (const_string "x64")
4077 (const_string "*")))
4079 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4080 (const_string "multi")
4082 (const_string "fmov")))
4084 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4085 (if_then_else (match_test "TARGET_64BIT")
4087 (const_string "SI"))
4089 (const_string "XF")))
4090 (set (attr "preferred_for_size")
4091 (cond [(eq_attr "alternative" "3,4")
4092 (symbol_ref "false")]
4093 (symbol_ref "true")))
4094 (set (attr "enabled")
4095 (cond [(eq_attr "alternative" "9,10,11")
4097 (match_test "TARGET_HARD_XF_REGS")
4098 (symbol_ref "false")
4100 (not (match_test "TARGET_HARD_XF_REGS"))
4101 (symbol_ref "false")
4103 (const_string "*")))])
4106 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4107 (match_operand:XF 1 "general_gr_operand"))]
4110 "ix86_split_long_move (operands); DONE;")
4112 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4113 (define_insn "*movdf_internal"
4114 [(set (match_operand:DF 0 "nonimmediate_operand"
4115 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,Yv,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m")
4116 (match_operand:DF 1 "general_operand"
4117 "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"))]
4118 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4119 && (lra_in_progress || reload_completed
4120 || !CONST_DOUBLE_P (operands[1])
4121 || ((optimize_function_for_size_p (cfun)
4122 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4123 && IS_STACK_MODE (DFmode)
4124 && standard_80387_constant_p (operands[1]) > 0
4125 && !memory_operand (operands[0], DFmode))
4126 || (TARGET_SSE2 && TARGET_SSE_MATH
4127 && standard_sse_constant_p (operands[1], DFmode) == 1
4128 && !memory_operand (operands[0], DFmode))
4129 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4130 && memory_operand (operands[0], DFmode))
4131 || !TARGET_HARD_DF_REGS)"
4133 switch (get_attr_type (insn))
4136 if (which_alternative == 2)
4137 return standard_80387_constant_opcode (operands[1]);
4138 return output_387_reg_move (insn, operands);
4144 if (get_attr_mode (insn) == MODE_SI)
4145 return "mov{l}\t{%1, %k0|%k0, %1}";
4146 else if (which_alternative == 11)
4147 return "movabs{q}\t{%1, %0|%0, %1}";
4149 return "mov{q}\t{%1, %0|%0, %1}";
4152 return standard_sse_constant_opcode (insn, operands);
4155 return ix86_output_ssemov (insn, operands);
4162 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4163 (const_string "nox64")
4164 (eq_attr "alternative" "8,9,10,11,24,25")
4165 (const_string "x64")
4166 (eq_attr "alternative" "12,13,14,15")
4167 (const_string "sse2")
4168 (eq_attr "alternative" "20,21")
4169 (const_string "x64_sse2")
4171 (const_string "*")))
4173 (cond [(eq_attr "alternative" "0,1,2")
4174 (const_string "fmov")
4175 (eq_attr "alternative" "3,4,5,6,7,22,23")
4176 (const_string "multi")
4177 (eq_attr "alternative" "8,9,10,11,24,25")
4178 (const_string "imov")
4179 (eq_attr "alternative" "12,16")
4180 (const_string "sselog1")
4182 (const_string "ssemov")))
4184 (if_then_else (eq_attr "alternative" "11")
4186 (const_string "*")))
4187 (set (attr "length_immediate")
4188 (if_then_else (eq_attr "alternative" "11")
4190 (const_string "*")))
4191 (set (attr "prefix")
4192 (if_then_else (eq_attr "type" "sselog1,ssemov")
4193 (const_string "maybe_vex")
4194 (const_string "orig")))
4195 (set (attr "prefix_data16")
4197 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4198 (eq_attr "mode" "V1DF"))
4200 (const_string "*")))
4202 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4204 (eq_attr "alternative" "8,9,11,20,21,24,25")
4207 /* xorps is one byte shorter for non-AVX targets. */
4208 (eq_attr "alternative" "12,16")
4209 (cond [(match_test "TARGET_AVX")
4210 (const_string "V2DF")
4211 (ior (not (match_test "TARGET_SSE2"))
4212 (match_test "optimize_function_for_size_p (cfun)"))
4213 (const_string "V4SF")
4214 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4217 (const_string "V2DF"))
4219 /* For architectures resolving dependencies on
4220 whole SSE registers use movapd to break dependency
4221 chains, otherwise use short move to avoid extra work. */
4223 /* movaps is one byte shorter for non-AVX targets. */
4224 (eq_attr "alternative" "13,17")
4225 (cond [(match_test "TARGET_AVX512VL")
4226 (const_string "V2DF")
4227 (match_test "TARGET_AVX512F")
4229 (match_test "TARGET_AVX")
4230 (const_string "V2DF")
4231 (ior (not (match_test "TARGET_SSE2"))
4232 (match_test "optimize_function_for_size_p (cfun)"))
4233 (const_string "V4SF")
4234 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4235 (const_string "V4SF")
4236 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4237 (const_string "V2DF")
4239 (const_string "DF"))
4241 /* For architectures resolving dependencies on register
4242 parts we may avoid extra work to zero out upper part
4244 (eq_attr "alternative" "14,18")
4245 (cond [(not (match_test "TARGET_SSE2"))
4246 (const_string "V2SF")
4247 (match_test "TARGET_AVX")
4249 (match_test "TARGET_SSE_SPLIT_REGS")
4250 (const_string "V1DF")
4252 (const_string "DF"))
4254 (and (eq_attr "alternative" "15,19")
4255 (not (match_test "TARGET_SSE2")))
4256 (const_string "V2SF")
4258 (const_string "DF")))
4259 (set (attr "preferred_for_size")
4260 (cond [(eq_attr "alternative" "3,4")
4261 (symbol_ref "false")]
4262 (symbol_ref "true")))
4263 (set (attr "preferred_for_speed")
4264 (cond [(eq_attr "alternative" "3,4")
4265 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4266 (eq_attr "alternative" "20")
4267 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4268 (eq_attr "alternative" "21")
4269 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4271 (symbol_ref "true")))
4272 (set (attr "enabled")
4273 (cond [(eq_attr "alternative" "22,23,24,25")
4275 (match_test "TARGET_HARD_DF_REGS")
4276 (symbol_ref "false")
4278 (not (match_test "TARGET_HARD_DF_REGS"))
4279 (symbol_ref "false")
4281 (const_string "*")))])
4284 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4285 (match_operand:DF 1 "general_gr_operand"))]
4286 "!TARGET_64BIT && reload_completed"
4288 "ix86_split_long_move (operands); DONE;")
4290 (define_insn "*movsf_internal"
4291 [(set (match_operand:SF 0 "nonimmediate_operand"
4292 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4293 (match_operand:SF 1 "general_operand"
4294 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4296 && (lra_in_progress || reload_completed
4297 || !CONST_DOUBLE_P (operands[1])
4298 || ((optimize_function_for_size_p (cfun)
4299 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4300 && IS_STACK_MODE (SFmode)
4301 && standard_80387_constant_p (operands[1]) > 0)
4302 || (TARGET_SSE && TARGET_SSE_MATH
4303 && standard_sse_constant_p (operands[1], SFmode) == 1)
4304 || memory_operand (operands[0], SFmode)
4305 || !TARGET_HARD_SF_REGS)"
4307 switch (get_attr_type (insn))
4310 if (which_alternative == 2)
4311 return standard_80387_constant_opcode (operands[1]);
4312 return output_387_reg_move (insn, operands);
4315 return "mov{l}\t{%1, %0|%0, %1}";
4318 return standard_sse_constant_opcode (insn, operands);
4321 return ix86_output_ssemov (insn, operands);
4324 switch (get_attr_mode (insn))
4327 return "movq\t{%1, %0|%0, %1}";
4329 return "movd\t{%1, %0|%0, %1}";
4340 (cond [(eq_attr "alternative" "9,10")
4341 (const_string "sse2")
4343 (const_string "*")))
4345 (cond [(eq_attr "alternative" "0,1,2")
4346 (const_string "fmov")
4347 (eq_attr "alternative" "3,4,16,17")
4348 (const_string "imov")
4349 (eq_attr "alternative" "5")
4350 (const_string "sselog1")
4351 (eq_attr "alternative" "11,12,13,14,15")
4352 (const_string "mmxmov")
4354 (const_string "ssemov")))
4355 (set (attr "prefix")
4356 (if_then_else (eq_attr "type" "sselog1,ssemov")
4357 (const_string "maybe_vex")
4358 (const_string "orig")))
4359 (set (attr "prefix_data16")
4360 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4362 (const_string "*")))
4364 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4366 (eq_attr "alternative" "11")
4368 (eq_attr "alternative" "5")
4369 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4370 (not (match_test "TARGET_PREFER_AVX256")))
4371 (const_string "V16SF")
4372 (match_test "TARGET_AVX")
4373 (const_string "V4SF")
4374 (ior (not (match_test "TARGET_SSE2"))
4375 (match_test "optimize_function_for_size_p (cfun)"))
4376 (const_string "V4SF")
4377 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4380 (const_string "V4SF"))
4382 /* For architectures resolving dependencies on
4383 whole SSE registers use APS move to break dependency
4384 chains, otherwise use short move to avoid extra work.
4386 Do the same for architectures resolving dependencies on
4387 the parts. While in DF mode it is better to always handle
4388 just register parts, the SF mode is different due to lack
4389 of instructions to load just part of the register. It is
4390 better to maintain the whole registers in single format
4391 to avoid problems on using packed logical operations. */
4392 (eq_attr "alternative" "6")
4393 (cond [(match_test "TARGET_AVX512VL")
4394 (const_string "V4SF")
4395 (match_test "TARGET_AVX512F")
4397 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4398 (match_test "TARGET_SSE_SPLIT_REGS"))
4399 (const_string "V4SF")
4401 (const_string "SF"))
4403 (const_string "SF")))
4404 (set (attr "preferred_for_speed")
4405 (cond [(eq_attr "alternative" "9,14")
4406 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4407 (eq_attr "alternative" "10,15")
4408 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4410 (symbol_ref "true")))
4411 (set (attr "enabled")
4412 (cond [(eq_attr "alternative" "16,17")
4414 (match_test "TARGET_HARD_SF_REGS")
4415 (symbol_ref "false")
4417 (not (match_test "TARGET_HARD_SF_REGS"))
4418 (symbol_ref "false")
4420 (const_string "*")))])
4422 (define_mode_attr hfbfconstf
4425 (define_insn "*mov<mode>_internal"
4426 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4427 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4428 (match_operand:HFBF 1 "general_operand"
4429 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4430 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4433 || !CONST_DOUBLE_P (operands[1])
4435 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4436 || memory_operand (operands[0], <MODE>mode))"
4438 switch (get_attr_type (insn))
4441 /* movzwl is faster than movw on p2 due to partial word stalls,
4442 though not as fast as an aligned movl. */
4443 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4446 return ix86_output_ssemov (insn, operands);
4449 if (satisfies_constraint_C (operands[1]))
4450 return standard_sse_constant_opcode (insn, operands);
4452 if (SSE_REG_P (operands[0]))
4453 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4455 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4458 if (get_attr_mode (insn) == MODE_SI)
4459 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4461 return "mov{w}\t{%1, %0|%0, %1}";
4465 (cond [(eq_attr "alternative" "4,5,6,9,10")
4466 (const_string "sse2")
4467 (eq_attr "alternative" "7")
4468 (const_string "sse4_noavx")
4469 (eq_attr "alternative" "8")
4470 (const_string "avx")
4472 (const_string "*")))
4474 (if_then_else (eq_attr "alternative" "8")
4476 (const_string "1")))
4478 (cond [(eq_attr "alternative" "4")
4479 (const_string "sselog1")
4480 (eq_attr "alternative" "5,6,9")
4481 (const_string "ssemov")
4482 (eq_attr "alternative" "7,8,10")
4484 (match_test ("TARGET_AVX512FP16"))
4485 (const_string "ssemov")
4486 (const_string "sselog1"))
4487 (match_test "optimize_function_for_size_p (cfun)")
4488 (const_string "imov")
4489 (and (eq_attr "alternative" "0")
4490 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4491 (not (match_test "TARGET_HIMODE_MATH"))))
4492 (const_string "imov")
4493 (and (eq_attr "alternative" "1,2")
4494 (match_operand:HI 1 "aligned_operand"))
4495 (const_string "imov")
4496 (and (match_test "TARGET_MOVX")
4497 (eq_attr "alternative" "0,2"))
4498 (const_string "imovx")
4500 (const_string "imov")))
4501 (set (attr "prefix")
4502 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4503 (const_string "maybe_vex")
4505 (const_string "orig")))
4507 (cond [(eq_attr "alternative" "4")
4508 (const_string "V4SF")
4509 (eq_attr "alternative" "6,9")
4511 (match_test "TARGET_AVX512FP16")
4513 (const_string "SI"))
4514 (eq_attr "alternative" "7,8,10")
4516 (match_test "TARGET_AVX512FP16")
4518 (const_string "TI"))
4519 (eq_attr "alternative" "5")
4520 (cond [(match_test "TARGET_AVX512VL")
4521 (const_string "V4SF")
4522 (match_test "TARGET_AVX512FP16")
4524 (match_test "TARGET_AVX512F")
4526 (match_test "TARGET_AVX")
4527 (const_string "V4SF")
4528 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4529 (match_test "TARGET_SSE_SPLIT_REGS"))
4530 (const_string "V4SF")
4532 (const_string "SF"))
4533 (eq_attr "type" "imovx")
4535 (and (eq_attr "alternative" "1,2")
4536 (match_operand:HI 1 "aligned_operand"))
4538 (and (eq_attr "alternative" "0")
4539 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4540 (not (match_test "TARGET_HIMODE_MATH"))))
4543 (const_string "HI")))
4544 (set (attr "enabled")
4545 (cond [(and (match_test "<MODE>mode == BFmode")
4546 (eq_attr "alternative" "1"))
4547 (symbol_ref "false")
4549 (const_string "*")))])
4552 [(set (match_operand 0 "any_fp_register_operand")
4553 (match_operand 1 "memory_operand"))]
4555 && (GET_MODE (operands[0]) == TFmode
4556 || GET_MODE (operands[0]) == XFmode
4557 || GET_MODE (operands[0]) == DFmode
4558 || GET_MODE (operands[0]) == SFmode)
4559 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4560 [(set (match_dup 0) (match_dup 2))]
4561 "operands[2] = find_constant_src (curr_insn);")
4564 [(set (match_operand 0 "any_fp_register_operand")
4565 (float_extend (match_operand 1 "memory_operand")))]
4567 && (GET_MODE (operands[0]) == TFmode
4568 || GET_MODE (operands[0]) == XFmode
4569 || GET_MODE (operands[0]) == DFmode)
4570 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4571 [(set (match_dup 0) (match_dup 2))]
4572 "operands[2] = find_constant_src (curr_insn);")
4574 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4576 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4577 (match_operand:X87MODEF 1 "immediate_operand"))]
4579 && (standard_80387_constant_p (operands[1]) == 8
4580 || standard_80387_constant_p (operands[1]) == 9)"
4581 [(set (match_dup 0)(match_dup 1))
4583 (neg:X87MODEF (match_dup 0)))]
4585 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4586 operands[1] = CONST0_RTX (<MODE>mode);
4588 operands[1] = CONST1_RTX (<MODE>mode);
4591 (define_insn "*swapxf"
4592 [(set (match_operand:XF 0 "register_operand" "+f")
4593 (match_operand:XF 1 "register_operand" "+f"))
4598 if (STACK_TOP_P (operands[0]))
4603 [(set_attr "type" "fxch")
4604 (set_attr "mode" "XF")])
4607 ;; Zero extension instructions
4609 (define_insn_and_split "zero_extendditi2"
4610 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4611 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4614 "&& reload_completed"
4615 [(set (match_dup 3) (match_dup 1))
4616 (set (match_dup 4) (const_int 0))]
4617 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4619 (define_expand "zero_extendsidi2"
4620 [(set (match_operand:DI 0 "nonimmediate_operand")
4621 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4623 (define_insn "*zero_extendsidi2"
4624 [(set (match_operand:DI 0 "nonimmediate_operand"
4625 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4627 (match_operand:SI 1 "x86_64_zext_operand"
4628 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4631 switch (get_attr_type (insn))
4634 if (ix86_use_lea_for_mov (insn, operands))
4635 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4637 return "mov{l}\t{%1, %k0|%k0, %1}";
4643 return "movd\t{%1, %0|%0, %1}";
4646 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4648 if (EXT_REX_SSE_REG_P (operands[0])
4649 || EXT_REX_SSE_REG_P (operands[1]))
4650 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4652 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4655 if (GENERAL_REG_P (operands[0]))
4656 return "%vmovd\t{%1, %k0|%k0, %1}";
4658 return "%vmovd\t{%1, %0|%0, %1}";
4661 return "kmovd\t{%1, %k0|%k0, %1}";
4668 (cond [(eq_attr "alternative" "0,1,2")
4669 (const_string "nox64")
4670 (eq_attr "alternative" "3")
4671 (const_string "x64")
4672 (eq_attr "alternative" "7,8,9")
4673 (const_string "sse2")
4674 (eq_attr "alternative" "10")
4675 (const_string "sse4")
4676 (eq_attr "alternative" "11")
4677 (const_string "avx512f")
4678 (eq_attr "alternative" "12")
4679 (const_string "x64_avx512bw")
4680 (eq_attr "alternative" "13")
4681 (const_string "avx512bw_512")
4683 (const_string "*")))
4684 (set (attr "mmx_isa")
4685 (if_then_else (eq_attr "alternative" "5,6")
4686 (const_string "native")
4687 (const_string "*")))
4689 (cond [(eq_attr "alternative" "0,1,2,4")
4690 (const_string "multi")
4691 (eq_attr "alternative" "5,6")
4692 (const_string "mmxmov")
4693 (eq_attr "alternative" "7")
4694 (if_then_else (match_test "TARGET_64BIT")
4695 (const_string "ssemov")
4696 (const_string "multi"))
4697 (eq_attr "alternative" "8,9,10,11")
4698 (const_string "ssemov")
4699 (eq_attr "alternative" "12,13")
4700 (const_string "mskmov")
4702 (const_string "imovx")))
4703 (set (attr "prefix_extra")
4704 (if_then_else (eq_attr "alternative" "10,11")
4706 (const_string "*")))
4707 (set (attr "prefix")
4708 (if_then_else (eq_attr "type" "ssemov")
4709 (const_string "maybe_vex")
4710 (const_string "orig")))
4711 (set (attr "prefix_0f")
4712 (if_then_else (eq_attr "type" "imovx")
4714 (const_string "*")))
4716 (cond [(eq_attr "alternative" "5,6")
4718 (and (eq_attr "alternative" "7")
4719 (match_test "TARGET_64BIT"))
4721 (eq_attr "alternative" "8,10,11")
4724 (const_string "SI")))
4725 (set (attr "preferred_for_speed")
4726 (cond [(eq_attr "alternative" "7")
4727 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4728 (eq_attr "alternative" "5,8")
4729 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4731 (symbol_ref "true")))])
4734 [(set (match_operand:DI 0 "memory_operand")
4735 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4737 [(set (match_dup 4) (const_int 0))]
4738 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4741 [(set (match_operand:DI 0 "general_reg_operand")
4742 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4743 "!TARGET_64BIT && reload_completed
4744 && REGNO (operands[0]) == REGNO (operands[1])"
4745 [(set (match_dup 4) (const_int 0))]
4746 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4749 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4750 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4751 "!TARGET_64BIT && reload_completed
4752 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4753 [(set (match_dup 3) (match_dup 1))
4754 (set (match_dup 4) (const_int 0))]
4755 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4757 (define_mode_attr kmov_isa
4758 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4760 (define_insn "zero_extend<mode>di2"
4761 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4763 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4766 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4767 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4768 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4769 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4770 (set_attr "type" "imovx,mskmov,mskmov")
4771 (set_attr "mode" "SI,<MODE>,<MODE>")])
4773 (define_expand "zero_extend<mode>si2"
4774 [(set (match_operand:SI 0 "register_operand")
4775 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4778 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4780 operands[1] = force_reg (<MODE>mode, operands[1]);
4781 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4786 (define_insn_and_split "zero_extend<mode>si2_and"
4787 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4789 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4793 "&& reload_completed"
4794 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4795 (clobber (reg:CC FLAGS_REG))])]
4797 if (!REG_P (operands[1])
4798 || REGNO (operands[0]) != REGNO (operands[1]))
4800 ix86_expand_clear (operands[0]);
4802 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4803 emit_insn (gen_rtx_SET
4804 (gen_rtx_STRICT_LOW_PART
4805 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4810 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4812 [(set_attr "type" "alu1")
4813 (set_attr "mode" "SI")])
4815 (define_insn "*zero_extend<mode>si2"
4816 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4818 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4819 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4821 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4822 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4823 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4824 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4825 (set_attr "type" "imovx,mskmov,mskmov")
4826 (set_attr "mode" "SI,<MODE>,<MODE>")])
4828 (define_expand "zero_extendqihi2"
4829 [(set (match_operand:HI 0 "register_operand")
4830 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4833 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4835 operands[1] = force_reg (QImode, operands[1]);
4836 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4841 (define_insn_and_split "zero_extendqihi2_and"
4842 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4843 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4844 (clobber (reg:CC FLAGS_REG))]
4845 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4847 "&& reload_completed"
4848 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4849 (clobber (reg:CC FLAGS_REG))])]
4851 if (!REG_P (operands[1])
4852 || REGNO (operands[0]) != REGNO (operands[1]))
4854 ix86_expand_clear (operands[0]);
4856 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4857 emit_insn (gen_rtx_SET
4858 (gen_rtx_STRICT_LOW_PART
4859 (VOIDmode, gen_lowpart (QImode, operands[0])),
4864 operands[0] = gen_lowpart (SImode, operands[0]);
4866 [(set_attr "type" "alu1")
4867 (set_attr "mode" "SI")])
4869 ; zero extend to SImode to avoid partial register stalls
4870 (define_insn "*zero_extendqihi2"
4871 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4872 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4873 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4875 movz{bl|x}\t{%1, %k0|%k0, %1}
4876 kmovb\t{%1, %k0|%k0, %1}
4877 kmovb\t{%1, %0|%0, %1}"
4878 [(set_attr "isa" "*,avx512dq,avx512dq")
4879 (set_attr "type" "imovx,mskmov,mskmov")
4880 (set_attr "mode" "SI,QI,QI")])
4882 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4884 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4886 (clobber (reg:CC FLAGS_REG))])
4887 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4888 (match_operand:SWI12 2 "nonimmediate_operand"))]
4889 "REGNO (operands[0]) == REGNO (operands[1])
4890 && (<SWI48:MODE>mode != SImode
4891 || !TARGET_ZERO_EXTEND_WITH_AND
4892 || !optimize_function_for_speed_p (cfun))"
4893 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4895 ;; Likewise, but preserving FLAGS_REG.
4897 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4898 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4899 (match_operand:SWI12 2 "nonimmediate_operand"))]
4900 "REGNO (operands[0]) == REGNO (operands[1])
4901 && (<SWI48:MODE>mode != SImode
4902 || !TARGET_ZERO_EXTEND_WITH_AND
4903 || !optimize_function_for_speed_p (cfun))"
4904 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4906 ;; Sign extension instructions
4908 (define_expand "extendsidi2"
4909 [(set (match_operand:DI 0 "register_operand")
4910 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4915 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4920 (define_insn "*extendsidi2_rex64"
4921 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4922 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4926 movs{lq|x}\t{%1, %0|%0, %1}"
4927 [(set_attr "type" "imovx")
4928 (set_attr "mode" "DI")
4929 (set_attr "prefix_0f" "0")
4930 (set_attr "modrm" "0,1")])
4932 (define_insn "extendsidi2_1"
4933 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4934 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4935 (clobber (reg:CC FLAGS_REG))
4936 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4940 (define_insn "extendditi2"
4941 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4942 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4943 (clobber (reg:CC FLAGS_REG))
4944 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4948 ;; Split the memory case. If the source register doesn't die, it will stay
4949 ;; this way, if it does die, following peephole2s take care of it.
4951 [(set (match_operand:<DWI> 0 "memory_operand")
4952 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4953 (clobber (reg:CC FLAGS_REG))
4954 (clobber (match_operand:DWIH 2 "register_operand"))]
4958 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4962 emit_move_insn (operands[3], operands[1]);
4964 /* Generate a cltd if possible and doing so it profitable. */
4965 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4966 && REGNO (operands[1]) == AX_REG
4967 && REGNO (operands[2]) == DX_REG)
4969 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4973 emit_move_insn (operands[2], operands[1]);
4974 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4976 emit_move_insn (operands[4], operands[2]);
4980 ;; Peepholes for the case where the source register does die, after
4981 ;; being split with the above splitter.
4983 [(set (match_operand:DWIH 0 "memory_operand")
4984 (match_operand:DWIH 1 "general_reg_operand"))
4985 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4986 (parallel [(set (match_dup 2)
4987 (ashiftrt:DWIH (match_dup 2)
4988 (match_operand 4 "const_int_operand")))
4989 (clobber (reg:CC FLAGS_REG))])
4990 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4991 "REGNO (operands[1]) != REGNO (operands[2])
4992 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4993 && peep2_reg_dead_p (2, operands[1])
4994 && peep2_reg_dead_p (4, operands[2])
4995 && !reg_mentioned_p (operands[2], operands[3])"
4996 [(set (match_dup 0) (match_dup 1))
4997 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4998 (clobber (reg:CC FLAGS_REG))])
4999 (set (match_dup 3) (match_dup 1))])
5002 [(set (match_operand:DWIH 0 "memory_operand")
5003 (match_operand:DWIH 1 "general_reg_operand"))
5004 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
5005 (ashiftrt:DWIH (match_dup 1)
5006 (match_operand 4 "const_int_operand")))
5007 (clobber (reg:CC FLAGS_REG))])
5008 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
5009 "/* cltd is shorter than sarl $31, %eax */
5010 !optimize_function_for_size_p (cfun)
5011 && REGNO (operands[1]) == AX_REG
5012 && REGNO (operands[2]) == DX_REG
5013 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5014 && peep2_reg_dead_p (2, operands[1])
5015 && peep2_reg_dead_p (3, operands[2])
5016 && !reg_mentioned_p (operands[2], operands[3])"
5017 [(set (match_dup 0) (match_dup 1))
5018 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5019 (clobber (reg:CC FLAGS_REG))])
5020 (set (match_dup 3) (match_dup 1))])
5022 ;; Extend to register case. Optimize case where source and destination
5023 ;; registers match and cases where we can use cltd.
5025 [(set (match_operand:<DWI> 0 "register_operand")
5026 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
5027 (clobber (reg:CC FLAGS_REG))
5028 (clobber (match_scratch:DWIH 2))]
5032 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
5034 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
5036 if (REGNO (operands[3]) != REGNO (operands[1]))
5037 emit_move_insn (operands[3], operands[1]);
5039 rtx src = operands[1];
5040 if (REGNO (operands[3]) == AX_REG)
5043 /* Generate a cltd if possible and doing so it profitable. */
5044 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5045 && REGNO (src) == AX_REG
5046 && REGNO (operands[4]) == DX_REG)
5048 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
5052 if (REGNO (operands[4]) != REGNO (operands[1]))
5053 emit_move_insn (operands[4], operands[1]);
5055 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5059 (define_insn "extend<mode>di2"
5060 [(set (match_operand:DI 0 "register_operand" "=r")
5062 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5064 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5065 [(set_attr "type" "imovx")
5066 (set_attr "mode" "DI")])
5068 (define_insn "extendhisi2"
5069 [(set (match_operand:SI 0 "register_operand" "=*a,r")
5070 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5073 switch (get_attr_prefix_0f (insn))
5076 return "{cwtl|cwde}";
5078 return "movs{wl|x}\t{%1, %0|%0, %1}";
5081 [(set_attr "type" "imovx")
5082 (set_attr "mode" "SI")
5083 (set (attr "prefix_0f")
5084 ;; movsx is short decodable while cwtl is vector decoded.
5085 (if_then_else (and (eq_attr "cpu" "!k6")
5086 (eq_attr "alternative" "0"))
5088 (const_string "1")))
5089 (set (attr "znver1_decode")
5090 (if_then_else (eq_attr "prefix_0f" "0")
5091 (const_string "double")
5092 (const_string "direct")))
5094 (if_then_else (eq_attr "prefix_0f" "0")
5096 (const_string "1")))])
5098 (define_insn "*extendhisi2_zext"
5099 [(set (match_operand:DI 0 "register_operand" "=*a,r")
5102 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5105 switch (get_attr_prefix_0f (insn))
5108 return "{cwtl|cwde}";
5110 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5113 [(set_attr "type" "imovx")
5114 (set_attr "mode" "SI")
5115 (set (attr "prefix_0f")
5116 ;; movsx is short decodable while cwtl is vector decoded.
5117 (if_then_else (and (eq_attr "cpu" "!k6")
5118 (eq_attr "alternative" "0"))
5120 (const_string "1")))
5122 (if_then_else (eq_attr "prefix_0f" "0")
5124 (const_string "1")))])
5126 (define_insn "extendqisi2"
5127 [(set (match_operand:SI 0 "register_operand" "=r")
5128 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5130 "movs{bl|x}\t{%1, %0|%0, %1}"
5131 [(set_attr "type" "imovx")
5132 (set_attr "mode" "SI")])
5134 (define_insn "*extendqisi2_zext"
5135 [(set (match_operand:DI 0 "register_operand" "=r")
5137 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5139 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5140 [(set_attr "type" "imovx")
5141 (set_attr "mode" "SI")])
5143 (define_insn "extendqihi2"
5144 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5145 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5148 switch (get_attr_prefix_0f (insn))
5151 return "{cbtw|cbw}";
5153 return "movs{bw|x}\t{%1, %0|%0, %1}";
5156 [(set_attr "type" "imovx")
5157 (set_attr "mode" "HI")
5158 (set (attr "prefix_0f")
5159 ;; movsx is short decodable while cwtl is vector decoded.
5160 (if_then_else (and (eq_attr "cpu" "!k6")
5161 (eq_attr "alternative" "0"))
5163 (const_string "1")))
5165 (if_then_else (eq_attr "prefix_0f" "0")
5167 (const_string "1")))])
5169 (define_insn "*extendqi<SWI24:mode>_ext_1"
5170 [(set (match_operand:SWI24 0 "register_operand" "=R")
5173 (match_operator:SWI248 2 "extract_operator"
5174 [(match_operand 1 "int248_register_operand" "Q")
5176 (const_int 8)]) 0)))]
5178 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5179 [(set_attr "type" "imovx")
5180 (set_attr "mode" "<SWI24:MODE>")])
5182 ;; Conversions between float and double.
5184 ;; These are all no-ops in the model used for the 80387.
5185 ;; So just emit moves.
5187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5189 [(set (match_operand:DF 0 "push_operand")
5190 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5192 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5193 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5196 [(set (match_operand:XF 0 "push_operand")
5197 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5199 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5200 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5201 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5203 (define_expand "extendsfdf2"
5204 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5205 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5206 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5208 /* ??? Needed for compress_float_constant since all fp constants
5209 are TARGET_LEGITIMATE_CONSTANT_P. */
5210 if (CONST_DOUBLE_P (operands[1]))
5212 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5213 && standard_80387_constant_p (operands[1]) > 0)
5215 operands[1] = simplify_const_unary_operation
5216 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5217 emit_move_insn_1 (operands[0], operands[1]);
5220 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5224 (define_insn "*extendsfdf2"
5225 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5227 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5228 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5230 switch (which_alternative)
5234 return output_387_reg_move (insn, operands);
5237 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5239 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5245 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5246 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5247 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5248 (set_attr "mode" "SF,XF,DF,DF")
5249 (set (attr "enabled")
5251 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5253 (eq_attr "alternative" "0,1")
5254 (symbol_ref "TARGET_MIX_SSE_I387")
5255 (symbol_ref "true"))
5257 (eq_attr "alternative" "0,1")
5259 (symbol_ref "false"))))])
5261 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5263 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5265 We do the conversion post reload to avoid producing of 128bit spills
5266 that might lead to ICE on 32bit target. The sequence unlikely combine
5269 [(set (match_operand:DF 0 "sse_reg_operand")
5271 (match_operand:SF 1 "nonimmediate_operand")))]
5272 "TARGET_USE_VECTOR_FP_CONVERTS
5273 && optimize_insn_for_speed_p ()
5275 && (!EXT_REX_SSE_REG_P (operands[0])
5276 || TARGET_AVX512VL || TARGET_EVEX512)"
5281 (parallel [(const_int 0) (const_int 1)]))))]
5283 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5284 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5285 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5286 Try to avoid move when unpacking can be done in source. */
5287 if (REG_P (operands[1]))
5289 /* If it is unsafe to overwrite upper half of source, we need
5290 to move to destination and unpack there. */
5291 if (REGNO (operands[0]) != REGNO (operands[1])
5292 || (EXT_REX_SSE_REG_P (operands[1])
5293 && !TARGET_AVX512VL))
5295 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5296 emit_move_insn (tmp, operands[1]);
5299 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5300 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5301 =v, v, then vbroadcastss will be only needed for AVX512F without
5303 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5304 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5308 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5309 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5313 emit_insn (gen_vec_setv4sf_0 (operands[3],
5314 CONST0_RTX (V4SFmode), operands[1]));
5317 ;; It's more profitable to split and then extend in the same register.
5319 [(set (match_operand:DF 0 "sse_reg_operand")
5321 (match_operand:SF 1 "memory_operand")))]
5322 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5323 && optimize_insn_for_speed_p ()"
5324 [(set (match_dup 2) (match_dup 1))
5325 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5326 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5328 ;; Break partial SSE register dependency stall. This splitter should split
5329 ;; late in the pass sequence (after register rename pass), so allocated
5330 ;; registers won't change anymore
5333 [(set (match_operand:DF 0 "sse_reg_operand")
5335 (match_operand:SF 1 "nonimmediate_operand")))]
5337 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5338 && epilogue_completed
5339 && optimize_function_for_speed_p (cfun)
5340 && (!REG_P (operands[1])
5341 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5342 && (!EXT_REX_SSE_REG_P (operands[0])
5343 || TARGET_AVX512VL)"
5352 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5353 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5356 (define_expand "extendhfsf2"
5357 [(set (match_operand:SF 0 "register_operand")
5359 (match_operand:HF 1 "nonimmediate_operand")))]
5360 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5362 if (!TARGET_AVX512FP16)
5364 rtx res = gen_reg_rtx (V4SFmode);
5365 rtx tmp = gen_reg_rtx (V8HFmode);
5366 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5368 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5369 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5370 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5375 (define_expand "extendhfdf2"
5376 [(set (match_operand:DF 0 "register_operand")
5378 (match_operand:HF 1 "nonimmediate_operand")))]
5379 "TARGET_AVX512FP16")
5381 (define_insn "*extendhf<mode>2"
5382 [(set (match_operand:MODEF 0 "register_operand" "=v")
5384 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5386 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5387 [(set_attr "type" "ssecvt")
5388 (set_attr "prefix" "evex")
5389 (set_attr "mode" "<MODE>")])
5391 (define_expand "extendbfsf2"
5392 [(set (match_operand:SF 0 "register_operand")
5394 [(match_operand:BF 1 "register_operand")]
5396 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5398 ;; Don't use float_extend since psrlld doesn't raise
5399 ;; exceptions and turn a sNaN into a qNaN.
5400 (define_insn "extendbfsf2_1"
5401 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5403 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5407 pslld\t{$16, %0|%0, 16}
5408 vpslld\t{$16, %1, %0|%0, %1, 16}
5409 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5410 [(set_attr "isa" "noavx,avx,*")
5411 (set_attr "type" "sseishft1")
5412 (set_attr "length_immediate" "1")
5413 (set_attr "prefix_data16" "1,*,*")
5414 (set_attr "prefix" "orig,maybe_evex,evex")
5415 (set_attr "mode" "TI,TI,XI")
5416 (set_attr "memory" "none")
5417 (set (attr "enabled")
5418 (if_then_else (eq_attr "alternative" "2")
5419 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5420 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5421 (const_string "*")))])
5423 (define_expand "extend<mode>xf2"
5424 [(set (match_operand:XF 0 "nonimmediate_operand")
5425 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5428 /* ??? Needed for compress_float_constant since all fp constants
5429 are TARGET_LEGITIMATE_CONSTANT_P. */
5430 if (CONST_DOUBLE_P (operands[1]))
5432 if (standard_80387_constant_p (operands[1]) > 0)
5434 operands[1] = simplify_const_unary_operation
5435 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5436 emit_move_insn_1 (operands[0], operands[1]);
5439 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5443 (define_insn "*extend<mode>xf2_i387"
5444 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5446 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5448 "* return output_387_reg_move (insn, operands);"
5449 [(set_attr "type" "fmov")
5450 (set_attr "mode" "<MODE>,XF")])
5452 ;; %%% This seems like bad news.
5453 ;; This cannot output into an f-reg because there is no way to be sure
5454 ;; of truncating in that case. Otherwise this is just like a simple move
5455 ;; insn. So we pretend we can output to a reg in order to get better
5456 ;; register preferencing, but we really use a stack slot.
5458 ;; Conversion from DFmode to SFmode.
5460 (define_insn "truncdfsf2"
5461 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5463 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5464 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5466 switch (which_alternative)
5470 return output_387_reg_move (insn, operands);
5473 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5475 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5481 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5482 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5483 (set_attr "mode" "SF")
5484 (set (attr "enabled")
5486 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5487 (cond [(eq_attr "alternative" "0")
5488 (symbol_ref "TARGET_MIX_SSE_I387")
5489 (eq_attr "alternative" "1")
5490 (symbol_ref "TARGET_MIX_SSE_I387
5491 && flag_unsafe_math_optimizations")
5493 (symbol_ref "true"))
5494 (cond [(eq_attr "alternative" "0")
5496 (eq_attr "alternative" "1")
5497 (symbol_ref "flag_unsafe_math_optimizations")
5499 (symbol_ref "false"))))])
5501 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5503 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5505 We do the conversion post reload to avoid producing of 128bit spills
5506 that might lead to ICE on 32bit target. The sequence unlikely combine
5509 [(set (match_operand:SF 0 "sse_reg_operand")
5511 (match_operand:DF 1 "nonimmediate_operand")))]
5512 "TARGET_USE_VECTOR_FP_CONVERTS
5513 && optimize_insn_for_speed_p ()
5515 && (!EXT_REX_SSE_REG_P (operands[0])
5516 || TARGET_AVX512VL)"
5519 (float_truncate:V2SF
5523 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5524 operands[3] = CONST0_RTX (V2SFmode);
5525 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5526 /* Use movsd for loading from memory, unpcklpd for registers.
5527 Try to avoid move when unpacking can be done in source, or SSE3
5528 movddup is available. */
5529 if (REG_P (operands[1]))
5531 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5532 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5534 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5535 emit_move_insn (tmp, operands[1]);
5538 else if (!TARGET_SSE3)
5539 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5540 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5543 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5544 CONST0_RTX (DFmode)));
5547 ;; It's more profitable to split and then truncate in the same register.
5549 [(set (match_operand:SF 0 "sse_reg_operand")
5551 (match_operand:DF 1 "memory_operand")))]
5552 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5553 && optimize_insn_for_speed_p ()"
5554 [(set (match_dup 2) (match_dup 1))
5555 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5556 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5558 ;; Break partial SSE register dependency stall. This splitter should split
5559 ;; late in the pass sequence (after register rename pass), so allocated
5560 ;; registers won't change anymore
5563 [(set (match_operand:SF 0 "sse_reg_operand")
5565 (match_operand:DF 1 "nonimmediate_operand")))]
5567 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5568 && epilogue_completed
5569 && optimize_function_for_speed_p (cfun)
5570 && (!REG_P (operands[1])
5571 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5572 && (!EXT_REX_SSE_REG_P (operands[0])
5573 || TARGET_AVX512VL)"
5582 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5583 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5586 ;; Conversion from XFmode to {SF,DF}mode
5588 (define_insn "truncxf<mode>2"
5589 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5590 (float_truncate:MODEF
5591 (match_operand:XF 1 "register_operand" "f,f")))]
5593 "* return output_387_reg_move (insn, operands);"
5594 [(set_attr "type" "fmov")
5595 (set_attr "mode" "<MODE>")
5596 (set (attr "enabled")
5597 (cond [(eq_attr "alternative" "1")
5598 (symbol_ref "flag_unsafe_math_optimizations")
5600 (symbol_ref "true")))])
5602 ;; Conversion from {SF,DF}mode to HFmode.
5604 (define_expand "truncsfhf2"
5605 [(set (match_operand:HF 0 "register_operand")
5607 (match_operand:SF 1 "nonimmediate_operand")))]
5608 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5610 if (!TARGET_AVX512FP16)
5612 rtx res = gen_reg_rtx (V8HFmode);
5613 rtx tmp = gen_reg_rtx (V4SFmode);
5614 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5616 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5617 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5618 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5623 (define_expand "truncdfhf2"
5624 [(set (match_operand:HF 0 "register_operand")
5626 (match_operand:DF 1 "nonimmediate_operand")))]
5627 "TARGET_AVX512FP16")
5629 (define_insn "*trunc<mode>hf2"
5630 [(set (match_operand:HF 0 "register_operand" "=v")
5632 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5634 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5635 [(set_attr "type" "ssecvt")
5636 (set_attr "prefix" "evex")
5637 (set_attr "mode" "HF")])
5639 (define_insn "truncsfbf2"
5640 [(set (match_operand:BF 0 "register_operand" "=x, v")
5642 (match_operand:SF 1 "register_operand" "x,v")))]
5643 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5644 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5646 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5647 vcvtneps2bf16\t{%1, %0|%0, %1}"
5648 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5649 (set_attr "prefix" "vex,evex")])
5651 ;; Signed conversion to DImode.
5653 (define_expand "fix_truncxfdi2"
5654 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5655 (fix:DI (match_operand:XF 1 "register_operand")))
5656 (clobber (reg:CC FLAGS_REG))])]
5661 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5666 (define_expand "fix_trunc<mode>di2"
5667 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5668 (fix:DI (match_operand:MODEF 1 "register_operand")))
5669 (clobber (reg:CC FLAGS_REG))])]
5670 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5673 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5675 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5678 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5680 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5681 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5682 if (out != operands[0])
5683 emit_move_insn (operands[0], out);
5688 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5689 [(set (match_operand:SWI48 0 "register_operand" "=r")
5691 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5693 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5694 [(set_attr "type" "sseicvt")
5695 (set_attr "prefix" "evex")
5696 (set_attr "mode" "<MODE>")])
5698 ;; Signed conversion to SImode.
5700 (define_expand "fix_truncxfsi2"
5701 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5702 (fix:SI (match_operand:XF 1 "register_operand")))
5703 (clobber (reg:CC FLAGS_REG))])]
5708 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5713 (define_expand "fix_trunc<mode>si2"
5714 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5715 (fix:SI (match_operand:MODEF 1 "register_operand")))
5716 (clobber (reg:CC FLAGS_REG))])]
5717 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5720 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5722 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5725 if (SSE_FLOAT_MODE_P (<MODE>mode))
5727 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5728 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5729 if (out != operands[0])
5730 emit_move_insn (operands[0], out);
5735 ;; Signed conversion to HImode.
5737 (define_expand "fix_trunc<mode>hi2"
5738 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5739 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5740 (clobber (reg:CC FLAGS_REG))])]
5742 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5746 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5751 ;; Unsigned conversion to DImode
5753 (define_insn "fixuns_trunc<mode>di2"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5756 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5757 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5758 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5759 [(set_attr "type" "sseicvt")
5760 (set_attr "prefix" "evex")
5761 (set_attr "mode" "DI")])
5763 ;; Unsigned conversion to SImode.
5765 (define_expand "fixuns_trunc<mode>si2"
5767 [(set (match_operand:SI 0 "register_operand")
5769 (match_operand:MODEF 1 "nonimmediate_operand")))
5771 (clobber (scratch:<ssevecmode>))
5772 (clobber (scratch:<ssevecmode>))])]
5773 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5775 machine_mode mode = <MODE>mode;
5776 machine_mode vecmode = <ssevecmode>mode;
5777 REAL_VALUE_TYPE TWO31r;
5782 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5786 if (optimize_insn_for_size_p ())
5789 real_ldexp (&TWO31r, &dconst1, 31);
5790 two31 = const_double_from_real_value (TWO31r, mode);
5791 two31 = ix86_build_const_vector (vecmode, true, two31);
5792 operands[2] = force_reg (vecmode, two31);
5795 (define_insn "fixuns_trunc<mode>si2_avx512f"
5796 [(set (match_operand:SI 0 "register_operand" "=r")
5798 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5799 "TARGET_AVX512F && TARGET_SSE_MATH"
5800 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5801 [(set_attr "type" "sseicvt")
5802 (set_attr "prefix" "evex")
5803 (set_attr "mode" "SI")])
5805 (define_insn "*fixuns_trunchfsi2zext"
5806 [(set (match_operand:DI 0 "register_operand" "=r")
5809 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5810 "TARGET_64BIT && TARGET_AVX512FP16"
5811 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5812 [(set_attr "type" "sseicvt")
5813 (set_attr "prefix" "evex")
5814 (set_attr "mode" "SI")])
5816 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5820 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5821 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5822 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5823 [(set_attr "type" "sseicvt")
5824 (set_attr "prefix" "evex")
5825 (set_attr "mode" "SI")])
5827 (define_insn_and_split "*fixuns_trunc<mode>_1"
5828 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5830 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5831 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5832 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5833 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5834 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5835 && optimize_function_for_speed_p (cfun)"
5837 "&& reload_completed"
5840 ix86_split_convert_uns_si_sse (operands);
5844 ;; Unsigned conversion to HImode.
5845 ;; Without these patterns, we'll try the unsigned SI conversion which
5846 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5848 (define_expand "fixuns_trunchfhi2"
5850 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5851 (set (match_operand:HI 0 "nonimmediate_operand")
5852 (subreg:HI (match_dup 2) 0))]
5854 "operands[2] = gen_reg_rtx (SImode);")
5856 (define_expand "fixuns_trunc<mode>hi2"
5858 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5859 (set (match_operand:HI 0 "nonimmediate_operand")
5860 (subreg:HI (match_dup 2) 0))]
5861 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5862 "operands[2] = gen_reg_rtx (SImode);")
5864 ;; When SSE is available, it is always faster to use it!
5865 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5866 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5867 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5868 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5869 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5870 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5871 [(set_attr "type" "sseicvt")
5872 (set_attr "prefix" "maybe_vex")
5873 (set (attr "prefix_rex")
5875 (match_test "<SWI48:MODE>mode == DImode")
5877 (const_string "*")))
5878 (set_attr "mode" "<MODEF:MODE>")
5879 (set_attr "athlon_decode" "double,vector")
5880 (set_attr "amdfam10_decode" "double,double")
5881 (set_attr "bdver1_decode" "double,double")])
5883 ;; Avoid vector decoded forms of the instruction.
5885 [(match_scratch:MODEF 2 "x")
5886 (set (match_operand:SWI48 0 "register_operand")
5887 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5888 "TARGET_AVOID_VECTOR_DECODE
5889 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5890 && optimize_insn_for_speed_p ()"
5891 [(set (match_dup 2) (match_dup 1))
5892 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5894 (define_insn "fix_trunc<mode>_i387_fisttp"
5895 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5896 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5897 (clobber (match_scratch:XF 2 "=&f"))]
5898 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5900 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5901 && (TARGET_64BIT || <MODE>mode != DImode))
5902 && TARGET_SSE_MATH)"
5903 "* return output_fix_trunc (insn, operands, true);"
5904 [(set_attr "type" "fisttp")
5905 (set_attr "mode" "<MODE>")])
5907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5911 ;; function in i386.cc.
5912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5913 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5914 (fix:SWI248x (match_operand 1 "register_operand")))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5918 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5919 && (TARGET_64BIT || <MODE>mode != DImode))
5920 && ix86_pre_reload_split ()"
5925 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5927 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5928 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5930 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5931 operands[2], operands[3]));
5934 [(set_attr "type" "fistp")
5935 (set_attr "i387_cw" "trunc")
5936 (set_attr "mode" "<MODE>")])
5938 (define_insn "fix_truncdi_i387"
5939 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5940 (fix:DI (match_operand 1 "register_operand" "f")))
5941 (use (match_operand:HI 2 "memory_operand" "m"))
5942 (use (match_operand:HI 3 "memory_operand" "m"))
5943 (clobber (match_scratch:XF 4 "=&f"))]
5944 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5946 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5947 "* return output_fix_trunc (insn, operands, false);"
5948 [(set_attr "type" "fistp")
5949 (set_attr "i387_cw" "trunc")
5950 (set_attr "mode" "DI")])
5952 (define_insn "fix_trunc<mode>_i387"
5953 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5954 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5955 (use (match_operand:HI 2 "memory_operand" "m"))
5956 (use (match_operand:HI 3 "memory_operand" "m"))]
5957 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5959 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5960 "* return output_fix_trunc (insn, operands, false);"
5961 [(set_attr "type" "fistp")
5962 (set_attr "i387_cw" "trunc")
5963 (set_attr "mode" "<MODE>")])
5965 (define_insn "x86_fnstcw_1"
5966 [(set (match_operand:HI 0 "memory_operand" "=m")
5967 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5970 [(set (attr "length")
5971 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5972 (set_attr "mode" "HI")
5973 (set_attr "unit" "i387")
5974 (set_attr "bdver1_decode" "vector")])
5976 ;; Conversion between fixed point and floating point.
5978 ;; Even though we only accept memory inputs, the backend _really_
5979 ;; wants to be able to do this between registers. Thankfully, LRA
5980 ;; will fix this up for us during register allocation.
5982 (define_insn "floathi<mode>2"
5983 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5984 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5987 || TARGET_MIX_SSE_I387)"
5989 [(set_attr "type" "fmov")
5990 (set_attr "mode" "<MODE>")
5991 (set_attr "znver1_decode" "double")
5992 (set_attr "fp_int_src" "true")])
5994 (define_insn "float<SWI48x:mode>xf2"
5995 [(set (match_operand:XF 0 "register_operand" "=f")
5996 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5999 [(set_attr "type" "fmov")
6000 (set_attr "mode" "XF")
6001 (set_attr "znver1_decode" "double")
6002 (set_attr "fp_int_src" "true")])
6004 (define_expand "float<SWI48x:mode><MODEF:mode>2"
6005 [(set (match_operand:MODEF 0 "register_operand")
6006 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
6007 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
6008 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
6009 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
6011 (define_insn "*float<SWI48:mode><MODEF:mode>2"
6012 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
6014 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
6015 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
6016 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
6019 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
6020 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
6021 [(set_attr "type" "fmov,sseicvt,sseicvt")
6022 (set_attr "avx_partial_xmm_update" "false,true,true")
6023 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
6024 (set_attr "mode" "<MODEF:MODE>")
6025 (set (attr "prefix_rex")
6027 (and (eq_attr "prefix" "maybe_vex")
6028 (match_test "<SWI48:MODE>mode == DImode"))
6030 (const_string "*")))
6031 (set_attr "unit" "i387,*,*")
6032 (set_attr "athlon_decode" "*,double,direct")
6033 (set_attr "amdfam10_decode" "*,vector,double")
6034 (set_attr "bdver1_decode" "*,double,direct")
6035 (set_attr "znver1_decode" "double,*,*")
6036 (set_attr "fp_int_src" "true")
6037 (set (attr "enabled")
6039 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
6041 (eq_attr "alternative" "0")
6042 (symbol_ref "TARGET_MIX_SSE_I387
6043 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
6045 (symbol_ref "true"))
6047 (eq_attr "alternative" "0")
6049 (symbol_ref "false"))))
6050 (set (attr "preferred_for_speed")
6051 (cond [(eq_attr "alternative" "1")
6052 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
6053 (symbol_ref "true")))])
6055 (define_insn "float<floatunssuffix><mode>hf2"
6056 [(set (match_operand:HF 0 "register_operand" "=v")
6058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6060 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6061 [(set_attr "type" "sseicvt")
6062 (set_attr "prefix" "evex")
6063 (set_attr "mode" "HF")])
6065 (define_insn "*floatdi<MODEF:mode>2_i387"
6066 [(set (match_operand:MODEF 0 "register_operand" "=f")
6067 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6069 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6071 [(set_attr "type" "fmov")
6072 (set_attr "mode" "<MODEF:MODE>")
6073 (set_attr "znver1_decode" "double")
6074 (set_attr "fp_int_src" "true")])
6076 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6077 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6078 ;; alternative in sse2_loadld.
6080 [(set (match_operand:MODEF 0 "sse_reg_operand")
6081 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6083 && TARGET_USE_VECTOR_CONVERTS
6084 && optimize_function_for_speed_p (cfun)
6086 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6087 && (!EXT_REX_SSE_REG_P (operands[0])
6088 || TARGET_AVX512VL)"
6091 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6092 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6094 emit_insn (gen_sse2_loadld (operands[4],
6095 CONST0_RTX (V4SImode), operands[1]));
6097 if (<ssevecmode>mode == V4SFmode)
6098 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6100 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6104 ;; Avoid store forwarding (partial memory) stall penalty
6105 ;; by passing DImode value through XMM registers. */
6108 [(set (match_operand:X87MODEF 0 "register_operand")
6110 (match_operand:DI 1 "register_operand")))]
6111 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6112 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6113 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6114 && can_create_pseudo_p ()"
6117 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6118 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6122 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6123 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6125 (match_operand:DI 1 "register_operand" "r,r")))
6126 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6127 (clobber (match_scratch:V4SI 3 "=x,x"))
6128 (clobber (match_scratch:V4SI 4 "=X,x"))]
6129 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6130 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6131 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6133 "&& reload_completed"
6134 [(set (match_dup 2) (match_dup 3))
6135 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6137 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6138 Assemble the 64-bit DImode value in an xmm register. */
6139 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6140 gen_lowpart (SImode, operands[1])));
6142 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6143 gen_highpart (SImode, operands[1]),
6147 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6148 gen_highpart (SImode, operands[1])));
6149 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6152 operands[3] = gen_lowpart (DImode, operands[3]);
6154 [(set_attr "isa" "sse4,*")
6155 (set_attr "type" "multi")
6156 (set_attr "mode" "<X87MODEF:MODE>")
6157 (set_attr "unit" "i387")
6158 (set_attr "fp_int_src" "true")])
6160 ;; Break partial SSE register dependency stall. This splitter should split
6161 ;; late in the pass sequence (after register rename pass), so allocated
6162 ;; registers won't change anymore
6165 [(set (match_operand:MODEF 0 "sse_reg_operand")
6166 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6168 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6169 && epilogue_completed
6170 && optimize_function_for_speed_p (cfun)
6171 && (!EXT_REX_SSE_REG_P (operands[0])
6172 || TARGET_AVX512VL)"
6174 (vec_merge:<MODEF:ssevecmode>
6175 (vec_duplicate:<MODEF:ssevecmode>
6181 const machine_mode vmode = <MODEF:ssevecmode>mode;
6183 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6184 emit_move_insn (operands[0], CONST0_RTX (vmode));
6187 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6188 [(set (match_operand:MODEF 0 "register_operand")
6189 (unsigned_float:MODEF
6190 (match_operand:SWI12 1 "nonimmediate_operand")))]
6192 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6194 operands[1] = convert_to_mode (SImode, operands[1], 1);
6195 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6199 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6200 [(set (match_operand:MODEF 0 "register_operand" "=v")
6201 (unsigned_float:MODEF
6202 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6203 "TARGET_AVX512F && TARGET_SSE_MATH"
6204 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6205 [(set_attr "type" "sseicvt")
6206 (set_attr "avx_partial_xmm_update" "true")
6207 (set_attr "prefix" "evex")
6208 (set_attr "mode" "<MODEF:MODE>")])
6210 ;; Avoid store forwarding (partial memory) stall penalty by extending
6211 ;; SImode value to DImode through XMM register instead of pushing two
6212 ;; SImode values to stack. Also note that fild loads from memory only.
6214 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6215 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6216 (unsigned_float:X87MODEF
6217 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6218 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6219 (clobber (match_scratch:DI 3 "=x"))]
6221 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6222 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6224 "&& reload_completed"
6225 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6226 (set (match_dup 2) (match_dup 3))
6228 (float:X87MODEF (match_dup 2)))]
6230 [(set_attr "type" "multi")
6231 (set_attr "mode" "<MODE>")])
6233 (define_expand "floatunssi<mode>2"
6234 [(set (match_operand:X87MODEF 0 "register_operand")
6235 (unsigned_float:X87MODEF
6236 (match_operand:SI 1 "nonimmediate_operand")))]
6238 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6239 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6240 || ((!TARGET_64BIT || TARGET_AVX512F)
6241 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6243 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6245 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6246 (operands[0], operands[1],
6247 assign_386_stack_local (DImode, SLOT_TEMP)));
6250 if (!TARGET_AVX512F)
6252 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6257 (define_expand "floatunsdisf2"
6258 [(set (match_operand:SF 0 "register_operand")
6260 (match_operand:DI 1 "nonimmediate_operand")))]
6261 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6263 if (!TARGET_AVX512F)
6265 x86_emit_floatuns (operands);
6270 (define_expand "floatunsdidf2"
6271 [(set (match_operand:DF 0 "register_operand")
6273 (match_operand:DI 1 "nonimmediate_operand")))]
6274 "((TARGET_64BIT && TARGET_AVX512F)
6275 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6276 && TARGET_SSE2 && TARGET_SSE_MATH"
6280 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6283 if (!TARGET_AVX512F)
6285 x86_emit_floatuns (operands);
6290 ;; Load effective address instructions
6292 (define_insn "*lea<mode>"
6293 [(set (match_operand:SWI48 0 "register_operand" "=r")
6294 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6295 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6297 if (SImode_address_operand (operands[1], VOIDmode))
6299 gcc_assert (TARGET_64BIT);
6300 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6303 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6305 [(set_attr "type" "lea")
6308 (match_operand 1 "SImode_address_operand")
6310 (const_string "<MODE>")))])
6313 [(set (match_operand:SWI48 0 "register_operand")
6314 (match_operand:SWI48 1 "address_no_seg_operand"))]
6315 "ix86_hardreg_mov_ok (operands[0], operands[1])
6316 && peep2_regno_dead_p (0, FLAGS_REG)
6317 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6320 machine_mode mode = <MODE>mode;
6322 /* Emit all operations in SImode for zero-extended addresses. */
6323 if (SImode_address_operand (operands[1], VOIDmode))
6326 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6328 /* Zero-extend return register to DImode for zero-extended addresses. */
6329 if (mode != <MODE>mode)
6330 emit_insn (gen_zero_extendsidi2 (operands[0],
6331 gen_lowpart (mode, operands[0])));
6336 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6337 ;; peephole2 optimized back into a lea. Split that into the shift during
6338 ;; the following split pass.
6340 [(set (match_operand:SWI48 0 "general_reg_operand")
6341 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6342 (clobber (reg:CC FLAGS_REG))]
6344 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6345 (clobber (reg:CC FLAGS_REG))])]
6346 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6350 (define_expand "add<mode>3"
6351 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6352 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6353 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6355 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6357 (define_insn_and_split "*add<dwi>3_doubleword"
6358 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6360 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6361 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6362 (clobber (reg:CC FLAGS_REG))]
6363 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6365 "&& reload_completed"
6366 [(parallel [(set (reg:CCC FLAGS_REG)
6368 (plus:DWIH (match_dup 1) (match_dup 2))
6371 (plus:DWIH (match_dup 1) (match_dup 2)))])
6372 (parallel [(set (match_dup 3)
6375 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6378 (clobber (reg:CC FLAGS_REG))])]
6380 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6381 if (operands[2] == const0_rtx)
6383 if (operands[5] != const0_rtx)
6384 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6385 else if (!rtx_equal_p (operands[3], operands[4]))
6386 emit_move_insn (operands[3], operands[4]);
6388 emit_note (NOTE_INSN_DELETED);
6393 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6394 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6397 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6398 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6402 "&& reload_completed"
6403 [(parallel [(set (reg:CCC FLAGS_REG)
6405 (plus:DWIH (match_dup 1) (match_dup 2))
6408 (plus:DWIH (match_dup 1) (match_dup 2)))])
6409 (parallel [(set (match_dup 3)
6412 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6415 (clobber (reg:CC FLAGS_REG))])]
6416 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6418 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6419 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6424 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6425 (match_operand:QI 3 "const_int_operand"))
6427 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6428 (match_operand:<DWI> 1 "register_operand" "0")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6432 "&& reload_completed"
6433 [(parallel [(set (reg:CCC FLAGS_REG)
6435 (plus:DWIH (match_dup 1) (match_dup 4))
6438 (plus:DWIH (match_dup 1) (match_dup 4)))])
6439 (parallel [(set (match_dup 5)
6442 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6445 (clobber (reg:CC FLAGS_REG))])]
6446 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6448 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6449 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6454 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6455 (match_operand:QI 3 "const_int_operand"))
6457 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6459 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6463 "&& reload_completed"
6464 [(set (match_dup 0) (match_dup 4))
6465 (set (match_dup 5) (match_dup 2))
6466 (parallel [(set (reg:CCC FLAGS_REG)
6468 (plus:DWIH (match_dup 0) (match_dup 1))
6471 (plus:DWIH (match_dup 0) (match_dup 1)))])
6472 (parallel [(set (match_dup 5)
6475 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6478 (clobber (reg:CC FLAGS_REG))])]
6479 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6481 (define_insn "*add<mode>_1"
6482 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6484 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6485 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6489 switch (get_attr_type (insn))
6495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6496 if (operands[2] == const1_rtx)
6497 return "inc{<imodesuffix>}\t%0";
6500 gcc_assert (operands[2] == constm1_rtx);
6501 return "dec{<imodesuffix>}\t%0";
6505 /* For most processors, ADD is faster than LEA. This alternative
6506 was added to use ADD as much as possible. */
6507 if (which_alternative == 2)
6508 std::swap (operands[1], operands[2]);
6510 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6511 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6512 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6514 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6518 (cond [(eq_attr "alternative" "3")
6519 (const_string "lea")
6520 (match_operand:SWI48 2 "incdec_operand")
6521 (const_string "incdec")
6523 (const_string "alu")))
6524 (set (attr "length_immediate")
6526 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6528 (const_string "*")))
6529 (set_attr "mode" "<MODE>")])
6531 ;; It may seem that nonimmediate operand is proper one for operand 1.
6532 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6533 ;; we take care in ix86_binary_operator_ok to not allow two memory
6534 ;; operands so proper swapping will be done in reload. This allow
6535 ;; patterns constructed from addsi_1 to match.
6537 (define_insn "addsi_1_zext"
6538 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6540 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6541 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6542 (clobber (reg:CC FLAGS_REG))]
6543 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6545 switch (get_attr_type (insn))
6551 if (operands[2] == const1_rtx)
6552 return "inc{l}\t%k0";
6555 gcc_assert (operands[2] == constm1_rtx);
6556 return "dec{l}\t%k0";
6560 /* For most processors, ADD is faster than LEA. This alternative
6561 was added to use ADD as much as possible. */
6562 if (which_alternative == 1)
6563 std::swap (operands[1], operands[2]);
6565 if (x86_maybe_negate_const_int (&operands[2], SImode))
6566 return "sub{l}\t{%2, %k0|%k0, %2}";
6568 return "add{l}\t{%2, %k0|%k0, %2}";
6572 (cond [(eq_attr "alternative" "2")
6573 (const_string "lea")
6574 (match_operand:SI 2 "incdec_operand")
6575 (const_string "incdec")
6577 (const_string "alu")))
6578 (set (attr "length_immediate")
6580 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6582 (const_string "*")))
6583 (set_attr "mode" "SI")])
6585 (define_insn "*addhi_1"
6586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6587 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6588 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6589 (clobber (reg:CC FLAGS_REG))]
6590 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6592 switch (get_attr_type (insn))
6598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6599 if (operands[2] == const1_rtx)
6600 return "inc{w}\t%0";
6603 gcc_assert (operands[2] == constm1_rtx);
6604 return "dec{w}\t%0";
6608 /* For most processors, ADD is faster than LEA. This alternative
6609 was added to use ADD as much as possible. */
6610 if (which_alternative == 2)
6611 std::swap (operands[1], operands[2]);
6613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614 if (x86_maybe_negate_const_int (&operands[2], HImode))
6615 return "sub{w}\t{%2, %0|%0, %2}";
6617 return "add{w}\t{%2, %0|%0, %2}";
6621 (cond [(eq_attr "alternative" "3")
6622 (const_string "lea")
6623 (match_operand:HI 2 "incdec_operand")
6624 (const_string "incdec")
6626 (const_string "alu")))
6627 (set (attr "length_immediate")
6629 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6631 (const_string "*")))
6632 (set_attr "mode" "HI,HI,HI,SI")])
6634 (define_insn "*addqi_1"
6635 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6637 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6641 bool widen = (get_attr_mode (insn) != MODE_QI);
6643 switch (get_attr_type (insn))
6649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6650 if (operands[2] == const1_rtx)
6651 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6654 gcc_assert (operands[2] == constm1_rtx);
6655 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6659 /* For most processors, ADD is faster than LEA. These alternatives
6660 were added to use ADD as much as possible. */
6661 if (which_alternative == 2 || which_alternative == 4)
6662 std::swap (operands[1], operands[2]);
6664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6665 if (x86_maybe_negate_const_int (&operands[2], QImode))
6668 return "sub{l}\t{%2, %k0|%k0, %2}";
6670 return "sub{b}\t{%2, %0|%0, %2}";
6673 return "add{l}\t{%k2, %k0|%k0, %k2}";
6675 return "add{b}\t{%2, %0|%0, %2}";
6679 (cond [(eq_attr "alternative" "5")
6680 (const_string "lea")
6681 (match_operand:QI 2 "incdec_operand")
6682 (const_string "incdec")
6684 (const_string "alu")))
6685 (set (attr "length_immediate")
6687 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6689 (const_string "*")))
6690 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6691 ;; Potential partial reg stall on alternatives 3 and 4.
6692 (set (attr "preferred_for_speed")
6693 (cond [(eq_attr "alternative" "3,4")
6694 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6695 (symbol_ref "true")))])
6697 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6698 (define_insn_and_split "*add<mode>_1_slp"
6699 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6700 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6701 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6705 if (which_alternative)
6708 switch (get_attr_type (insn))
6711 if (operands[2] == const1_rtx)
6712 return "inc{<imodesuffix>}\t%0";
6715 gcc_assert (operands[2] == constm1_rtx);
6716 return "dec{<imodesuffix>}\t%0";
6720 if (x86_maybe_negate_const_int (&operands[2], QImode))
6721 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6723 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6726 "&& reload_completed"
6727 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6729 [(set (strict_low_part (match_dup 0))
6730 (plus:SWI12 (match_dup 0) (match_dup 2)))
6731 (clobber (reg:CC FLAGS_REG))])]
6734 (if_then_else (match_operand:QI 2 "incdec_operand")
6735 (const_string "incdec")
6736 (const_string "alu")))
6737 (set_attr "mode" "<MODE>")])
6739 ;; Split non destructive adds if we cannot use lea.
6741 [(set (match_operand:SWI48 0 "register_operand")
6742 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6743 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6746 [(set (match_dup 0) (match_dup 1))
6747 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6748 (clobber (reg:CC FLAGS_REG))])])
6750 ;; Split non destructive adds if we cannot use lea.
6752 [(set (match_operand:DI 0 "register_operand")
6754 (plus:SI (match_operand:SI 1 "register_operand")
6755 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6756 (clobber (reg:CC FLAGS_REG))]
6758 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6759 [(set (match_dup 3) (match_dup 1))
6760 (parallel [(set (match_dup 0)
6761 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6762 (clobber (reg:CC FLAGS_REG))])]
6763 "operands[3] = gen_lowpart (SImode, operands[0]);")
6765 ;; Convert add to the lea pattern to avoid flags dependency.
6767 [(set (match_operand:SWI 0 "register_operand")
6768 (plus:SWI (match_operand:SWI 1 "register_operand")
6769 (match_operand:SWI 2 "<nonmemory_operand>")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6773 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6775 if (<MODE>mode != <LEAMODE>mode)
6777 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6778 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6779 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6783 ;; Convert add to the lea pattern to avoid flags dependency.
6785 [(set (match_operand:DI 0 "register_operand")
6787 (plus:SI (match_operand:SI 1 "register_operand")
6788 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6789 (clobber (reg:CC FLAGS_REG))]
6790 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6792 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6794 (define_insn "*add<mode>_2"
6795 [(set (reg FLAGS_REG)
6798 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6799 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6801 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6802 (plus:SWI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCGOCmode)
6804 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6806 switch (get_attr_type (insn))
6809 if (operands[2] == const1_rtx)
6810 return "inc{<imodesuffix>}\t%0";
6813 gcc_assert (operands[2] == constm1_rtx);
6814 return "dec{<imodesuffix>}\t%0";
6818 if (which_alternative == 2)
6819 std::swap (operands[1], operands[2]);
6821 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6822 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6823 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6825 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6829 (if_then_else (match_operand:SWI 2 "incdec_operand")
6830 (const_string "incdec")
6831 (const_string "alu")))
6832 (set (attr "length_immediate")
6834 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6836 (const_string "*")))
6837 (set_attr "mode" "<MODE>")])
6839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6840 (define_insn "*addsi_2_zext"
6841 [(set (reg FLAGS_REG)
6843 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6844 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6846 (set (match_operand:DI 0 "register_operand" "=r,r")
6847 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6848 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6849 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6851 switch (get_attr_type (insn))
6854 if (operands[2] == const1_rtx)
6855 return "inc{l}\t%k0";
6858 gcc_assert (operands[2] == constm1_rtx);
6859 return "dec{l}\t%k0";
6863 if (which_alternative == 1)
6864 std::swap (operands[1], operands[2]);
6866 if (x86_maybe_negate_const_int (&operands[2], SImode))
6867 return "sub{l}\t{%2, %k0|%k0, %2}";
6869 return "add{l}\t{%2, %k0|%k0, %2}";
6873 (if_then_else (match_operand:SI 2 "incdec_operand")
6874 (const_string "incdec")
6875 (const_string "alu")))
6876 (set (attr "length_immediate")
6878 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6880 (const_string "*")))
6881 (set_attr "mode" "SI")])
6883 (define_insn "*add<mode>_3"
6884 [(set (reg FLAGS_REG)
6886 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6887 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6888 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6889 "ix86_match_ccmode (insn, CCZmode)
6890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6892 switch (get_attr_type (insn))
6895 if (operands[2] == const1_rtx)
6896 return "inc{<imodesuffix>}\t%0";
6899 gcc_assert (operands[2] == constm1_rtx);
6900 return "dec{<imodesuffix>}\t%0";
6904 if (which_alternative == 1)
6905 std::swap (operands[1], operands[2]);
6907 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6908 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6909 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6911 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6915 (if_then_else (match_operand:SWI 2 "incdec_operand")
6916 (const_string "incdec")
6917 (const_string "alu")))
6918 (set (attr "length_immediate")
6920 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6922 (const_string "*")))
6923 (set_attr "mode" "<MODE>")])
6925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6926 (define_insn "*addsi_3_zext"
6927 [(set (reg FLAGS_REG)
6929 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6930 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6931 (set (match_operand:DI 0 "register_operand" "=r,r")
6932 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6933 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6934 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6936 switch (get_attr_type (insn))
6939 if (operands[2] == const1_rtx)
6940 return "inc{l}\t%k0";
6943 gcc_assert (operands[2] == constm1_rtx);
6944 return "dec{l}\t%k0";
6948 if (which_alternative == 1)
6949 std::swap (operands[1], operands[2]);
6951 if (x86_maybe_negate_const_int (&operands[2], SImode))
6952 return "sub{l}\t{%2, %k0|%k0, %2}";
6954 return "add{l}\t{%2, %k0|%k0, %2}";
6958 (if_then_else (match_operand:SI 2 "incdec_operand")
6959 (const_string "incdec")
6960 (const_string "alu")))
6961 (set (attr "length_immediate")
6963 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6965 (const_string "*")))
6966 (set_attr "mode" "SI")])
6968 ; For comparisons against 1, -1 and 128, we may generate better code
6969 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6970 ; is matched then. We can't accept general immediate, because for
6971 ; case of overflows, the result is messed up.
6972 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6973 ; only for comparisons not depending on it.
6975 (define_insn "*adddi_4"
6976 [(set (reg FLAGS_REG)
6978 (match_operand:DI 1 "nonimmediate_operand" "0")
6979 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6980 (clobber (match_scratch:DI 0 "=r"))]
6982 && ix86_match_ccmode (insn, CCGCmode)"
6984 switch (get_attr_type (insn))
6987 if (operands[2] == constm1_rtx)
6988 return "inc{q}\t%0";
6991 gcc_assert (operands[2] == const1_rtx);
6992 return "dec{q}\t%0";
6996 if (x86_maybe_negate_const_int (&operands[2], DImode))
6997 return "add{q}\t{%2, %0|%0, %2}";
6999 return "sub{q}\t{%2, %0|%0, %2}";
7003 (if_then_else (match_operand:DI 2 "incdec_operand")
7004 (const_string "incdec")
7005 (const_string "alu")))
7006 (set (attr "length_immediate")
7008 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7010 (const_string "*")))
7011 (set_attr "mode" "DI")])
7013 ; For comparisons against 1, -1 and 128, we may generate better code
7014 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7015 ; is matched then. We can't accept general immediate, because for
7016 ; case of overflows, the result is messed up.
7017 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7018 ; only for comparisons not depending on it.
7020 (define_insn "*add<mode>_4"
7021 [(set (reg FLAGS_REG)
7023 (match_operand:SWI124 1 "nonimmediate_operand" "0")
7024 (match_operand:SWI124 2 "const_int_operand")))
7025 (clobber (match_scratch:SWI124 0 "=<r>"))]
7026 "ix86_match_ccmode (insn, CCGCmode)"
7028 switch (get_attr_type (insn))
7031 if (operands[2] == constm1_rtx)
7032 return "inc{<imodesuffix>}\t%0";
7035 gcc_assert (operands[2] == const1_rtx);
7036 return "dec{<imodesuffix>}\t%0";
7040 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7041 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7047 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7048 (const_string "incdec")
7049 (const_string "alu")))
7050 (set (attr "length_immediate")
7052 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7054 (const_string "*")))
7055 (set_attr "mode" "<MODE>")])
7057 (define_insn "*add<mode>_5"
7058 [(set (reg FLAGS_REG)
7061 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
7062 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
7064 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
7065 "ix86_match_ccmode (insn, CCGOCmode)
7066 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068 switch (get_attr_type (insn))
7071 if (operands[2] == const1_rtx)
7072 return "inc{<imodesuffix>}\t%0";
7075 gcc_assert (operands[2] == constm1_rtx);
7076 return "dec{<imodesuffix>}\t%0";
7080 if (which_alternative == 1)
7081 std::swap (operands[1], operands[2]);
7083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7084 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7085 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7087 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7091 (if_then_else (match_operand:SWI 2 "incdec_operand")
7092 (const_string "incdec")
7093 (const_string "alu")))
7094 (set (attr "length_immediate")
7096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7098 (const_string "*")))
7099 (set_attr "mode" "<MODE>")])
7101 (define_insn "*addqi_ext<mode>_0"
7102 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7105 (match_operator:SWI248 3 "extract_operator"
7106 [(match_operand 2 "int248_register_operand" "Q,Q")
7109 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
7110 (clobber (reg:CC FLAGS_REG))]
7112 "add{b}\t{%h2, %0|%0, %h2}"
7113 [(set_attr "isa" "*,nox64")
7114 (set_attr "type" "alu")
7115 (set_attr "mode" "QI")])
7117 (define_expand "addqi_ext_1"
7119 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7125 (zero_extract:HI (match_operand:HI 1 "register_operand")
7128 (match_operand:QI 2 "const_int_operand")) 0))
7129 (clobber (reg:CC FLAGS_REG))])])
7131 (define_insn "*addqi_ext<mode>_1"
7132 [(set (zero_extract:SWI248
7133 (match_operand 0 "int248_register_operand" "+Q,Q")
7139 (match_operator:SWI248 3 "extract_operator"
7140 [(match_operand 1 "int248_register_operand" "0,0")
7143 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7146 rtx_equal_p (operands[0], operands[1])"
7148 switch (get_attr_type (insn))
7151 if (operands[2] == const1_rtx)
7152 return "inc{b}\t%h0";
7155 gcc_assert (operands[2] == constm1_rtx);
7156 return "dec{b}\t%h0";
7160 return "add{b}\t{%2, %h0|%h0, %2}";
7163 [(set_attr "isa" "*,nox64")
7165 (if_then_else (match_operand:QI 2 "incdec_operand")
7166 (const_string "incdec")
7167 (const_string "alu")))
7168 (set_attr "mode" "QI")])
7170 (define_insn "*addqi_ext<mode>_2"
7171 [(set (zero_extract:SWI248
7172 (match_operand 0 "int248_register_operand" "+Q")
7178 (match_operator:SWI248 3 "extract_operator"
7179 [(match_operand 1 "int248_register_operand" "%0")
7183 (match_operator:SWI248 4 "extract_operator"
7184 [(match_operand 2 "int248_register_operand" "Q")
7186 (const_int 8)]) 0)) 0))
7187 (clobber (reg:CC FLAGS_REG))]
7188 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7189 rtx_equal_p (operands[0], operands[1])
7190 || rtx_equal_p (operands[0], operands[2])"
7191 "add{b}\t{%h2, %h0|%h0, %h2}"
7192 [(set_attr "type" "alu")
7193 (set_attr "mode" "QI")])
7195 ;; Like DWI, but use POImode instead of OImode.
7196 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7198 ;; Add with jump on overflow.
7199 (define_expand "addv<mode>4"
7200 [(parallel [(set (reg:CCO FLAGS_REG)
7204 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7207 (plus:SWIDWI (match_dup 1)
7208 (match_operand:SWIDWI 2
7209 "<general_hilo_operand>")))))
7210 (set (match_operand:SWIDWI 0 "register_operand")
7211 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7212 (set (pc) (if_then_else
7213 (eq (reg:CCO FLAGS_REG) (const_int 0))
7214 (label_ref (match_operand 3))
7218 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7219 if (CONST_SCALAR_INT_P (operands[2]))
7220 operands[4] = operands[2];
7222 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7225 (define_insn "*addv<mode>4"
7226 [(set (reg:CCO FLAGS_REG)
7229 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7231 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7233 (plus:SWI (match_dup 1) (match_dup 2)))))
7234 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7235 (plus:SWI (match_dup 1) (match_dup 2)))]
7236 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7237 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7238 [(set_attr "type" "alu")
7239 (set_attr "mode" "<MODE>")])
7241 (define_insn "addv<mode>4_1"
7242 [(set (reg:CCO FLAGS_REG)
7245 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7246 (match_operand:<DWI> 3 "const_int_operand"))
7250 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7251 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7252 (plus:SWI (match_dup 1) (match_dup 2)))]
7253 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7254 && CONST_INT_P (operands[2])
7255 && INTVAL (operands[2]) == INTVAL (operands[3])"
7256 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7257 [(set_attr "type" "alu")
7258 (set_attr "mode" "<MODE>")
7259 (set (attr "length_immediate")
7260 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7262 (match_test "<MODE_SIZE> == 8")
7264 (const_string "<MODE_SIZE>")))])
7266 ;; Quad word integer modes as mode attribute.
7267 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7269 (define_insn_and_split "*addv<dwi>4_doubleword"
7270 [(set (reg:CCO FLAGS_REG)
7274 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7276 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7278 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7279 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7280 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7281 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7283 "&& reload_completed"
7284 [(parallel [(set (reg:CCC FLAGS_REG)
7286 (plus:DWIH (match_dup 1) (match_dup 2))
7289 (plus:DWIH (match_dup 1) (match_dup 2)))])
7290 (parallel [(set (reg:CCO FLAGS_REG)
7294 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7295 (sign_extend:<DWI> (match_dup 4)))
7296 (sign_extend:<DWI> (match_dup 5)))
7300 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7306 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7310 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7313 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7314 [(set (reg:CCO FLAGS_REG)
7318 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7319 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7323 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7324 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7325 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7326 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7327 && CONST_SCALAR_INT_P (operands[2])
7328 && rtx_equal_p (operands[2], operands[3])"
7330 "&& reload_completed"
7331 [(parallel [(set (reg:CCC FLAGS_REG)
7333 (plus:DWIH (match_dup 1) (match_dup 2))
7336 (plus:DWIH (match_dup 1) (match_dup 2)))])
7337 (parallel [(set (reg:CCO FLAGS_REG)
7341 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7342 (sign_extend:<DWI> (match_dup 4)))
7347 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7353 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7357 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7358 if (operands[2] == const0_rtx)
7360 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7366 (define_insn "*addv<mode>4_overflow_1"
7367 [(set (reg:CCO FLAGS_REG)
7371 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7372 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7374 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7376 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7380 (match_operator:SWI 5 "ix86_carry_flag_operator"
7381 [(match_dup 3) (const_int 0)])
7384 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7387 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7390 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7391 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7392 [(set_attr "type" "alu")
7393 (set_attr "mode" "<MODE>")])
7395 (define_insn "*addv<mode>4_overflow_2"
7396 [(set (reg:CCO FLAGS_REG)
7400 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7401 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7403 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7404 (match_operand:<DWI> 6 "const_int_operand" "n"))
7408 (match_operator:SWI 5 "ix86_carry_flag_operator"
7409 [(match_dup 3) (const_int 0)])
7411 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7412 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7415 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7419 && CONST_INT_P (operands[2])
7420 && INTVAL (operands[2]) == INTVAL (operands[6])"
7421 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "<MODE>")
7424 (set (attr "length_immediate")
7425 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7427 (const_string "4")))])
7429 (define_expand "uaddv<mode>4"
7430 [(parallel [(set (reg:CCC FLAGS_REG)
7433 (match_operand:SWIDWI 1 "nonimmediate_operand")
7434 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7436 (set (match_operand:SWIDWI 0 "register_operand")
7437 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7438 (set (pc) (if_then_else
7439 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7440 (label_ref (match_operand 3))
7443 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7445 ;; The lea patterns for modes less than 32 bits need to be matched by
7446 ;; several insns converted to real lea by splitters.
7448 (define_insn_and_split "*lea<mode>_general_1"
7449 [(set (match_operand:SWI12 0 "register_operand" "=r")
7451 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7452 (match_operand:SWI12 2 "register_operand" "r"))
7453 (match_operand:SWI12 3 "immediate_operand" "i")))]
7454 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7456 "&& reload_completed"
7459 (plus:SI (match_dup 1) (match_dup 2))
7462 operands[0] = gen_lowpart (SImode, operands[0]);
7463 operands[1] = gen_lowpart (SImode, operands[1]);
7464 operands[2] = gen_lowpart (SImode, operands[2]);
7465 operands[3] = gen_lowpart (SImode, operands[3]);
7467 [(set_attr "type" "lea")
7468 (set_attr "mode" "SI")])
7470 (define_insn_and_split "*lea<mode>_general_2"
7471 [(set (match_operand:SWI12 0 "register_operand" "=r")
7473 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7474 (match_operand 2 "const248_operand" "n"))
7475 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7476 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7478 "&& reload_completed"
7481 (mult:SI (match_dup 1) (match_dup 2))
7484 operands[0] = gen_lowpart (SImode, operands[0]);
7485 operands[1] = gen_lowpart (SImode, operands[1]);
7486 operands[3] = gen_lowpart (SImode, operands[3]);
7488 [(set_attr "type" "lea")
7489 (set_attr "mode" "SI")])
7491 (define_insn_and_split "*lea<mode>_general_2b"
7492 [(set (match_operand:SWI12 0 "register_operand" "=r")
7494 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7495 (match_operand 2 "const123_operand" "n"))
7496 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7497 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7499 "&& reload_completed"
7502 (ashift:SI (match_dup 1) (match_dup 2))
7505 operands[0] = gen_lowpart (SImode, operands[0]);
7506 operands[1] = gen_lowpart (SImode, operands[1]);
7507 operands[3] = gen_lowpart (SImode, operands[3]);
7509 [(set_attr "type" "lea")
7510 (set_attr "mode" "SI")])
7512 (define_insn_and_split "*lea<mode>_general_3"
7513 [(set (match_operand:SWI12 0 "register_operand" "=r")
7516 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7517 (match_operand 2 "const248_operand" "n"))
7518 (match_operand:SWI12 3 "register_operand" "r"))
7519 (match_operand:SWI12 4 "immediate_operand" "i")))]
7520 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7522 "&& reload_completed"
7526 (mult:SI (match_dup 1) (match_dup 2))
7530 operands[0] = gen_lowpart (SImode, operands[0]);
7531 operands[1] = gen_lowpart (SImode, operands[1]);
7532 operands[3] = gen_lowpart (SImode, operands[3]);
7533 operands[4] = gen_lowpart (SImode, operands[4]);
7535 [(set_attr "type" "lea")
7536 (set_attr "mode" "SI")])
7538 (define_insn_and_split "*lea<mode>_general_3b"
7539 [(set (match_operand:SWI12 0 "register_operand" "=r")
7542 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7543 (match_operand 2 "const123_operand" "n"))
7544 (match_operand:SWI12 3 "register_operand" "r"))
7545 (match_operand:SWI12 4 "immediate_operand" "i")))]
7546 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7548 "&& reload_completed"
7552 (ashift:SI (match_dup 1) (match_dup 2))
7556 operands[0] = gen_lowpart (SImode, operands[0]);
7557 operands[1] = gen_lowpart (SImode, operands[1]);
7558 operands[3] = gen_lowpart (SImode, operands[3]);
7559 operands[4] = gen_lowpart (SImode, operands[4]);
7561 [(set_attr "type" "lea")
7562 (set_attr "mode" "SI")])
7564 (define_insn_and_split "*lea<mode>_general_4"
7565 [(set (match_operand:SWI12 0 "register_operand" "=r")
7568 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7569 (match_operand 2 "const_0_to_3_operand"))
7570 (match_operand 3 "const_int_operand")))]
7571 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7572 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7573 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7575 "&& reload_completed"
7578 (mult:SI (match_dup 1) (match_dup 2))
7581 operands[0] = gen_lowpart (SImode, operands[0]);
7582 operands[1] = gen_lowpart (SImode, operands[1]);
7583 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7585 [(set_attr "type" "lea")
7586 (set_attr "mode" "SI")])
7588 (define_insn_and_split "*lea<mode>_general_4"
7589 [(set (match_operand:SWI48 0 "register_operand" "=r")
7592 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7593 (match_operand 2 "const_0_to_3_operand"))
7594 (match_operand 3 "const_int_operand")))]
7595 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7596 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7598 "&& reload_completed"
7601 (mult:SWI48 (match_dup 1) (match_dup 2))
7603 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7604 [(set_attr "type" "lea")
7605 (set_attr "mode" "<MODE>")])
7607 ;; Subtract instructions
7609 (define_expand "sub<mode>3"
7610 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7611 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7612 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7614 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7616 (define_insn_and_split "*sub<dwi>3_doubleword"
7617 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7619 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7620 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7624 "&& reload_completed"
7625 [(parallel [(set (reg:CC FLAGS_REG)
7626 (compare:CC (match_dup 1) (match_dup 2)))
7628 (minus:DWIH (match_dup 1) (match_dup 2)))])
7629 (parallel [(set (match_dup 3)
7633 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7635 (clobber (reg:CC FLAGS_REG))])]
7637 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7638 if (operands[2] == const0_rtx)
7640 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7645 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7646 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7648 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7650 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7654 "&& reload_completed"
7655 [(parallel [(set (reg:CC FLAGS_REG)
7656 (compare:CC (match_dup 1) (match_dup 2)))
7658 (minus:DWIH (match_dup 1) (match_dup 2)))])
7659 (parallel [(set (match_dup 3)
7663 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7665 (clobber (reg:CC FLAGS_REG))])]
7666 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7668 (define_insn "*sub<mode>_1"
7669 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7671 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7672 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7673 (clobber (reg:CC FLAGS_REG))]
7674 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7675 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7676 [(set_attr "type" "alu")
7677 (set_attr "mode" "<MODE>")])
7679 (define_insn "*subsi_1_zext"
7680 [(set (match_operand:DI 0 "register_operand" "=r")
7682 (minus:SI (match_operand:SI 1 "register_operand" "0")
7683 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7684 (clobber (reg:CC FLAGS_REG))]
7685 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7686 "sub{l}\t{%2, %k0|%k0, %2}"
7687 [(set_attr "type" "alu")
7688 (set_attr "mode" "SI")])
7690 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7691 (define_insn_and_split "*sub<mode>_1_slp"
7692 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7693 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7694 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7695 (clobber (reg:CC FLAGS_REG))]
7696 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7698 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7700 "&& reload_completed"
7701 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7703 [(set (strict_low_part (match_dup 0))
7704 (minus:SWI12 (match_dup 0) (match_dup 2)))
7705 (clobber (reg:CC FLAGS_REG))])]
7707 [(set_attr "type" "alu")
7708 (set_attr "mode" "<MODE>")])
7710 (define_insn "*sub<mode>_2"
7711 [(set (reg FLAGS_REG)
7714 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7715 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7717 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7718 (minus:SWI (match_dup 1) (match_dup 2)))]
7719 "ix86_match_ccmode (insn, CCGOCmode)
7720 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7721 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7722 [(set_attr "type" "alu")
7723 (set_attr "mode" "<MODE>")])
7725 (define_insn "*subsi_2_zext"
7726 [(set (reg FLAGS_REG)
7728 (minus:SI (match_operand:SI 1 "register_operand" "0")
7729 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7731 (set (match_operand:DI 0 "register_operand" "=r")
7733 (minus:SI (match_dup 1)
7735 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7736 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7737 "sub{l}\t{%2, %k0|%k0, %2}"
7738 [(set_attr "type" "alu")
7739 (set_attr "mode" "SI")])
7741 (define_insn "*subqi_ext<mode>_0"
7742 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7744 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7746 (match_operator:SWI248 3 "extract_operator"
7747 [(match_operand 2 "int248_register_operand" "Q,Q")
7749 (const_int 8)]) 0)))
7750 (clobber (reg:CC FLAGS_REG))]
7752 "sub{b}\t{%h2, %0|%0, %h2}"
7753 [(set_attr "isa" "*,nox64")
7754 (set_attr "type" "alu")
7755 (set_attr "mode" "QI")])
7757 (define_insn "*subqi_ext<mode>_2"
7758 [(set (zero_extract:SWI248
7759 (match_operand 0 "int248_register_operand" "+Q")
7765 (match_operator:SWI248 3 "extract_operator"
7766 [(match_operand 1 "int248_register_operand" "0")
7770 (match_operator:SWI248 4 "extract_operator"
7771 [(match_operand 2 "int248_register_operand" "Q")
7773 (const_int 8)]) 0)) 0))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7776 rtx_equal_p (operands[0], operands[1])"
7777 "sub{b}\t{%h2, %h0|%h0, %h2}"
7778 [(set_attr "type" "alu")
7779 (set_attr "mode" "QI")])
7781 ;; Subtract with jump on overflow.
7782 (define_expand "subv<mode>4"
7783 [(parallel [(set (reg:CCO FLAGS_REG)
7787 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7790 (minus:SWIDWI (match_dup 1)
7791 (match_operand:SWIDWI 2
7792 "<general_hilo_operand>")))))
7793 (set (match_operand:SWIDWI 0 "register_operand")
7794 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7795 (set (pc) (if_then_else
7796 (eq (reg:CCO FLAGS_REG) (const_int 0))
7797 (label_ref (match_operand 3))
7801 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7802 if (CONST_SCALAR_INT_P (operands[2]))
7803 operands[4] = operands[2];
7805 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7808 (define_insn "*subv<mode>4"
7809 [(set (reg:CCO FLAGS_REG)
7810 (eq:CCO (minus:<DWI>
7812 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7814 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7816 (minus:SWI (match_dup 1) (match_dup 2)))))
7817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7818 (minus:SWI (match_dup 1) (match_dup 2)))]
7819 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7820 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7821 [(set_attr "type" "alu")
7822 (set_attr "mode" "<MODE>")])
7824 (define_insn "subv<mode>4_1"
7825 [(set (reg:CCO FLAGS_REG)
7826 (eq:CCO (minus:<DWI>
7828 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7829 (match_operand:<DWI> 3 "const_int_operand"))
7833 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7834 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7835 (minus:SWI (match_dup 1) (match_dup 2)))]
7836 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7837 && CONST_INT_P (operands[2])
7838 && INTVAL (operands[2]) == INTVAL (operands[3])"
7839 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7840 [(set_attr "type" "alu")
7841 (set_attr "mode" "<MODE>")
7842 (set (attr "length_immediate")
7843 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7845 (match_test "<MODE_SIZE> == 8")
7847 (const_string "<MODE_SIZE>")))])
7849 (define_insn_and_split "*subv<dwi>4_doubleword"
7850 [(set (reg:CCO FLAGS_REG)
7854 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7856 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7858 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7859 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7860 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7861 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7863 "&& reload_completed"
7864 [(parallel [(set (reg:CC FLAGS_REG)
7865 (compare:CC (match_dup 1) (match_dup 2)))
7867 (minus:DWIH (match_dup 1) (match_dup 2)))])
7868 (parallel [(set (reg:CCO FLAGS_REG)
7872 (sign_extend:<DWI> (match_dup 4))
7873 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7874 (sign_extend:<DWI> (match_dup 5)))
7879 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7885 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7888 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7891 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7892 [(set (reg:CCO FLAGS_REG)
7896 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7897 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7901 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7902 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7903 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7904 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7905 && CONST_SCALAR_INT_P (operands[2])
7906 && rtx_equal_p (operands[2], operands[3])"
7908 "&& reload_completed"
7909 [(parallel [(set (reg:CC FLAGS_REG)
7910 (compare:CC (match_dup 1) (match_dup 2)))
7912 (minus:DWIH (match_dup 1) (match_dup 2)))])
7913 (parallel [(set (reg:CCO FLAGS_REG)
7917 (sign_extend:<DWI> (match_dup 4))
7918 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7924 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7930 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7933 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7934 if (operands[2] == const0_rtx)
7936 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7942 (define_insn "*subv<mode>4_overflow_1"
7943 [(set (reg:CCO FLAGS_REG)
7948 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7949 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7950 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7952 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7957 (match_operator:SWI 5 "ix86_carry_flag_operator"
7958 [(match_dup 3) (const_int 0)]))
7960 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7964 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7966 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7967 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7968 [(set_attr "type" "alu")
7969 (set_attr "mode" "<MODE>")])
7971 (define_insn "*subv<mode>4_overflow_2"
7972 [(set (reg:CCO FLAGS_REG)
7977 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7978 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7979 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7980 (match_operand:<DWI> 6 "const_int_operand" "n"))
7985 (match_operator:SWI 5 "ix86_carry_flag_operator"
7986 [(match_dup 3) (const_int 0)]))
7987 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7988 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7992 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7994 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7995 && CONST_INT_P (operands[2])
7996 && INTVAL (operands[2]) == INTVAL (operands[6])"
7997 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7998 [(set_attr "type" "alu")
7999 (set_attr "mode" "<MODE>")
8000 (set (attr "length_immediate")
8001 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8003 (const_string "4")))])
8005 (define_expand "usubv<mode>4"
8006 [(parallel [(set (reg:CC FLAGS_REG)
8008 (match_operand:SWI 1 "nonimmediate_operand")
8009 (match_operand:SWI 2 "<general_operand>")))
8010 (set (match_operand:SWI 0 "register_operand")
8011 (minus:SWI (match_dup 1) (match_dup 2)))])
8012 (set (pc) (if_then_else
8013 (ltu (reg:CC FLAGS_REG) (const_int 0))
8014 (label_ref (match_operand 3))
8017 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8019 (define_insn "*sub<mode>_3"
8020 [(set (reg FLAGS_REG)
8021 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8022 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8023 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8024 (minus:SWI (match_dup 1) (match_dup 2)))]
8025 "ix86_match_ccmode (insn, CCmode)
8026 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8027 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "mode" "<MODE>")])
8033 [(set (reg:CC FLAGS_REG)
8034 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8035 (match_operand:SWI 1 "general_gr_operand")))
8037 (minus:SWI (match_dup 0) (match_dup 1)))])]
8038 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8039 [(set (reg:CC FLAGS_REG)
8040 (compare:CC (match_dup 0) (match_dup 1)))])
8043 [(set (match_operand:SWI 0 "general_reg_operand")
8044 (match_operand:SWI 1 "memory_operand"))
8045 (parallel [(set (reg:CC FLAGS_REG)
8046 (compare:CC (match_dup 0)
8047 (match_operand:SWI 2 "memory_operand")))
8049 (minus:SWI (match_dup 0) (match_dup 2)))])
8050 (set (match_dup 1) (match_dup 0))]
8051 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8052 && peep2_reg_dead_p (3, operands[0])
8053 && !reg_overlap_mentioned_p (operands[0], operands[1])
8054 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8055 [(set (match_dup 0) (match_dup 2))
8056 (parallel [(set (reg:CC FLAGS_REG)
8057 (compare:CC (match_dup 1) (match_dup 0)))
8059 (minus:SWI (match_dup 1) (match_dup 0)))])])
8061 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8062 ;; subl $1, %eax; jnc .Lxx;
8065 [(set (match_operand:SWI 0 "general_reg_operand")
8066 (plus:SWI (match_dup 0) (const_int -1)))
8067 (clobber (reg FLAGS_REG))])
8068 (set (reg:CCZ FLAGS_REG)
8069 (compare:CCZ (match_dup 0) (const_int -1)))
8071 (if_then_else (match_operator 1 "bt_comparison_operator"
8072 [(reg:CCZ FLAGS_REG) (const_int 0)])
8075 "peep2_regno_dead_p (3, FLAGS_REG)"
8077 [(set (reg:CC FLAGS_REG)
8078 (compare:CC (match_dup 0) (const_int 1)))
8080 (minus:SWI (match_dup 0) (const_int 1)))])
8082 (if_then_else (match_dup 3)
8086 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8087 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8088 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8091 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8092 (define_insn_and_split "*dec_cmov<mode>"
8093 [(set (match_operand:SWI248 0 "register_operand" "=r")
8094 (if_then_else:SWI248
8095 (match_operator 1 "bt_comparison_operator"
8096 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8097 (plus:SWI248 (match_dup 2) (const_int -1))
8098 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8099 (clobber (reg:CC FLAGS_REG))]
8102 "&& reload_completed"
8103 [(parallel [(set (reg:CC FLAGS_REG)
8104 (compare:CC (match_dup 2) (const_int 1)))
8105 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8107 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8109 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8110 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8111 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8114 (define_insn "*subsi_3_zext"
8115 [(set (reg FLAGS_REG)
8116 (compare (match_operand:SI 1 "register_operand" "0")
8117 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8118 (set (match_operand:DI 0 "register_operand" "=r")
8120 (minus:SI (match_dup 1)
8122 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8123 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8124 "sub{l}\t{%2, %1|%1, %2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "mode" "SI")])
8128 ;; Add with carry and subtract with borrow
8130 (define_insn "@add<mode>3_carry"
8131 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8134 (match_operator:SWI 4 "ix86_carry_flag_operator"
8135 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8136 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8137 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8140 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "use_carry" "1")
8143 (set_attr "pent_pair" "pu")
8144 (set_attr "mode" "<MODE>")])
8147 [(set (match_operand:SWI 0 "general_reg_operand")
8148 (match_operand:SWI 1 "memory_operand"))
8149 (parallel [(set (match_dup 0)
8152 (match_operator:SWI 4 "ix86_carry_flag_operator"
8153 [(match_operand 3 "flags_reg_operand")
8156 (match_operand:SWI 2 "memory_operand")))
8157 (clobber (reg:CC FLAGS_REG))])
8158 (set (match_dup 1) (match_dup 0))]
8159 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8160 && peep2_reg_dead_p (3, operands[0])
8161 && !reg_overlap_mentioned_p (operands[0], operands[1])
8162 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8163 [(set (match_dup 0) (match_dup 2))
8164 (parallel [(set (match_dup 1)
8165 (plus:SWI (plus:SWI (match_op_dup 4
8166 [(match_dup 3) (const_int 0)])
8169 (clobber (reg:CC FLAGS_REG))])])
8172 [(set (match_operand:SWI 0 "general_reg_operand")
8173 (match_operand:SWI 1 "memory_operand"))
8174 (parallel [(set (match_dup 0)
8177 (match_operator:SWI 4 "ix86_carry_flag_operator"
8178 [(match_operand 3 "flags_reg_operand")
8181 (match_operand:SWI 2 "memory_operand")))
8182 (clobber (reg:CC FLAGS_REG))])
8183 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8184 (set (match_dup 1) (match_dup 5))]
8185 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8186 && peep2_reg_dead_p (3, operands[0])
8187 && peep2_reg_dead_p (4, operands[5])
8188 && !reg_overlap_mentioned_p (operands[0], operands[1])
8189 && !reg_overlap_mentioned_p (operands[0], operands[2])
8190 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8191 [(set (match_dup 0) (match_dup 2))
8192 (parallel [(set (match_dup 1)
8193 (plus:SWI (plus:SWI (match_op_dup 4
8194 [(match_dup 3) (const_int 0)])
8197 (clobber (reg:CC FLAGS_REG))])])
8199 (define_insn "*add<mode>3_carry_0"
8200 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8202 (match_operator:SWI 2 "ix86_carry_flag_operator"
8203 [(reg FLAGS_REG) (const_int 0)])
8204 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8207 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8208 [(set_attr "type" "alu")
8209 (set_attr "use_carry" "1")
8210 (set_attr "pent_pair" "pu")
8211 (set_attr "mode" "<MODE>")])
8213 (define_insn "*add<mode>3_carry_0r"
8214 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8216 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8217 [(reg FLAGS_REG) (const_int 0)])
8218 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8219 (clobber (reg:CC FLAGS_REG))]
8220 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8221 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8222 [(set_attr "type" "alu")
8223 (set_attr "use_carry" "1")
8224 (set_attr "pent_pair" "pu")
8225 (set_attr "mode" "<MODE>")])
8227 (define_insn "*addsi3_carry_zext"
8228 [(set (match_operand:DI 0 "register_operand" "=r")
8231 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8232 [(reg FLAGS_REG) (const_int 0)])
8233 (match_operand:SI 1 "register_operand" "%0"))
8234 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8237 "adc{l}\t{%2, %k0|%k0, %2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "use_carry" "1")
8240 (set_attr "pent_pair" "pu")
8241 (set_attr "mode" "SI")])
8243 (define_insn "*addsi3_carry_zext_0"
8244 [(set (match_operand:DI 0 "register_operand" "=r")
8246 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8247 [(reg FLAGS_REG) (const_int 0)])
8248 (match_operand:SI 1 "register_operand" "0"))))
8249 (clobber (reg:CC FLAGS_REG))]
8251 "adc{l}\t{$0, %k0|%k0, 0}"
8252 [(set_attr "type" "alu")
8253 (set_attr "use_carry" "1")
8254 (set_attr "pent_pair" "pu")
8255 (set_attr "mode" "SI")])
8257 (define_insn "*addsi3_carry_zext_0r"
8258 [(set (match_operand:DI 0 "register_operand" "=r")
8260 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8261 [(reg FLAGS_REG) (const_int 0)])
8262 (match_operand:SI 1 "register_operand" "0"))))
8263 (clobber (reg:CC FLAGS_REG))]
8265 "sbb{l}\t{$-1, %k0|%k0, -1}"
8266 [(set_attr "type" "alu")
8267 (set_attr "use_carry" "1")
8268 (set_attr "pent_pair" "pu")
8269 (set_attr "mode" "SI")])
8271 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8273 (define_insn "addcarry<mode>"
8274 [(set (reg:CCC FLAGS_REG)
8279 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8280 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8281 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8282 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8284 (zero_extend:<DWI> (match_dup 2))
8285 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8286 [(match_dup 3) (const_int 0)]))))
8287 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8288 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8289 [(match_dup 3) (const_int 0)])
8292 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8293 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "use_carry" "1")
8296 (set_attr "pent_pair" "pu")
8297 (set_attr "mode" "<MODE>")])
8300 [(parallel [(set (reg:CCC FLAGS_REG)
8305 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8306 [(match_operand 2 "flags_reg_operand")
8308 (match_operand:SWI48 0 "general_reg_operand"))
8309 (match_operand:SWI48 1 "memory_operand")))
8311 (zero_extend:<DWI> (match_dup 1))
8312 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8313 [(match_dup 2) (const_int 0)]))))
8315 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8316 [(match_dup 2) (const_int 0)])
8319 (set (match_dup 1) (match_dup 0))]
8320 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8321 && peep2_reg_dead_p (2, operands[0])
8322 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8323 [(parallel [(set (reg:CCC FLAGS_REG)
8329 [(match_dup 2) (const_int 0)])
8333 (zero_extend:<DWI> (match_dup 0))
8335 [(match_dup 2) (const_int 0)]))))
8337 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8338 [(match_dup 2) (const_int 0)])
8343 [(set (match_operand:SWI48 0 "general_reg_operand")
8344 (match_operand:SWI48 1 "memory_operand"))
8345 (parallel [(set (reg:CCC FLAGS_REG)
8350 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8351 [(match_operand 3 "flags_reg_operand")
8354 (match_operand:SWI48 2 "memory_operand")))
8356 (zero_extend:<DWI> (match_dup 2))
8357 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8358 [(match_dup 3) (const_int 0)]))))
8360 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8361 [(match_dup 3) (const_int 0)])
8364 (set (match_dup 1) (match_dup 0))]
8365 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8366 && peep2_reg_dead_p (3, operands[0])
8367 && !reg_overlap_mentioned_p (operands[0], operands[1])
8368 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8369 [(set (match_dup 0) (match_dup 2))
8370 (parallel [(set (reg:CCC FLAGS_REG)
8376 [(match_dup 3) (const_int 0)])
8380 (zero_extend:<DWI> (match_dup 0))
8382 [(match_dup 3) (const_int 0)]))))
8384 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8385 [(match_dup 3) (const_int 0)])
8390 [(parallel [(set (reg:CCC FLAGS_REG)
8395 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8396 [(match_operand 2 "flags_reg_operand")
8398 (match_operand:SWI48 0 "general_reg_operand"))
8399 (match_operand:SWI48 1 "memory_operand")))
8401 (zero_extend:<DWI> (match_dup 1))
8402 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8403 [(match_dup 2) (const_int 0)]))))
8405 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8406 [(match_dup 2) (const_int 0)])
8409 (set (match_operand:QI 5 "general_reg_operand")
8410 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8411 (set (match_operand:SWI48 6 "general_reg_operand")
8412 (zero_extend:SWI48 (match_dup 5)))
8413 (set (match_dup 1) (match_dup 0))]
8414 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8415 && peep2_reg_dead_p (4, operands[0])
8416 && !reg_overlap_mentioned_p (operands[0], operands[1])
8417 && !reg_overlap_mentioned_p (operands[0], operands[5])
8418 && !reg_overlap_mentioned_p (operands[5], operands[1])
8419 && !reg_overlap_mentioned_p (operands[0], operands[6])
8420 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8421 [(parallel [(set (reg:CCC FLAGS_REG)
8427 [(match_dup 2) (const_int 0)])
8431 (zero_extend:<DWI> (match_dup 0))
8433 [(match_dup 2) (const_int 0)]))))
8435 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8436 [(match_dup 2) (const_int 0)])
8439 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8440 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8442 (define_expand "addcarry<mode>_0"
8444 [(set (reg:CCC FLAGS_REG)
8447 (match_operand:SWI48 1 "nonimmediate_operand")
8448 (match_operand:SWI48 2 "x86_64_general_operand"))
8450 (set (match_operand:SWI48 0 "nonimmediate_operand")
8451 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8452 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8454 (define_insn "*addcarry<mode>_1"
8455 [(set (reg:CCC FLAGS_REG)
8460 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8461 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8462 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8463 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8465 (match_operand:<DWI> 6 "const_scalar_int_operand")
8466 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8467 [(match_dup 3) (const_int 0)]))))
8468 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8469 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8470 [(match_dup 3) (const_int 0)])
8473 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8474 && CONST_INT_P (operands[2])
8475 /* Check that operands[6] is operands[2] zero extended from
8476 <MODE>mode to <DWI>mode. */
8477 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8478 ? (CONST_INT_P (operands[6])
8479 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8480 & GET_MODE_MASK (<MODE>mode)))
8481 : (CONST_WIDE_INT_P (operands[6])
8482 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8483 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8484 == UINTVAL (operands[2]))
8485 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8486 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8487 [(set_attr "type" "alu")
8488 (set_attr "use_carry" "1")
8489 (set_attr "pent_pair" "pu")
8490 (set_attr "mode" "<MODE>")
8491 (set (attr "length_immediate")
8492 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8494 (const_string "4")))])
8496 (define_insn "@sub<mode>3_carry"
8497 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8500 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8501 (match_operator:SWI 4 "ix86_carry_flag_operator"
8502 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8503 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8504 (clobber (reg:CC FLAGS_REG))]
8505 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8506 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8507 [(set_attr "type" "alu")
8508 (set_attr "use_carry" "1")
8509 (set_attr "pent_pair" "pu")
8510 (set_attr "mode" "<MODE>")])
8513 [(set (match_operand:SWI 0 "general_reg_operand")
8514 (match_operand:SWI 1 "memory_operand"))
8515 (parallel [(set (match_dup 0)
8519 (match_operator:SWI 4 "ix86_carry_flag_operator"
8520 [(match_operand 3 "flags_reg_operand")
8522 (match_operand:SWI 2 "memory_operand")))
8523 (clobber (reg:CC FLAGS_REG))])
8524 (set (match_dup 1) (match_dup 0))]
8525 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8526 && peep2_reg_dead_p (3, operands[0])
8527 && !reg_overlap_mentioned_p (operands[0], operands[1])
8528 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8529 [(set (match_dup 0) (match_dup 2))
8530 (parallel [(set (match_dup 1)
8531 (minus:SWI (minus:SWI (match_dup 1)
8533 [(match_dup 3) (const_int 0)]))
8535 (clobber (reg:CC FLAGS_REG))])])
8538 [(set (match_operand:SWI 0 "general_reg_operand")
8539 (match_operand:SWI 1 "memory_operand"))
8540 (parallel [(set (match_dup 0)
8544 (match_operator:SWI 4 "ix86_carry_flag_operator"
8545 [(match_operand 3 "flags_reg_operand")
8547 (match_operand:SWI 2 "memory_operand")))
8548 (clobber (reg:CC FLAGS_REG))])
8549 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8550 (set (match_dup 1) (match_dup 5))]
8551 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8552 && peep2_reg_dead_p (3, operands[0])
8553 && peep2_reg_dead_p (4, operands[5])
8554 && !reg_overlap_mentioned_p (operands[0], operands[1])
8555 && !reg_overlap_mentioned_p (operands[0], operands[2])
8556 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8557 [(set (match_dup 0) (match_dup 2))
8558 (parallel [(set (match_dup 1)
8559 (minus:SWI (minus:SWI (match_dup 1)
8561 [(match_dup 3) (const_int 0)]))
8563 (clobber (reg:CC FLAGS_REG))])])
8565 (define_insn "*sub<mode>3_carry_0"
8566 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8568 (match_operand:SWI 1 "nonimmediate_operand" "0")
8569 (match_operator:SWI 2 "ix86_carry_flag_operator"
8570 [(reg FLAGS_REG) (const_int 0)])))
8571 (clobber (reg:CC FLAGS_REG))]
8572 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8573 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8574 [(set_attr "type" "alu")
8575 (set_attr "use_carry" "1")
8576 (set_attr "pent_pair" "pu")
8577 (set_attr "mode" "<MODE>")])
8579 (define_insn "*sub<mode>3_carry_0r"
8580 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8582 (match_operand:SWI 1 "nonimmediate_operand" "0")
8583 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8584 [(reg FLAGS_REG) (const_int 0)])))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8587 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8588 [(set_attr "type" "alu")
8589 (set_attr "use_carry" "1")
8590 (set_attr "pent_pair" "pu")
8591 (set_attr "mode" "<MODE>")])
8593 (define_insn "*subsi3_carry_zext"
8594 [(set (match_operand:DI 0 "register_operand" "=r")
8598 (match_operand:SI 1 "register_operand" "0")
8599 (match_operator:SI 3 "ix86_carry_flag_operator"
8600 [(reg FLAGS_REG) (const_int 0)]))
8601 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8604 "sbb{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "use_carry" "1")
8607 (set_attr "pent_pair" "pu")
8608 (set_attr "mode" "SI")])
8610 (define_insn "*subsi3_carry_zext_0"
8611 [(set (match_operand:DI 0 "register_operand" "=r")
8614 (match_operand:SI 1 "register_operand" "0")
8615 (match_operator:SI 2 "ix86_carry_flag_operator"
8616 [(reg FLAGS_REG) (const_int 0)]))))
8617 (clobber (reg:CC FLAGS_REG))]
8619 "sbb{l}\t{$0, %k0|%k0, 0}"
8620 [(set_attr "type" "alu")
8621 (set_attr "use_carry" "1")
8622 (set_attr "pent_pair" "pu")
8623 (set_attr "mode" "SI")])
8625 (define_insn "*subsi3_carry_zext_0r"
8626 [(set (match_operand:DI 0 "register_operand" "=r")
8629 (match_operand:SI 1 "register_operand" "0")
8630 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8631 [(reg FLAGS_REG) (const_int 0)]))))
8632 (clobber (reg:CC FLAGS_REG))]
8634 "adc{l}\t{$-1, %k0|%k0, -1}"
8635 [(set_attr "type" "alu")
8636 (set_attr "use_carry" "1")
8637 (set_attr "pent_pair" "pu")
8638 (set_attr "mode" "SI")])
8640 (define_insn "@sub<mode>3_carry_ccc"
8641 [(set (reg:CCC FLAGS_REG)
8643 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8645 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8647 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8648 (clobber (match_scratch:DWIH 0 "=r"))]
8650 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "<MODE>")])
8654 (define_insn "*sub<mode>3_carry_ccc_1"
8655 [(set (reg:CCC FLAGS_REG)
8657 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8659 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8660 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8661 (clobber (match_scratch:DWIH 0 "=r"))]
8664 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8665 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "<MODE>")])
8670 ;; The sign flag is set from the
8671 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8672 ;; result, the overflow flag likewise, but the overflow flag is also
8673 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8674 (define_insn "@sub<mode>3_carry_ccgz"
8675 [(set (reg:CCGZ FLAGS_REG)
8676 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8677 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8678 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8680 (clobber (match_scratch:DWIH 0 "=r"))]
8682 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "<MODE>")])
8686 (define_insn "subborrow<mode>"
8687 [(set (reg:CCC FLAGS_REG)
8690 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8692 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8693 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8695 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8696 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8697 (minus:SWI48 (minus:SWI48
8699 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8700 [(match_dup 3) (const_int 0)]))
8702 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8703 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "use_carry" "1")
8706 (set_attr "pent_pair" "pu")
8707 (set_attr "mode" "<MODE>")])
8710 [(set (match_operand:SWI48 0 "general_reg_operand")
8711 (match_operand:SWI48 1 "memory_operand"))
8712 (parallel [(set (reg:CCC FLAGS_REG)
8714 (zero_extend:<DWI> (match_dup 0))
8716 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8717 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8719 (match_operand:SWI48 2 "memory_operand")))))
8724 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8725 [(match_dup 3) (const_int 0)]))
8727 (set (match_dup 1) (match_dup 0))]
8728 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8729 && peep2_reg_dead_p (3, operands[0])
8730 && !reg_overlap_mentioned_p (operands[0], operands[1])
8731 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8732 [(set (match_dup 0) (match_dup 2))
8733 (parallel [(set (reg:CCC FLAGS_REG)
8735 (zero_extend:<DWI> (match_dup 1))
8736 (plus:<DWI> (match_op_dup 4
8737 [(match_dup 3) (const_int 0)])
8738 (zero_extend:<DWI> (match_dup 0)))))
8740 (minus:SWI48 (minus:SWI48 (match_dup 1)
8742 [(match_dup 3) (const_int 0)]))
8746 [(set (match_operand:SWI48 6 "general_reg_operand")
8747 (match_operand:SWI48 7 "memory_operand"))
8748 (set (match_operand:SWI48 8 "general_reg_operand")
8749 (match_operand:SWI48 9 "memory_operand"))
8750 (parallel [(set (reg:CCC FLAGS_REG)
8753 (match_operand:SWI48 0 "general_reg_operand"))
8755 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8756 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8758 (match_operand:SWI48 2 "general_reg_operand")))))
8763 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8764 [(match_dup 3) (const_int 0)]))
8766 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8767 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8768 && peep2_reg_dead_p (4, operands[0])
8769 && peep2_reg_dead_p (3, operands[2])
8770 && !reg_overlap_mentioned_p (operands[0], operands[1])
8771 && !reg_overlap_mentioned_p (operands[2], operands[1])
8772 && !reg_overlap_mentioned_p (operands[6], operands[9])
8773 && (rtx_equal_p (operands[6], operands[0])
8774 ? (rtx_equal_p (operands[7], operands[1])
8775 && rtx_equal_p (operands[8], operands[2]))
8776 : (rtx_equal_p (operands[8], operands[0])
8777 && rtx_equal_p (operands[9], operands[1])
8778 && rtx_equal_p (operands[6], operands[2])))"
8779 [(set (match_dup 0) (match_dup 9))
8780 (parallel [(set (reg:CCC FLAGS_REG)
8782 (zero_extend:<DWI> (match_dup 1))
8783 (plus:<DWI> (match_op_dup 4
8784 [(match_dup 3) (const_int 0)])
8785 (zero_extend:<DWI> (match_dup 0)))))
8787 (minus:SWI48 (minus:SWI48 (match_dup 1)
8789 [(match_dup 3) (const_int 0)]))
8792 if (!rtx_equal_p (operands[6], operands[0]))
8793 operands[9] = operands[7];
8797 [(set (match_operand:SWI48 6 "general_reg_operand")
8798 (match_operand:SWI48 7 "memory_operand"))
8799 (set (match_operand:SWI48 8 "general_reg_operand")
8800 (match_operand:SWI48 9 "memory_operand"))
8801 (parallel [(set (reg:CCC FLAGS_REG)
8804 (match_operand:SWI48 0 "general_reg_operand"))
8806 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8807 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8809 (match_operand:SWI48 2 "general_reg_operand")))))
8814 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8815 [(match_dup 3) (const_int 0)]))
8817 (set (match_operand:QI 10 "general_reg_operand")
8818 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8819 (set (match_operand:SWI48 11 "general_reg_operand")
8820 (zero_extend:SWI48 (match_dup 10)))
8821 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8822 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8823 && peep2_reg_dead_p (6, operands[0])
8824 && peep2_reg_dead_p (3, operands[2])
8825 && !reg_overlap_mentioned_p (operands[0], operands[1])
8826 && !reg_overlap_mentioned_p (operands[2], operands[1])
8827 && !reg_overlap_mentioned_p (operands[6], operands[9])
8828 && !reg_overlap_mentioned_p (operands[0], operands[10])
8829 && !reg_overlap_mentioned_p (operands[10], operands[1])
8830 && !reg_overlap_mentioned_p (operands[0], operands[11])
8831 && !reg_overlap_mentioned_p (operands[11], operands[1])
8832 && (rtx_equal_p (operands[6], operands[0])
8833 ? (rtx_equal_p (operands[7], operands[1])
8834 && rtx_equal_p (operands[8], operands[2]))
8835 : (rtx_equal_p (operands[8], operands[0])
8836 && rtx_equal_p (operands[9], operands[1])
8837 && rtx_equal_p (operands[6], operands[2])))"
8838 [(set (match_dup 0) (match_dup 9))
8839 (parallel [(set (reg:CCC FLAGS_REG)
8841 (zero_extend:<DWI> (match_dup 1))
8842 (plus:<DWI> (match_op_dup 4
8843 [(match_dup 3) (const_int 0)])
8844 (zero_extend:<DWI> (match_dup 0)))))
8846 (minus:SWI48 (minus:SWI48 (match_dup 1)
8848 [(match_dup 3) (const_int 0)]))
8850 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8851 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8853 if (!rtx_equal_p (operands[6], operands[0]))
8854 operands[9] = operands[7];
8857 (define_expand "subborrow<mode>_0"
8859 [(set (reg:CC FLAGS_REG)
8861 (match_operand:SWI48 1 "nonimmediate_operand")
8862 (match_operand:SWI48 2 "<general_operand>")))
8863 (set (match_operand:SWI48 0 "register_operand")
8864 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8865 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8867 (define_expand "uaddc<mode>5"
8868 [(match_operand:SWI48 0 "register_operand")
8869 (match_operand:SWI48 1 "register_operand")
8870 (match_operand:SWI48 2 "register_operand")
8871 (match_operand:SWI48 3 "register_operand")
8872 (match_operand:SWI48 4 "nonmemory_operand")]
8875 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8876 if (operands[4] == const0_rtx)
8877 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8880 ix86_expand_carry (operands[4]);
8881 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8882 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8883 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8886 rtx cc = gen_reg_rtx (QImode);
8887 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8888 emit_insn (gen_rtx_SET (cc, pat));
8889 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8893 (define_expand "usubc<mode>5"
8894 [(match_operand:SWI48 0 "register_operand")
8895 (match_operand:SWI48 1 "register_operand")
8896 (match_operand:SWI48 2 "register_operand")
8897 (match_operand:SWI48 3 "register_operand")
8898 (match_operand:SWI48 4 "nonmemory_operand")]
8902 if (operands[4] == const0_rtx)
8904 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8905 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8910 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8911 ix86_expand_carry (operands[4]);
8912 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8913 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8914 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8917 rtx cc = gen_reg_rtx (QImode);
8918 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8919 emit_insn (gen_rtx_SET (cc, pat));
8920 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8924 (define_mode_iterator CC_CCC [CC CCC])
8926 ;; Pre-reload splitter to optimize
8927 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8928 ;; operand and no intervening flags modifications into nothing.
8929 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8930 [(set (reg:CCC FLAGS_REG)
8931 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8932 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8933 "ix86_pre_reload_split ()"
8937 "emit_note (NOTE_INSN_DELETED); DONE;")
8939 ;; Set the carry flag from the carry flag.
8940 (define_insn_and_split "*setccc"
8941 [(set (reg:CCC FLAGS_REG)
8942 (reg:CCC FLAGS_REG))]
8943 "ix86_pre_reload_split ()"
8947 "emit_note (NOTE_INSN_DELETED); DONE;")
8949 ;; Set the carry flag from the carry flag.
8950 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8951 [(set (reg:CCC FLAGS_REG)
8952 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8953 "ix86_pre_reload_split ()"
8957 "emit_note (NOTE_INSN_DELETED); DONE;")
8959 ;; Set the carry flag from the carry flag.
8960 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8961 [(set (reg:CCC FLAGS_REG)
8962 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8963 (const_int 0)] UNSPEC_CC_NE))]
8964 "ix86_pre_reload_split ()"
8968 "emit_note (NOTE_INSN_DELETED); DONE;")
8970 ;; Overflow setting add instructions
8972 (define_expand "addqi3_cconly_overflow"
8974 [(set (reg:CCC FLAGS_REG)
8977 (match_operand:QI 0 "nonimmediate_operand")
8978 (match_operand:QI 1 "general_operand"))
8980 (clobber (scratch:QI))])]
8981 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8983 (define_insn "*add<mode>3_cconly_overflow_1"
8984 [(set (reg:CCC FLAGS_REG)
8987 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8988 (match_operand:SWI 2 "<general_operand>" "<g>"))
8990 (clobber (match_scratch:SWI 0 "=<r>"))]
8991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8992 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "<MODE>")])
8996 (define_insn "@add<mode>3_cc_overflow_1"
8997 [(set (reg:CCC FLAGS_REG)
9000 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9001 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9003 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9004 (plus:SWI (match_dup 1) (match_dup 2)))]
9005 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9006 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "<MODE>")])
9011 [(parallel [(set (reg:CCC FLAGS_REG)
9013 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9014 (match_operand:SWI 1 "memory_operand"))
9016 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9017 (set (match_dup 1) (match_dup 0))]
9018 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9019 && peep2_reg_dead_p (2, operands[0])
9020 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9021 [(parallel [(set (reg:CCC FLAGS_REG)
9023 (plus:SWI (match_dup 1) (match_dup 0))
9025 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9028 [(set (match_operand:SWI 0 "general_reg_operand")
9029 (match_operand:SWI 1 "memory_operand"))
9030 (parallel [(set (reg:CCC FLAGS_REG)
9032 (plus:SWI (match_dup 0)
9033 (match_operand:SWI 2 "memory_operand"))
9035 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9036 (set (match_dup 1) (match_dup 0))]
9037 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9038 && peep2_reg_dead_p (3, operands[0])
9039 && !reg_overlap_mentioned_p (operands[0], operands[1])
9040 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9041 [(set (match_dup 0) (match_dup 2))
9042 (parallel [(set (reg:CCC FLAGS_REG)
9044 (plus:SWI (match_dup 1) (match_dup 0))
9046 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9048 (define_insn "*addsi3_zext_cc_overflow_1"
9049 [(set (reg:CCC FLAGS_REG)
9052 (match_operand:SI 1 "nonimmediate_operand" "%0")
9053 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9055 (set (match_operand:DI 0 "register_operand" "=r")
9056 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9057 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9058 "add{l}\t{%2, %k0|%k0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "SI")])
9062 (define_insn "*add<mode>3_cconly_overflow_2"
9063 [(set (reg:CCC FLAGS_REG)
9066 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9067 (match_operand:SWI 2 "<general_operand>" "<g>"))
9069 (clobber (match_scratch:SWI 0 "=<r>"))]
9070 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9071 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "<MODE>")])
9075 (define_insn "*add<mode>3_cc_overflow_2"
9076 [(set (reg:CCC FLAGS_REG)
9079 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9080 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9082 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9083 (plus:SWI (match_dup 1) (match_dup 2)))]
9084 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9085 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "<MODE>")])
9089 (define_insn "*addsi3_zext_cc_overflow_2"
9090 [(set (reg:CCC FLAGS_REG)
9093 (match_operand:SI 1 "nonimmediate_operand" "%0")
9094 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9096 (set (match_operand:DI 0 "register_operand" "=r")
9097 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9098 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9099 "add{l}\t{%2, %k0|%k0, %2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "SI")])
9103 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9104 [(set (reg:CCC FLAGS_REG)
9107 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9108 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9110 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9111 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9112 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9114 "&& reload_completed"
9115 [(parallel [(set (reg:CCC FLAGS_REG)
9117 (plus:DWIH (match_dup 1) (match_dup 2))
9120 (plus:DWIH (match_dup 1) (match_dup 2)))])
9121 (parallel [(set (reg:CCC FLAGS_REG)
9126 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9131 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9134 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9138 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9139 if (operands[2] == const0_rtx)
9141 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9144 if (CONST_INT_P (operands[5]))
9145 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9146 operands[5], <MODE>mode);
9148 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9151 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9152 ;; test, where the latter is preferrable if we have some carry consuming
9154 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9156 (define_insn_and_split "*add<mode>3_eq"
9157 [(set (match_operand:SWI 0 "nonimmediate_operand")
9160 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9161 (match_operand:SWI 1 "nonimmediate_operand"))
9162 (match_operand:SWI 2 "<general_operand>")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9165 && ix86_pre_reload_split ()"
9168 [(set (reg:CC FLAGS_REG)
9169 (compare:CC (match_dup 3) (const_int 1)))
9170 (parallel [(set (match_dup 0)
9172 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9175 (clobber (reg:CC FLAGS_REG))])])
9177 (define_insn_and_split "*add<mode>3_ne"
9178 [(set (match_operand:SWI 0 "nonimmediate_operand")
9181 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9182 (match_operand:SWI 1 "nonimmediate_operand"))
9183 (match_operand:SWI 2 "<immediate_operand>")))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "CONST_INT_P (operands[2])
9186 && (<MODE>mode != DImode
9187 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9188 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9189 && ix86_pre_reload_split ()"
9192 [(set (reg:CC FLAGS_REG)
9193 (compare:CC (match_dup 3) (const_int 1)))
9194 (parallel [(set (match_dup 0)
9196 (minus:SWI (match_dup 1)
9197 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9199 (clobber (reg:CC FLAGS_REG))])]
9201 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9202 <MODE>mode == DImode ? SImode : <MODE>mode);
9205 (define_insn_and_split "*add<mode>3_eq_0"
9206 [(set (match_operand:SWI 0 "nonimmediate_operand")
9208 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9209 (match_operand:SWI 1 "<general_operand>")))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9212 && ix86_pre_reload_split ()"
9215 [(set (reg:CC FLAGS_REG)
9216 (compare:CC (match_dup 2) (const_int 1)))
9217 (parallel [(set (match_dup 0)
9218 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9220 (clobber (reg:CC FLAGS_REG))])]
9222 if (!nonimmediate_operand (operands[1], <MODE>mode))
9223 operands[1] = force_reg (<MODE>mode, operands[1]);
9226 (define_insn_and_split "*add<mode>3_ne_0"
9227 [(set (match_operand:SWI 0 "nonimmediate_operand")
9229 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9230 (match_operand:SWI 1 "<general_operand>")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9233 && ix86_pre_reload_split ()"
9236 [(set (reg:CC FLAGS_REG)
9237 (compare:CC (match_dup 2) (const_int 1)))
9238 (parallel [(set (match_dup 0)
9239 (minus:SWI (minus:SWI
9241 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9243 (clobber (reg:CC FLAGS_REG))])]
9245 if (!nonimmediate_operand (operands[1], <MODE>mode))
9246 operands[1] = force_reg (<MODE>mode, operands[1]);
9249 (define_insn_and_split "*sub<mode>3_eq"
9250 [(set (match_operand:SWI 0 "nonimmediate_operand")
9253 (match_operand:SWI 1 "nonimmediate_operand")
9254 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9256 (match_operand:SWI 2 "<general_operand>")))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9259 && ix86_pre_reload_split ()"
9262 [(set (reg:CC FLAGS_REG)
9263 (compare:CC (match_dup 3) (const_int 1)))
9264 (parallel [(set (match_dup 0)
9266 (minus:SWI (match_dup 1)
9267 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9269 (clobber (reg:CC FLAGS_REG))])])
9271 (define_insn_and_split "*sub<mode>3_ne"
9272 [(set (match_operand:SWI 0 "nonimmediate_operand")
9275 (match_operand:SWI 1 "nonimmediate_operand")
9276 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9278 (match_operand:SWI 2 "<immediate_operand>")))
9279 (clobber (reg:CC FLAGS_REG))]
9280 "CONST_INT_P (operands[2])
9281 && (<MODE>mode != DImode
9282 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9283 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9284 && ix86_pre_reload_split ()"
9287 [(set (reg:CC FLAGS_REG)
9288 (compare:CC (match_dup 3) (const_int 1)))
9289 (parallel [(set (match_dup 0)
9291 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9294 (clobber (reg:CC FLAGS_REG))])]
9296 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9297 <MODE>mode == DImode ? SImode : <MODE>mode);
9300 (define_insn_and_split "*sub<mode>3_eq_1"
9301 [(set (match_operand:SWI 0 "nonimmediate_operand")
9304 (match_operand:SWI 1 "nonimmediate_operand")
9305 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9307 (match_operand:SWI 2 "<immediate_operand>")))
9308 (clobber (reg:CC FLAGS_REG))]
9309 "CONST_INT_P (operands[2])
9310 && (<MODE>mode != DImode
9311 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9312 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9313 && ix86_pre_reload_split ()"
9316 [(set (reg:CC FLAGS_REG)
9317 (compare:CC (match_dup 3) (const_int 1)))
9318 (parallel [(set (match_dup 0)
9320 (minus:SWI (match_dup 1)
9321 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9323 (clobber (reg:CC FLAGS_REG))])]
9325 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9326 <MODE>mode == DImode ? SImode : <MODE>mode);
9329 (define_insn_and_split "*sub<mode>3_eq_0"
9330 [(set (match_operand:SWI 0 "nonimmediate_operand")
9332 (match_operand:SWI 1 "<general_operand>")
9333 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9336 && ix86_pre_reload_split ()"
9339 [(set (reg:CC FLAGS_REG)
9340 (compare:CC (match_dup 2) (const_int 1)))
9341 (parallel [(set (match_dup 0)
9342 (minus:SWI (match_dup 1)
9343 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9344 (clobber (reg:CC FLAGS_REG))])]
9346 if (!nonimmediate_operand (operands[1], <MODE>mode))
9347 operands[1] = force_reg (<MODE>mode, operands[1]);
9350 (define_insn_and_split "*sub<mode>3_ne_0"
9351 [(set (match_operand:SWI 0 "nonimmediate_operand")
9353 (match_operand:SWI 1 "<general_operand>")
9354 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9357 && ix86_pre_reload_split ()"
9360 [(set (reg:CC FLAGS_REG)
9361 (compare:CC (match_dup 2) (const_int 1)))
9362 (parallel [(set (match_dup 0)
9364 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9367 (clobber (reg:CC FLAGS_REG))])]
9369 if (!nonimmediate_operand (operands[1], <MODE>mode))
9370 operands[1] = force_reg (<MODE>mode, operands[1]);
9373 ;; The patterns that match these are at the end of this file.
9375 (define_expand "<insn>xf3"
9376 [(set (match_operand:XF 0 "register_operand")
9378 (match_operand:XF 1 "register_operand")
9379 (match_operand:XF 2 "register_operand")))]
9382 (define_expand "<insn>hf3"
9383 [(set (match_operand:HF 0 "register_operand")
9385 (match_operand:HF 1 "register_operand")
9386 (match_operand:HF 2 "nonimmediate_operand")))]
9387 "TARGET_AVX512FP16")
9389 (define_expand "<insn><mode>3"
9390 [(set (match_operand:MODEF 0 "register_operand")
9392 (match_operand:MODEF 1 "register_operand")
9393 (match_operand:MODEF 2 "nonimmediate_operand")))]
9394 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9395 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9397 ;; Multiply instructions
9399 (define_expand "mul<mode>3"
9400 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9402 (match_operand:SWIM248 1 "register_operand")
9403 (match_operand:SWIM248 2 "<general_operand>")))
9404 (clobber (reg:CC FLAGS_REG))])])
9406 (define_expand "mulqi3"
9407 [(parallel [(set (match_operand:QI 0 "register_operand")
9409 (match_operand:QI 1 "register_operand")
9410 (match_operand:QI 2 "nonimmediate_operand")))
9411 (clobber (reg:CC FLAGS_REG))])]
9412 "TARGET_QIMODE_MATH")
9415 ;; IMUL reg32/64, reg32/64, imm8 Direct
9416 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9417 ;; IMUL reg32/64, reg32/64, imm32 Direct
9418 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9419 ;; IMUL reg32/64, reg32/64 Direct
9420 ;; IMUL reg32/64, mem32/64 Direct
9422 ;; On BDVER1, all above IMULs use DirectPath
9425 ;; IMUL reg16, reg16, imm8 VectorPath
9426 ;; IMUL reg16, mem16, imm8 VectorPath
9427 ;; IMUL reg16, reg16, imm16 VectorPath
9428 ;; IMUL reg16, mem16, imm16 VectorPath
9429 ;; IMUL reg16, reg16 Direct
9430 ;; IMUL reg16, mem16 Direct
9432 ;; On BDVER1, all HI MULs use DoublePath
9434 (define_insn "*mul<mode>3_1"
9435 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9437 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9438 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9439 (clobber (reg:CC FLAGS_REG))]
9440 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9442 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9443 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9444 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9445 [(set_attr "type" "imul")
9446 (set_attr "prefix_0f" "0,0,1")
9447 (set (attr "athlon_decode")
9448 (cond [(eq_attr "cpu" "athlon")
9449 (const_string "vector")
9450 (eq_attr "alternative" "1")
9451 (const_string "vector")
9452 (and (eq_attr "alternative" "2")
9453 (ior (match_test "<MODE>mode == HImode")
9454 (match_operand 1 "memory_operand")))
9455 (const_string "vector")]
9456 (const_string "direct")))
9457 (set (attr "amdfam10_decode")
9458 (cond [(and (eq_attr "alternative" "0,1")
9459 (ior (match_test "<MODE>mode == HImode")
9460 (match_operand 1 "memory_operand")))
9461 (const_string "vector")]
9462 (const_string "direct")))
9463 (set (attr "bdver1_decode")
9465 (match_test "<MODE>mode == HImode")
9466 (const_string "double")
9467 (const_string "direct")))
9468 (set_attr "mode" "<MODE>")])
9470 (define_insn "*mulsi3_1_zext"
9471 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9473 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9474 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9475 (clobber (reg:CC FLAGS_REG))]
9477 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9479 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9480 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9481 imul{l}\t{%2, %k0|%k0, %2}"
9482 [(set_attr "type" "imul")
9483 (set_attr "prefix_0f" "0,0,1")
9484 (set (attr "athlon_decode")
9485 (cond [(eq_attr "cpu" "athlon")
9486 (const_string "vector")
9487 (eq_attr "alternative" "1")
9488 (const_string "vector")
9489 (and (eq_attr "alternative" "2")
9490 (match_operand 1 "memory_operand"))
9491 (const_string "vector")]
9492 (const_string "direct")))
9493 (set (attr "amdfam10_decode")
9494 (cond [(and (eq_attr "alternative" "0,1")
9495 (match_operand 1 "memory_operand"))
9496 (const_string "vector")]
9497 (const_string "direct")))
9498 (set_attr "bdver1_decode" "direct")
9499 (set_attr "mode" "SI")])
9501 ;;On AMDFAM10 and BDVER1
9505 (define_insn "*mulqi3_1"
9506 [(set (match_operand:QI 0 "register_operand" "=a")
9507 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9508 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9509 (clobber (reg:CC FLAGS_REG))]
9511 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9513 [(set_attr "type" "imul")
9514 (set_attr "length_immediate" "0")
9515 (set (attr "athlon_decode")
9516 (if_then_else (eq_attr "cpu" "athlon")
9517 (const_string "vector")
9518 (const_string "direct")))
9519 (set_attr "amdfam10_decode" "direct")
9520 (set_attr "bdver1_decode" "direct")
9521 (set_attr "mode" "QI")])
9523 ;; Multiply with jump on overflow.
9524 (define_expand "mulv<mode>4"
9525 [(parallel [(set (reg:CCO FLAGS_REG)
9528 (match_operand:SWI248 1 "register_operand"))
9531 (mult:SWI248 (match_dup 1)
9532 (match_operand:SWI248 2
9533 "<general_operand>")))))
9534 (set (match_operand:SWI248 0 "register_operand")
9535 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9536 (set (pc) (if_then_else
9537 (eq (reg:CCO FLAGS_REG) (const_int 0))
9538 (label_ref (match_operand 3))
9542 if (CONST_INT_P (operands[2]))
9543 operands[4] = operands[2];
9545 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9548 (define_insn "*mulv<mode>4"
9549 [(set (reg:CCO FLAGS_REG)
9552 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9554 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9556 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9557 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9558 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9559 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9561 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9562 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9563 [(set_attr "type" "imul")
9564 (set_attr "prefix_0f" "0,1")
9565 (set (attr "athlon_decode")
9566 (cond [(eq_attr "cpu" "athlon")
9567 (const_string "vector")
9568 (eq_attr "alternative" "0")
9569 (const_string "vector")
9570 (and (eq_attr "alternative" "1")
9571 (match_operand 1 "memory_operand"))
9572 (const_string "vector")]
9573 (const_string "direct")))
9574 (set (attr "amdfam10_decode")
9575 (cond [(and (eq_attr "alternative" "1")
9576 (match_operand 1 "memory_operand"))
9577 (const_string "vector")]
9578 (const_string "direct")))
9579 (set_attr "bdver1_decode" "direct")
9580 (set_attr "mode" "<MODE>")])
9582 (define_insn "*mulvhi4"
9583 [(set (reg:CCO FLAGS_REG)
9586 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9588 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9590 (mult:HI (match_dup 1) (match_dup 2)))))
9591 (set (match_operand:HI 0 "register_operand" "=r")
9592 (mult:HI (match_dup 1) (match_dup 2)))]
9593 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9594 "imul{w}\t{%2, %0|%0, %2}"
9595 [(set_attr "type" "imul")
9596 (set_attr "prefix_0f" "1")
9597 (set_attr "athlon_decode" "vector")
9598 (set_attr "amdfam10_decode" "direct")
9599 (set_attr "bdver1_decode" "double")
9600 (set_attr "mode" "HI")])
9602 (define_insn "*mulv<mode>4_1"
9603 [(set (reg:CCO FLAGS_REG)
9606 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9607 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9609 (mult:SWI248 (match_dup 1)
9610 (match_operand:SWI248 2
9611 "<immediate_operand>" "K,<i>")))))
9612 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9613 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9614 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9615 && CONST_INT_P (operands[2])
9616 && INTVAL (operands[2]) == INTVAL (operands[3])"
9617 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9618 [(set_attr "type" "imul")
9619 (set (attr "prefix_0f")
9621 (match_test "<MODE>mode == HImode")
9623 (const_string "*")))
9624 (set (attr "athlon_decode")
9625 (cond [(eq_attr "cpu" "athlon")
9626 (const_string "vector")
9627 (eq_attr "alternative" "1")
9628 (const_string "vector")]
9629 (const_string "direct")))
9630 (set (attr "amdfam10_decode")
9631 (cond [(ior (match_test "<MODE>mode == HImode")
9632 (match_operand 1 "memory_operand"))
9633 (const_string "vector")]
9634 (const_string "direct")))
9635 (set (attr "bdver1_decode")
9637 (match_test "<MODE>mode == HImode")
9638 (const_string "double")
9639 (const_string "direct")))
9640 (set_attr "mode" "<MODE>")
9641 (set (attr "length_immediate")
9642 (cond [(eq_attr "alternative" "0")
9644 (match_test "<MODE_SIZE> == 8")
9646 (const_string "<MODE_SIZE>")))])
9648 (define_expand "umulv<mode>4"
9649 [(parallel [(set (reg:CCO FLAGS_REG)
9652 (match_operand:SWI248 1
9653 "nonimmediate_operand"))
9655 (match_operand:SWI248 2
9656 "nonimmediate_operand")))
9658 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9659 (set (match_operand:SWI248 0 "register_operand")
9660 (mult:SWI248 (match_dup 1) (match_dup 2)))
9661 (clobber (scratch:SWI248))])
9662 (set (pc) (if_then_else
9663 (eq (reg:CCO FLAGS_REG) (const_int 0))
9664 (label_ref (match_operand 3))
9668 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9669 operands[1] = force_reg (<MODE>mode, operands[1]);
9672 (define_insn "*umulv<mode>4"
9673 [(set (reg:CCO FLAGS_REG)
9676 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9678 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9680 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9681 (set (match_operand:SWI248 0 "register_operand" "=a")
9682 (mult:SWI248 (match_dup 1) (match_dup 2)))
9683 (clobber (match_scratch:SWI248 3 "=d"))]
9684 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9685 "mul{<imodesuffix>}\t%2"
9686 [(set_attr "type" "imul")
9687 (set_attr "length_immediate" "0")
9688 (set (attr "athlon_decode")
9689 (if_then_else (eq_attr "cpu" "athlon")
9690 (const_string "vector")
9691 (const_string "double")))
9692 (set_attr "amdfam10_decode" "double")
9693 (set_attr "bdver1_decode" "direct")
9694 (set_attr "mode" "<MODE>")])
9696 (define_expand "<u>mulvqi4"
9697 [(parallel [(set (reg:CCO FLAGS_REG)
9700 (match_operand:QI 1 "nonimmediate_operand"))
9702 (match_operand:QI 2 "nonimmediate_operand")))
9704 (mult:QI (match_dup 1) (match_dup 2)))))
9705 (set (match_operand:QI 0 "register_operand")
9706 (mult:QI (match_dup 1) (match_dup 2)))])
9707 (set (pc) (if_then_else
9708 (eq (reg:CCO FLAGS_REG) (const_int 0))
9709 (label_ref (match_operand 3))
9711 "TARGET_QIMODE_MATH"
9713 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9714 operands[1] = force_reg (QImode, operands[1]);
9717 (define_insn "*<u>mulvqi4"
9718 [(set (reg:CCO FLAGS_REG)
9721 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9723 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9725 (mult:QI (match_dup 1) (match_dup 2)))))
9726 (set (match_operand:QI 0 "register_operand" "=a")
9727 (mult:QI (match_dup 1) (match_dup 2)))]
9729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9730 "<sgnprefix>mul{b}\t%2"
9731 [(set_attr "type" "imul")
9732 (set_attr "length_immediate" "0")
9733 (set (attr "athlon_decode")
9734 (if_then_else (eq_attr "cpu" "athlon")
9735 (const_string "vector")
9736 (const_string "direct")))
9737 (set_attr "amdfam10_decode" "direct")
9738 (set_attr "bdver1_decode" "direct")
9739 (set_attr "mode" "QI")])
9741 (define_expand "<u>mul<mode><dwi>3"
9742 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9745 (match_operand:DWIH 1 "register_operand"))
9747 (match_operand:DWIH 2 "nonimmediate_operand"))))
9748 (clobber (reg:CC FLAGS_REG))])])
9750 (define_expand "<u>mulqihi3"
9751 [(parallel [(set (match_operand:HI 0 "register_operand")
9754 (match_operand:QI 1 "register_operand"))
9756 (match_operand:QI 2 "nonimmediate_operand"))))
9757 (clobber (reg:CC FLAGS_REG))])]
9758 "TARGET_QIMODE_MATH")
9760 (define_insn "*bmi2_umul<mode><dwi>3_1"
9761 [(set (match_operand:DWIH 0 "register_operand" "=r")
9763 (match_operand:DWIH 2 "register_operand" "%d")
9764 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9765 (set (match_operand:DWIH 1 "register_operand" "=r")
9766 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9768 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9769 "mulx\t{%3, %0, %1|%1, %0, %3}"
9770 [(set_attr "type" "imulx")
9771 (set_attr "prefix" "vex")
9772 (set_attr "mode" "<MODE>")])
9774 (define_insn "*umul<mode><dwi>3_1"
9775 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9778 (match_operand:DWIH 1 "register_operand" "%d,a"))
9780 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9785 mul{<imodesuffix>}\t%2"
9786 [(set_attr "isa" "bmi2,*")
9787 (set_attr "type" "imulx,imul")
9788 (set_attr "length_immediate" "*,0")
9789 (set (attr "athlon_decode")
9790 (cond [(eq_attr "alternative" "1")
9791 (if_then_else (eq_attr "cpu" "athlon")
9792 (const_string "vector")
9793 (const_string "double"))]
9794 (const_string "*")))
9795 (set_attr "amdfam10_decode" "*,double")
9796 (set_attr "bdver1_decode" "*,direct")
9797 (set_attr "prefix" "vex,orig")
9798 (set_attr "mode" "<MODE>")])
9800 ;; Convert mul to the mulx pattern to avoid flags dependency.
9802 [(set (match_operand:<DWI> 0 "register_operand")
9805 (match_operand:DWIH 1 "register_operand"))
9807 (match_operand:DWIH 2 "nonimmediate_operand"))))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "TARGET_BMI2 && reload_completed
9810 && REGNO (operands[1]) == DX_REG"
9811 [(parallel [(set (match_dup 3)
9812 (mult:DWIH (match_dup 1) (match_dup 2)))
9814 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9816 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9818 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9821 (define_insn "*mul<mode><dwi>3_1"
9822 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9825 (match_operand:DWIH 1 "register_operand" "%a"))
9827 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9830 "imul{<imodesuffix>}\t%2"
9831 [(set_attr "type" "imul")
9832 (set_attr "length_immediate" "0")
9833 (set (attr "athlon_decode")
9834 (if_then_else (eq_attr "cpu" "athlon")
9835 (const_string "vector")
9836 (const_string "double")))
9837 (set_attr "amdfam10_decode" "double")
9838 (set_attr "bdver1_decode" "direct")
9839 (set_attr "mode" "<MODE>")])
9841 (define_insn "*<u>mulqihi3_1"
9842 [(set (match_operand:HI 0 "register_operand" "=a")
9845 (match_operand:QI 1 "register_operand" "%0"))
9847 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9848 (clobber (reg:CC FLAGS_REG))]
9850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9851 "<sgnprefix>mul{b}\t%2"
9852 [(set_attr "type" "imul")
9853 (set_attr "length_immediate" "0")
9854 (set (attr "athlon_decode")
9855 (if_then_else (eq_attr "cpu" "athlon")
9856 (const_string "vector")
9857 (const_string "direct")))
9858 (set_attr "amdfam10_decode" "direct")
9859 (set_attr "bdver1_decode" "direct")
9860 (set_attr "mode" "QI")])
9862 ;; Widening multiplication peephole2s to tweak register allocation.
9863 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9865 [(set (match_operand:DWIH 0 "general_reg_operand")
9866 (match_operand:DWIH 1 "immediate_operand"))
9867 (set (match_operand:DWIH 2 "general_reg_operand")
9868 (match_operand:DWIH 3 "general_reg_operand"))
9869 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9870 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9871 (zero_extend:<DWI> (match_dup 0))))
9872 (clobber (reg:CC FLAGS_REG))])]
9873 "REGNO (operands[3]) != AX_REG
9874 && REGNO (operands[0]) != REGNO (operands[2])
9875 && REGNO (operands[0]) != REGNO (operands[3])
9876 && (REGNO (operands[0]) == REGNO (operands[4])
9877 || REGNO (operands[0]) == DX_REG
9878 || peep2_reg_dead_p (3, operands[0]))"
9879 [(set (match_dup 2) (match_dup 1))
9880 (parallel [(set (match_dup 4)
9881 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9882 (zero_extend:<DWI> (match_dup 3))))
9883 (clobber (reg:CC FLAGS_REG))])])
9885 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9887 [(set (match_operand:DWIH 0 "general_reg_operand")
9888 (match_operand:DWIH 1 "immediate_operand"))
9889 (set (match_operand:DWIH 2 "general_reg_operand")
9890 (match_operand:DWIH 3 "general_reg_operand"))
9891 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9892 (mult:DWIH (match_dup 2) (match_dup 0)))
9893 (set (match_operand:DWIH 5 "general_reg_operand")
9894 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9895 "REGNO (operands[3]) != DX_REG
9896 && REGNO (operands[0]) != REGNO (operands[2])
9897 && REGNO (operands[0]) != REGNO (operands[3])
9898 && (REGNO (operands[0]) == REGNO (operands[4])
9899 || REGNO (operands[0]) == REGNO (operands[5])
9900 || peep2_reg_dead_p (3, operands[0]))"
9901 [(set (match_dup 2) (match_dup 1))
9902 (parallel [(set (match_dup 4)
9903 (mult:DWIH (match_dup 2) (match_dup 3)))
9905 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9907 ;; Highpart multiplication patterns
9908 (define_insn "<s>mul<mode>3_highpart"
9909 [(set (match_operand:DWIH 0 "register_operand" "=d")
9910 (any_mul_highpart:DWIH
9911 (match_operand:DWIH 1 "register_operand" "%a")
9912 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9913 (clobber (match_scratch:DWIH 3 "=1"))
9914 (clobber (reg:CC FLAGS_REG))]
9916 "<sgnprefix>mul{<imodesuffix>}\t%2"
9917 [(set_attr "type" "imul")
9918 (set_attr "length_immediate" "0")
9919 (set (attr "athlon_decode")
9920 (if_then_else (eq_attr "cpu" "athlon")
9921 (const_string "vector")
9922 (const_string "double")))
9923 (set_attr "amdfam10_decode" "double")
9924 (set_attr "bdver1_decode" "direct")
9925 (set_attr "mode" "<MODE>")])
9927 (define_insn "*<s>mulsi3_highpart_zext"
9928 [(set (match_operand:DI 0 "register_operand" "=d")
9930 (any_mul_highpart:SI
9931 (match_operand:SI 1 "register_operand" "%a")
9932 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9933 (clobber (match_scratch:SI 3 "=1"))
9934 (clobber (reg:CC FLAGS_REG))]
9936 "<sgnprefix>mul{l}\t%2"
9937 [(set_attr "type" "imul")
9938 (set_attr "length_immediate" "0")
9939 (set (attr "athlon_decode")
9940 (if_then_else (eq_attr "cpu" "athlon")
9941 (const_string "vector")
9942 (const_string "double")))
9943 (set_attr "amdfam10_decode" "double")
9944 (set_attr "bdver1_decode" "direct")
9945 (set_attr "mode" "SI")])
9947 (define_insn "*<s>muldi3_highpart_1"
9948 [(set (match_operand:DI 0 "register_operand" "=d")
9953 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9955 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9957 (clobber (match_scratch:DI 3 "=1"))
9958 (clobber (reg:CC FLAGS_REG))]
9960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9961 "<sgnprefix>mul{q}\t%2"
9962 [(set_attr "type" "imul")
9963 (set_attr "length_immediate" "0")
9964 (set (attr "athlon_decode")
9965 (if_then_else (eq_attr "cpu" "athlon")
9966 (const_string "vector")
9967 (const_string "double")))
9968 (set_attr "amdfam10_decode" "double")
9969 (set_attr "bdver1_decode" "direct")
9970 (set_attr "mode" "DI")])
9972 (define_insn "*<s>mulsi3_highpart_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=d")
9974 (zero_extend:DI (truncate:SI
9976 (mult:DI (any_extend:DI
9977 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9981 (clobber (match_scratch:SI 3 "=1"))
9982 (clobber (reg:CC FLAGS_REG))]
9984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9985 "<sgnprefix>mul{l}\t%2"
9986 [(set_attr "type" "imul")
9987 (set_attr "length_immediate" "0")
9988 (set (attr "athlon_decode")
9989 (if_then_else (eq_attr "cpu" "athlon")
9990 (const_string "vector")
9991 (const_string "double")))
9992 (set_attr "amdfam10_decode" "double")
9993 (set_attr "bdver1_decode" "direct")
9994 (set_attr "mode" "SI")])
9996 (define_insn "*<s>mulsi3_highpart_1"
9997 [(set (match_operand:SI 0 "register_operand" "=d")
10002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10006 (clobber (match_scratch:SI 3 "=1"))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10009 "<sgnprefix>mul{l}\t%2"
10010 [(set_attr "type" "imul")
10011 (set_attr "length_immediate" "0")
10012 (set (attr "athlon_decode")
10013 (if_then_else (eq_attr "cpu" "athlon")
10014 (const_string "vector")
10015 (const_string "double")))
10016 (set_attr "amdfam10_decode" "double")
10017 (set_attr "bdver1_decode" "direct")
10018 (set_attr "mode" "SI")])
10020 ;; Highpart multiplication peephole2s to tweak register allocation.
10021 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10023 [(set (match_operand:SWI48 0 "general_reg_operand")
10024 (match_operand:SWI48 1 "immediate_operand"))
10025 (set (match_operand:SWI48 2 "general_reg_operand")
10026 (match_operand:SWI48 3 "general_reg_operand"))
10027 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10028 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10029 (clobber (match_dup 2))
10030 (clobber (reg:CC FLAGS_REG))])]
10031 "REGNO (operands[3]) != AX_REG
10032 && REGNO (operands[0]) != REGNO (operands[2])
10033 && REGNO (operands[0]) != REGNO (operands[3])
10034 && (REGNO (operands[0]) == REGNO (operands[4])
10035 || peep2_reg_dead_p (3, operands[0]))"
10036 [(set (match_dup 2) (match_dup 1))
10037 (parallel [(set (match_dup 4)
10038 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10039 (clobber (match_dup 2))
10040 (clobber (reg:CC FLAGS_REG))])])
10043 [(set (match_operand:SI 0 "general_reg_operand")
10044 (match_operand:SI 1 "immediate_operand"))
10045 (set (match_operand:SI 2 "general_reg_operand")
10046 (match_operand:SI 3 "general_reg_operand"))
10047 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10049 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10050 (clobber (match_dup 2))
10051 (clobber (reg:CC FLAGS_REG))])]
10053 && REGNO (operands[3]) != AX_REG
10054 && REGNO (operands[0]) != REGNO (operands[2])
10055 && REGNO (operands[2]) != REGNO (operands[3])
10056 && REGNO (operands[0]) != REGNO (operands[3])
10057 && (REGNO (operands[0]) == REGNO (operands[4])
10058 || peep2_reg_dead_p (3, operands[0]))"
10059 [(set (match_dup 2) (match_dup 1))
10060 (parallel [(set (match_dup 4)
10062 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10063 (clobber (match_dup 2))
10064 (clobber (reg:CC FLAGS_REG))])])
10066 ;; The patterns that match these are at the end of this file.
10068 (define_expand "mulxf3"
10069 [(set (match_operand:XF 0 "register_operand")
10070 (mult:XF (match_operand:XF 1 "register_operand")
10071 (match_operand:XF 2 "register_operand")))]
10074 (define_expand "mulhf3"
10075 [(set (match_operand:HF 0 "register_operand")
10076 (mult:HF (match_operand:HF 1 "register_operand")
10077 (match_operand:HF 2 "nonimmediate_operand")))]
10078 "TARGET_AVX512FP16")
10080 (define_expand "mul<mode>3"
10081 [(set (match_operand:MODEF 0 "register_operand")
10082 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10083 (match_operand:MODEF 2 "nonimmediate_operand")))]
10084 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10085 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10087 ;; Divide instructions
10089 ;; The patterns that match these are at the end of this file.
10091 (define_expand "divxf3"
10092 [(set (match_operand:XF 0 "register_operand")
10093 (div:XF (match_operand:XF 1 "register_operand")
10094 (match_operand:XF 2 "register_operand")))]
10097 /* There is no more precision loss than Newton-Rhapson approximation
10098 when using HFmode rcp/rsqrt, so do the transformation directly under
10099 TARGET_RECIP_DIV and fast-math. */
10100 (define_expand "divhf3"
10101 [(set (match_operand:HF 0 "register_operand")
10102 (div:HF (match_operand:HF 1 "register_operand")
10103 (match_operand:HF 2 "nonimmediate_operand")))]
10104 "TARGET_AVX512FP16"
10106 if (TARGET_RECIP_DIV
10107 && optimize_insn_for_speed_p ()
10108 && flag_finite_math_only && !flag_trapping_math
10109 && flag_unsafe_math_optimizations)
10111 rtx op = gen_reg_rtx (HFmode);
10112 operands[2] = force_reg (HFmode, operands[2]);
10113 emit_insn (gen_rcphf2 (op, operands[2]));
10114 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10119 (define_expand "div<mode>3"
10120 [(set (match_operand:MODEF 0 "register_operand")
10121 (div:MODEF (match_operand:MODEF 1 "register_operand")
10122 (match_operand:MODEF 2 "nonimmediate_operand")))]
10123 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10124 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10126 if (<MODE>mode == SFmode
10127 && TARGET_SSE && TARGET_SSE_MATH
10128 && TARGET_RECIP_DIV
10129 && optimize_insn_for_speed_p ()
10130 && flag_finite_math_only && !flag_trapping_math
10131 && flag_unsafe_math_optimizations)
10133 ix86_emit_swdivsf (operands[0], operands[1],
10134 operands[2], SFmode);
10139 ;; Divmod instructions.
10141 (define_code_iterator any_div [div udiv])
10142 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10144 (define_expand "<u>divmod<mode>4"
10145 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10147 (match_operand:SWIM248 1 "register_operand")
10148 (match_operand:SWIM248 2 "nonimmediate_operand")))
10149 (set (match_operand:SWIM248 3 "register_operand")
10150 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10151 (clobber (reg:CC FLAGS_REG))])])
10153 ;; Split with 8bit unsigned divide:
10154 ;; if (dividend an divisor are in [0-255])
10155 ;; use 8bit unsigned integer divide
10157 ;; use original integer divide
10159 [(set (match_operand:SWI48 0 "register_operand")
10160 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10161 (match_operand:SWI48 3 "nonimmediate_operand")))
10162 (set (match_operand:SWI48 1 "register_operand")
10163 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10164 (clobber (reg:CC FLAGS_REG))]
10165 "TARGET_USE_8BIT_IDIV
10166 && TARGET_QIMODE_MATH
10167 && can_create_pseudo_p ()
10168 && !optimize_insn_for_size_p ()"
10170 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10173 [(set (match_operand:DI 0 "register_operand")
10175 (any_div:SI (match_operand:SI 2 "register_operand")
10176 (match_operand:SI 3 "nonimmediate_operand"))))
10177 (set (match_operand:SI 1 "register_operand")
10178 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10179 (clobber (reg:CC FLAGS_REG))]
10181 && TARGET_USE_8BIT_IDIV
10182 && TARGET_QIMODE_MATH
10183 && can_create_pseudo_p ()
10184 && !optimize_insn_for_size_p ()"
10186 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10189 [(set (match_operand:DI 1 "register_operand")
10191 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10192 (match_operand:SI 3 "nonimmediate_operand"))))
10193 (set (match_operand:SI 0 "register_operand")
10194 (any_div:SI (match_dup 2) (match_dup 3)))
10195 (clobber (reg:CC FLAGS_REG))]
10197 && TARGET_USE_8BIT_IDIV
10198 && TARGET_QIMODE_MATH
10199 && can_create_pseudo_p ()
10200 && !optimize_insn_for_size_p ()"
10202 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10204 (define_insn_and_split "divmod<mode>4_1"
10205 [(set (match_operand:SWI48 0 "register_operand" "=a")
10206 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10207 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10208 (set (match_operand:SWI48 1 "register_operand" "=&d")
10209 (mod:SWI48 (match_dup 2) (match_dup 3)))
10210 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10211 (clobber (reg:CC FLAGS_REG))]
10215 [(parallel [(set (match_dup 1)
10216 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10217 (clobber (reg:CC FLAGS_REG))])
10218 (parallel [(set (match_dup 0)
10219 (div:SWI48 (match_dup 2) (match_dup 3)))
10221 (mod:SWI48 (match_dup 2) (match_dup 3)))
10222 (use (match_dup 1))
10223 (clobber (reg:CC FLAGS_REG))])]
10225 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10227 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10228 operands[4] = operands[2];
10231 /* Avoid use of cltd in favor of a mov+shift. */
10232 emit_move_insn (operands[1], operands[2]);
10233 operands[4] = operands[1];
10236 [(set_attr "type" "multi")
10237 (set_attr "mode" "<MODE>")])
10239 (define_insn_and_split "udivmod<mode>4_1"
10240 [(set (match_operand:SWI48 0 "register_operand" "=a")
10241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10242 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10243 (set (match_operand:SWI48 1 "register_operand" "=&d")
10244 (umod:SWI48 (match_dup 2) (match_dup 3)))
10245 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10246 (clobber (reg:CC FLAGS_REG))]
10250 [(set (match_dup 1) (const_int 0))
10251 (parallel [(set (match_dup 0)
10252 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10254 (umod:SWI48 (match_dup 2) (match_dup 3)))
10255 (use (match_dup 1))
10256 (clobber (reg:CC FLAGS_REG))])]
10258 [(set_attr "type" "multi")
10259 (set_attr "mode" "<MODE>")])
10261 (define_insn_and_split "divmodsi4_zext_1"
10262 [(set (match_operand:DI 0 "register_operand" "=a")
10264 (div:SI (match_operand:SI 2 "register_operand" "0")
10265 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10266 (set (match_operand:SI 1 "register_operand" "=&d")
10267 (mod:SI (match_dup 2) (match_dup 3)))
10268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10269 (clobber (reg:CC FLAGS_REG))]
10272 "&& reload_completed"
10273 [(parallel [(set (match_dup 1)
10274 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10275 (clobber (reg:CC FLAGS_REG))])
10276 (parallel [(set (match_dup 0)
10277 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10279 (mod:SI (match_dup 2) (match_dup 3)))
10280 (use (match_dup 1))
10281 (clobber (reg:CC FLAGS_REG))])]
10283 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10285 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10286 operands[4] = operands[2];
10289 /* Avoid use of cltd in favor of a mov+shift. */
10290 emit_move_insn (operands[1], operands[2]);
10291 operands[4] = operands[1];
10294 [(set_attr "type" "multi")
10295 (set_attr "mode" "SI")])
10297 (define_insn_and_split "udivmodsi4_zext_1"
10298 [(set (match_operand:DI 0 "register_operand" "=a")
10300 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10301 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10302 (set (match_operand:SI 1 "register_operand" "=&d")
10303 (umod:SI (match_dup 2) (match_dup 3)))
10304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10305 (clobber (reg:CC FLAGS_REG))]
10308 "&& reload_completed"
10309 [(set (match_dup 1) (const_int 0))
10310 (parallel [(set (match_dup 0)
10311 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10313 (umod:SI (match_dup 2) (match_dup 3)))
10314 (use (match_dup 1))
10315 (clobber (reg:CC FLAGS_REG))])]
10317 [(set_attr "type" "multi")
10318 (set_attr "mode" "SI")])
10320 (define_insn_and_split "divmodsi4_zext_2"
10321 [(set (match_operand:DI 1 "register_operand" "=&d")
10323 (mod:SI (match_operand:SI 2 "register_operand" "0")
10324 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10325 (set (match_operand:SI 0 "register_operand" "=a")
10326 (div:SI (match_dup 2) (match_dup 3)))
10327 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10328 (clobber (reg:CC FLAGS_REG))]
10331 "&& reload_completed"
10332 [(parallel [(set (match_dup 6)
10333 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10334 (clobber (reg:CC FLAGS_REG))])
10335 (parallel [(set (match_dup 1)
10336 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10338 (div:SI (match_dup 2) (match_dup 3)))
10339 (use (match_dup 6))
10340 (clobber (reg:CC FLAGS_REG))])]
10342 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10343 operands[6] = gen_lowpart (SImode, operands[1]);
10345 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10346 operands[4] = operands[2];
10349 /* Avoid use of cltd in favor of a mov+shift. */
10350 emit_move_insn (operands[6], operands[2]);
10351 operands[4] = operands[6];
10354 [(set_attr "type" "multi")
10355 (set_attr "mode" "SI")])
10357 (define_insn_and_split "udivmodsi4_zext_2"
10358 [(set (match_operand:DI 1 "register_operand" "=&d")
10360 (umod:SI (match_operand:SI 2 "register_operand" "0")
10361 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10362 (set (match_operand:SI 0 "register_operand" "=a")
10363 (udiv:SI (match_dup 2) (match_dup 3)))
10364 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10365 (clobber (reg:CC FLAGS_REG))]
10368 "&& reload_completed"
10369 [(set (match_dup 4) (const_int 0))
10370 (parallel [(set (match_dup 1)
10371 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10373 (udiv:SI (match_dup 2) (match_dup 3)))
10374 (use (match_dup 4))
10375 (clobber (reg:CC FLAGS_REG))])]
10376 "operands[4] = gen_lowpart (SImode, operands[1]);"
10377 [(set_attr "type" "multi")
10378 (set_attr "mode" "SI")])
10380 (define_insn_and_split "*divmod<mode>4"
10381 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10382 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10383 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10384 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10385 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10386 (clobber (reg:CC FLAGS_REG))]
10390 [(parallel [(set (match_dup 1)
10391 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10392 (clobber (reg:CC FLAGS_REG))])
10393 (parallel [(set (match_dup 0)
10394 (div:SWIM248 (match_dup 2) (match_dup 3)))
10396 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10397 (use (match_dup 1))
10398 (clobber (reg:CC FLAGS_REG))])]
10400 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10402 if (<MODE>mode != HImode
10403 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10404 operands[4] = operands[2];
10407 /* Avoid use of cltd in favor of a mov+shift. */
10408 emit_move_insn (operands[1], operands[2]);
10409 operands[4] = operands[1];
10412 [(set_attr "type" "multi")
10413 (set_attr "mode" "<MODE>")])
10415 (define_insn_and_split "*udivmod<mode>4"
10416 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10417 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10418 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10419 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10420 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10421 (clobber (reg:CC FLAGS_REG))]
10425 [(set (match_dup 1) (const_int 0))
10426 (parallel [(set (match_dup 0)
10427 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10429 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10430 (use (match_dup 1))
10431 (clobber (reg:CC FLAGS_REG))])]
10433 [(set_attr "type" "multi")
10434 (set_attr "mode" "<MODE>")])
10436 ;; Optimize division or modulo by constant power of 2, if the constant
10437 ;; materializes only after expansion.
10438 (define_insn_and_split "*udivmod<mode>4_pow2"
10439 [(set (match_operand:SWI48 0 "register_operand" "=r")
10440 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10441 (match_operand:SWI48 3 "const_int_operand")))
10442 (set (match_operand:SWI48 1 "register_operand" "=r")
10443 (umod:SWI48 (match_dup 2) (match_dup 3)))
10444 (clobber (reg:CC FLAGS_REG))]
10445 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10447 "&& reload_completed"
10448 [(set (match_dup 1) (match_dup 2))
10449 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10450 (clobber (reg:CC FLAGS_REG))])
10451 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10452 (clobber (reg:CC FLAGS_REG))])]
10454 int v = exact_log2 (UINTVAL (operands[3]));
10455 operands[4] = GEN_INT (v);
10456 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10458 [(set_attr "type" "multi")
10459 (set_attr "mode" "<MODE>")])
10461 (define_insn_and_split "*divmodsi4_zext_1"
10462 [(set (match_operand:DI 0 "register_operand" "=a")
10464 (div:SI (match_operand:SI 2 "register_operand" "0")
10465 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10466 (set (match_operand:SI 1 "register_operand" "=&d")
10467 (mod:SI (match_dup 2) (match_dup 3)))
10468 (clobber (reg:CC FLAGS_REG))]
10471 "&& reload_completed"
10472 [(parallel [(set (match_dup 1)
10473 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10474 (clobber (reg:CC FLAGS_REG))])
10475 (parallel [(set (match_dup 0)
10476 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10478 (mod:SI (match_dup 2) (match_dup 3)))
10479 (use (match_dup 1))
10480 (clobber (reg:CC FLAGS_REG))])]
10482 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10484 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10485 operands[4] = operands[2];
10488 /* Avoid use of cltd in favor of a mov+shift. */
10489 emit_move_insn (operands[1], operands[2]);
10490 operands[4] = operands[1];
10493 [(set_attr "type" "multi")
10494 (set_attr "mode" "SI")])
10496 (define_insn_and_split "*udivmodsi4_zext_1"
10497 [(set (match_operand:DI 0 "register_operand" "=a")
10499 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10500 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10501 (set (match_operand:SI 1 "register_operand" "=&d")
10502 (umod:SI (match_dup 2) (match_dup 3)))
10503 (clobber (reg:CC FLAGS_REG))]
10506 "&& reload_completed"
10507 [(set (match_dup 1) (const_int 0))
10508 (parallel [(set (match_dup 0)
10509 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10511 (umod:SI (match_dup 2) (match_dup 3)))
10512 (use (match_dup 1))
10513 (clobber (reg:CC FLAGS_REG))])]
10515 [(set_attr "type" "multi")
10516 (set_attr "mode" "SI")])
10518 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10519 [(set (match_operand:DI 0 "register_operand" "=r")
10521 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10522 (match_operand:SI 3 "const_int_operand"))))
10523 (set (match_operand:SI 1 "register_operand" "=r")
10524 (umod:SI (match_dup 2) (match_dup 3)))
10525 (clobber (reg:CC FLAGS_REG))]
10527 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10529 "&& reload_completed"
10530 [(set (match_dup 1) (match_dup 2))
10531 (parallel [(set (match_dup 0)
10532 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10533 (clobber (reg:CC FLAGS_REG))])
10534 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10535 (clobber (reg:CC FLAGS_REG))])]
10537 int v = exact_log2 (UINTVAL (operands[3]));
10538 operands[4] = GEN_INT (v);
10539 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10541 [(set_attr "type" "multi")
10542 (set_attr "mode" "SI")])
10544 (define_insn_and_split "*divmodsi4_zext_2"
10545 [(set (match_operand:DI 1 "register_operand" "=&d")
10547 (mod:SI (match_operand:SI 2 "register_operand" "0")
10548 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10549 (set (match_operand:SI 0 "register_operand" "=a")
10550 (div:SI (match_dup 2) (match_dup 3)))
10551 (clobber (reg:CC FLAGS_REG))]
10554 "&& reload_completed"
10555 [(parallel [(set (match_dup 6)
10556 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10557 (clobber (reg:CC FLAGS_REG))])
10558 (parallel [(set (match_dup 1)
10559 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10561 (div:SI (match_dup 2) (match_dup 3)))
10562 (use (match_dup 6))
10563 (clobber (reg:CC FLAGS_REG))])]
10565 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10566 operands[6] = gen_lowpart (SImode, operands[1]);
10568 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10569 operands[4] = operands[2];
10572 /* Avoid use of cltd in favor of a mov+shift. */
10573 emit_move_insn (operands[6], operands[2]);
10574 operands[4] = operands[6];
10577 [(set_attr "type" "multi")
10578 (set_attr "mode" "SI")])
10580 (define_insn_and_split "*udivmodsi4_zext_2"
10581 [(set (match_operand:DI 1 "register_operand" "=&d")
10583 (umod:SI (match_operand:SI 2 "register_operand" "0")
10584 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10585 (set (match_operand:SI 0 "register_operand" "=a")
10586 (udiv:SI (match_dup 2) (match_dup 3)))
10587 (clobber (reg:CC FLAGS_REG))]
10590 "&& reload_completed"
10591 [(set (match_dup 4) (const_int 0))
10592 (parallel [(set (match_dup 1)
10593 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10595 (udiv:SI (match_dup 2) (match_dup 3)))
10596 (use (match_dup 4))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "operands[4] = gen_lowpart (SImode, operands[1]);"
10599 [(set_attr "type" "multi")
10600 (set_attr "mode" "SI")])
10602 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10603 [(set (match_operand:DI 1 "register_operand" "=r")
10605 (umod:SI (match_operand:SI 2 "register_operand" "0")
10606 (match_operand:SI 3 "const_int_operand"))))
10607 (set (match_operand:SI 0 "register_operand" "=r")
10608 (udiv:SI (match_dup 2) (match_dup 3)))
10609 (clobber (reg:CC FLAGS_REG))]
10611 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10613 "&& reload_completed"
10614 [(set (match_dup 1) (match_dup 2))
10615 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10616 (clobber (reg:CC FLAGS_REG))])
10617 (parallel [(set (match_dup 1)
10618 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10619 (clobber (reg:CC FLAGS_REG))])]
10621 int v = exact_log2 (UINTVAL (operands[3]));
10622 operands[4] = GEN_INT (v);
10623 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10625 [(set_attr "type" "multi")
10626 (set_attr "mode" "SI")])
10628 (define_insn "*<u>divmod<mode>4_noext"
10629 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10631 (match_operand:SWIM248 2 "register_operand" "0")
10632 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10633 (set (match_operand:SWIM248 1 "register_operand" "=d")
10634 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10635 (use (match_operand:SWIM248 4 "register_operand" "1"))
10636 (clobber (reg:CC FLAGS_REG))]
10638 "<sgnprefix>div{<imodesuffix>}\t%3"
10639 [(set_attr "type" "idiv")
10640 (set_attr "mode" "<MODE>")])
10642 (define_insn "*<u>divmodsi4_noext_zext_1"
10643 [(set (match_operand:DI 0 "register_operand" "=a")
10645 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10646 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10647 (set (match_operand:SI 1 "register_operand" "=d")
10648 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10649 (use (match_operand:SI 4 "register_operand" "1"))
10650 (clobber (reg:CC FLAGS_REG))]
10652 "<sgnprefix>div{l}\t%3"
10653 [(set_attr "type" "idiv")
10654 (set_attr "mode" "SI")])
10656 (define_insn "*<u>divmodsi4_noext_zext_2"
10657 [(set (match_operand:DI 1 "register_operand" "=d")
10659 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10660 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10661 (set (match_operand:SI 0 "register_operand" "=a")
10662 (any_div:SI (match_dup 2) (match_dup 3)))
10663 (use (match_operand:SI 4 "register_operand" "1"))
10664 (clobber (reg:CC FLAGS_REG))]
10666 "<sgnprefix>div{l}\t%3"
10667 [(set_attr "type" "idiv")
10668 (set_attr "mode" "SI")])
10670 ;; Avoid sign-extension (using cdq) for constant numerators.
10671 (define_insn_and_split "*divmodsi4_const"
10672 [(set (match_operand:SI 0 "register_operand" "=&a")
10673 (div:SI (match_operand:SI 2 "const_int_operand")
10674 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10675 (set (match_operand:SI 1 "register_operand" "=&d")
10676 (mod:SI (match_dup 2) (match_dup 3)))
10677 (clobber (reg:CC FLAGS_REG))]
10678 "!optimize_function_for_size_p (cfun)"
10680 "&& reload_completed"
10681 [(set (match_dup 0) (match_dup 2))
10682 (set (match_dup 1) (match_dup 4))
10683 (parallel [(set (match_dup 0)
10684 (div:SI (match_dup 0) (match_dup 3)))
10686 (mod:SI (match_dup 0) (match_dup 3)))
10687 (use (match_dup 1))
10688 (clobber (reg:CC FLAGS_REG))])]
10690 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10692 [(set_attr "type" "multi")
10693 (set_attr "mode" "SI")])
10695 (define_expand "divmodqi4"
10696 [(parallel [(set (match_operand:QI 0 "register_operand")
10698 (match_operand:QI 1 "register_operand")
10699 (match_operand:QI 2 "nonimmediate_operand")))
10700 (set (match_operand:QI 3 "register_operand")
10701 (mod:QI (match_dup 1) (match_dup 2)))
10702 (clobber (reg:CC FLAGS_REG))])]
10703 "TARGET_QIMODE_MATH"
10708 tmp0 = gen_reg_rtx (HImode);
10709 tmp1 = gen_reg_rtx (HImode);
10711 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10712 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10713 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10715 /* Extract remainder from AH. */
10716 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10717 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10718 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10720 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10721 set_unique_reg_note (insn, REG_EQUAL, mod);
10723 /* Extract quotient from AL. */
10724 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10726 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10727 set_unique_reg_note (insn, REG_EQUAL, div);
10732 (define_expand "udivmodqi4"
10733 [(parallel [(set (match_operand:QI 0 "register_operand")
10735 (match_operand:QI 1 "register_operand")
10736 (match_operand:QI 2 "nonimmediate_operand")))
10737 (set (match_operand:QI 3 "register_operand")
10738 (umod:QI (match_dup 1) (match_dup 2)))
10739 (clobber (reg:CC FLAGS_REG))])]
10740 "TARGET_QIMODE_MATH"
10745 tmp0 = gen_reg_rtx (HImode);
10746 tmp1 = gen_reg_rtx (HImode);
10748 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10749 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10750 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10752 /* Extract remainder from AH. */
10753 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10754 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10755 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10757 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10758 set_unique_reg_note (insn, REG_EQUAL, mod);
10760 /* Extract quotient from AL. */
10761 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10763 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10764 set_unique_reg_note (insn, REG_EQUAL, div);
10769 ;; Divide AX by r/m8, with result stored in
10772 ;; Change div/mod to HImode and extend the second argument to HImode
10773 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10774 ;; combine may fail.
10775 (define_insn "<u>divmodhiqi3"
10776 [(set (match_operand:HI 0 "register_operand" "=a")
10781 (mod:HI (match_operand:HI 1 "register_operand" "0")
10783 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10787 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10788 (clobber (reg:CC FLAGS_REG))]
10789 "TARGET_QIMODE_MATH"
10790 "<sgnprefix>div{b}\t%2"
10791 [(set_attr "type" "idiv")
10792 (set_attr "mode" "QI")])
10794 ;; We cannot use div/idiv for double division, because it causes
10795 ;; "division by zero" on the overflow and that's not what we expect
10796 ;; from truncate. Because true (non truncating) double division is
10797 ;; never generated, we can't create this insn anyway.
10800 ; [(set (match_operand:SI 0 "register_operand" "=a")
10802 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10804 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10805 ; (set (match_operand:SI 3 "register_operand" "=d")
10807 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10808 ; (clobber (reg:CC FLAGS_REG))]
10810 ; "div{l}\t{%2, %0|%0, %2}"
10811 ; [(set_attr "type" "idiv")])
10813 ;;- Logical AND instructions
10815 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10816 ;; Note that this excludes ah.
10818 (define_expand "@test<mode>_ccno_1"
10819 [(set (reg:CCNO FLAGS_REG)
10822 (match_operand:SWI48 0 "nonimmediate_operand")
10823 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10826 (define_expand "testqi_ccz_1"
10827 [(set (reg:CCZ FLAGS_REG)
10830 (match_operand:QI 0 "nonimmediate_operand")
10831 (match_operand:QI 1 "nonmemory_operand"))
10834 (define_insn "*testdi_1"
10835 [(set (reg FLAGS_REG)
10838 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10839 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10842 && ix86_match_ccmode
10844 /* If we are going to emit testl instead of testq, and the operands[1]
10845 constant might have the SImode sign bit set, make sure the sign
10846 flag isn't tested, because the instruction will set the sign flag
10847 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10848 conservatively assume it might have bit 31 set. */
10849 (satisfies_constraint_Z (operands[1])
10850 && (!CONST_INT_P (operands[1])
10851 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10852 ? CCZmode : CCNOmode)"
10854 test{l}\t{%k1, %k0|%k0, %k1}
10855 test{q}\t{%1, %0|%0, %1}"
10856 [(set_attr "type" "test")
10857 (set_attr "mode" "SI,DI")])
10859 (define_insn "*testqi_1_maybe_si"
10860 [(set (reg FLAGS_REG)
10863 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10864 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10866 "ix86_match_ccmode (insn,
10867 CONST_INT_P (operands[1])
10868 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10870 if (get_attr_mode (insn) == MODE_SI)
10872 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10873 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10874 return "test{l}\t{%1, %k0|%k0, %1}";
10876 return "test{b}\t{%1, %0|%0, %1}";
10878 [(set_attr "type" "test")
10880 (cond [(eq_attr "alternative" "2")
10881 (const_string "SI")
10882 (and (match_test "optimize_insn_for_size_p ()")
10883 (and (match_operand 0 "ext_QIreg_operand")
10884 (match_operand 1 "const_0_to_127_operand")))
10885 (const_string "SI")
10887 (const_string "QI")))
10888 (set_attr "pent_pair" "uv,np,np")])
10890 (define_insn "*test<mode>_1"
10891 [(set (reg FLAGS_REG)
10894 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10895 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10897 "ix86_match_ccmode (insn, CCNOmode)"
10898 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10899 [(set_attr "type" "test")
10900 (set_attr "mode" "<MODE>")
10901 (set_attr "pent_pair" "uv,uv,np")])
10903 (define_expand "testqi_ext_1_ccno"
10904 [(set (reg:CCNO FLAGS_REG)
10909 (match_operand:HI 0 "register_operand")
10912 (match_operand:QI 1 "const_int_operand"))
10915 (define_insn "*testqi_ext<mode>_1"
10916 [(set (reg FLAGS_REG)
10920 (match_operator:SWI248 2 "extract_operator"
10921 [(match_operand 0 "int248_register_operand" "Q,Q")
10924 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10926 "ix86_match_ccmode (insn, CCNOmode)"
10927 "test{b}\t{%1, %h0|%h0, %1}"
10928 [(set_attr "isa" "*,nox64")
10929 (set_attr "type" "test")
10930 (set_attr "mode" "QI")])
10932 (define_insn "*testqi_ext<mode>_2"
10933 [(set (reg FLAGS_REG)
10937 (match_operator:SWI248 2 "extract_operator"
10938 [(match_operand 0 "int248_register_operand" "Q")
10942 (match_operator:SWI248 3 "extract_operator"
10943 [(match_operand 1 "int248_register_operand" "Q")
10945 (const_int 8)]) 0))
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 "test{b}\t{%h1, %h0|%h0, %h1}"
10949 [(set_attr "type" "test")
10950 (set_attr "mode" "QI")])
10952 ;; Provide a *testti instruction that STV can implement using ptest.
10953 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10954 (define_insn_and_split "*testti_doubleword"
10955 [(set (reg:CCZ FLAGS_REG)
10957 (and:TI (match_operand:TI 0 "register_operand")
10958 (match_operand:TI 1 "general_operand"))
10961 && ix86_pre_reload_split ()"
10964 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10965 (clobber (reg:CC FLAGS_REG))])
10966 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10968 operands[2] = gen_reg_rtx (TImode);
10969 if (!x86_64_hilo_general_operand (operands[1], TImode))
10970 operands[1] = force_reg (TImode, operands[1]);
10973 ;; Combine likes to form bit extractions for some tests. Humor it.
10974 (define_insn_and_split "*testqi_ext_3"
10975 [(set (match_operand 0 "flags_reg_operand")
10976 (match_operator 1 "compare_operator"
10977 [(zero_extract:SWI248
10978 (match_operand 2 "int_nonimmediate_operand" "rm")
10979 (match_operand:QI 3 "const_int_operand")
10980 (match_operand:QI 4 "const_int_operand"))
10982 "/* Ensure that resulting mask is zero or sign extended operand. */
10983 INTVAL (operands[4]) >= 0
10984 && ((INTVAL (operands[3]) > 0
10985 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10986 || (<MODE>mode == DImode
10987 && INTVAL (operands[3]) > 32
10988 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10989 && ix86_match_ccmode (insn,
10990 /* If zero_extract mode precision is the same
10991 as len, the SF of the zero_extract
10992 comparison will be the most significant
10993 extracted bit, but this could be matched
10994 after splitting only for pos 0 len all bits
10995 trivial extractions. Require CCZmode. */
10996 (GET_MODE_PRECISION (<MODE>mode)
10997 == INTVAL (operands[3]))
10998 /* Otherwise, require CCZmode if we'd use a mask
10999 with the most significant bit set and can't
11000 widen it to wider mode. *testdi_1 also
11001 requires CCZmode if the mask has bit
11002 31 set and all bits above it clear. */
11003 || (INTVAL (operands[3]) + INTVAL (operands[4])
11005 /* We can't widen also if val is not a REG. */
11006 || (INTVAL (operands[3]) + INTVAL (operands[4])
11007 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11008 && !register_operand (operands[2],
11009 GET_MODE (operands[2])))
11010 /* And we shouldn't widen if
11011 TARGET_PARTIAL_REG_STALL. */
11012 || (TARGET_PARTIAL_REG_STALL
11013 && (INTVAL (operands[3]) + INTVAL (operands[4])
11014 >= (paradoxical_subreg_p (operands[2])
11016 (GET_MODE (SUBREG_REG (operands[2])))
11018 ? GET_MODE_PRECISION
11019 (GET_MODE (SUBREG_REG (operands[2])))
11020 : GET_MODE_PRECISION
11021 (GET_MODE (operands[2])))))
11022 ? CCZmode : CCNOmode)"
11025 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11027 rtx val = operands[2];
11028 HOST_WIDE_INT len = INTVAL (operands[3]);
11029 HOST_WIDE_INT pos = INTVAL (operands[4]);
11030 machine_mode mode = GET_MODE (val);
11032 if (SUBREG_P (val))
11034 machine_mode submode = GET_MODE (SUBREG_REG (val));
11036 /* Narrow paradoxical subregs to prevent partial register stalls. */
11037 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11038 && GET_MODE_CLASS (submode) == MODE_INT
11039 && (GET_MODE (operands[0]) == CCZmode
11040 || pos + len < GET_MODE_PRECISION (submode)
11041 || REG_P (SUBREG_REG (val))))
11043 val = SUBREG_REG (val);
11048 /* Small HImode tests can be converted to QImode. */
11050 && register_operand (val, HImode))
11052 rtx nval = gen_lowpart (QImode, val);
11054 || GET_MODE (operands[0]) == CCZmode
11062 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11064 /* If the mask is going to have the sign bit set in the mode
11065 we want to do the comparison in and user isn't interested just
11066 in the zero flag, then we must widen the target mode. */
11067 if (pos + len == GET_MODE_PRECISION (mode)
11068 && GET_MODE (operands[0]) != CCZmode)
11070 gcc_assert (pos + len < 32 && !MEM_P (val));
11072 val = gen_lowpart (mode, val);
11076 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11078 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11081 ;; Split and;cmp (as optimized by combine) into not;test
11082 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11083 (define_insn_and_split "*test<mode>_not"
11084 [(set (reg:CCZ FLAGS_REG)
11087 (not:SWI (match_operand:SWI 0 "register_operand"))
11088 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11090 "ix86_pre_reload_split ()
11091 && (!TARGET_BMI || !REG_P (operands[1]))"
11094 [(set (match_dup 2) (not:SWI (match_dup 0)))
11095 (set (reg:CCZ FLAGS_REG)
11096 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11098 "operands[2] = gen_reg_rtx (<MODE>mode);")
11100 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11101 (define_insn_and_split "*test<mode>_not_doubleword"
11102 [(set (reg:CCZ FLAGS_REG)
11105 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11106 (match_operand:DWI 1 "nonimmediate_operand"))
11108 "ix86_pre_reload_split ()"
11112 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11113 (clobber (reg:CC FLAGS_REG))])
11114 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11116 operands[0] = force_reg (<MODE>mode, operands[0]);
11117 operands[2] = gen_reg_rtx (<MODE>mode);
11120 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11121 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11122 ;; this is relatively important trick.
11123 ;; Do the conversion only post-reload to avoid limiting of the register class
11126 [(set (match_operand 0 "flags_reg_operand")
11127 (match_operator 1 "compare_operator"
11128 [(and (match_operand 2 "QIreg_operand")
11129 (match_operand 3 "const_int_operand"))
11132 && GET_MODE (operands[2]) != QImode
11133 && ((ix86_match_ccmode (insn, CCZmode)
11134 && !(INTVAL (operands[3]) & ~(255 << 8)))
11135 || (ix86_match_ccmode (insn, CCNOmode)
11136 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11137 [(set (match_dup 0)
11141 (zero_extract:HI (match_dup 2)
11147 operands[2] = gen_lowpart (HImode, operands[2]);
11148 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11152 [(set (match_operand 0 "flags_reg_operand")
11153 (match_operator 1 "compare_operator"
11154 [(and (match_operand 2 "nonimmediate_operand")
11155 (match_operand 3 "const_int_operand"))
11158 && GET_MODE (operands[2]) != QImode
11159 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11160 && ((ix86_match_ccmode (insn, CCZmode)
11161 && !(INTVAL (operands[3]) & ~255))
11162 || (ix86_match_ccmode (insn, CCNOmode)
11163 && !(INTVAL (operands[3]) & ~127)))"
11164 [(set (match_dup 0)
11165 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11168 operands[2] = gen_lowpart (QImode, operands[2]);
11169 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11172 ;; Narrow test instructions with immediate operands that test
11173 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11174 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11175 ;; targets where reading (possibly unaligned) part of memory
11176 ;; location after a large write to the same address causes
11177 ;; store-to-load forwarding stall.
11179 [(set (reg:CCZ FLAGS_REG)
11181 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11182 (match_operand 1 "const_int_operand"))
11184 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11185 [(set (reg:CCZ FLAGS_REG)
11186 (compare:CCZ (match_dup 2) (const_int 0)))]
11188 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11189 int first_nonzero_byte, bitsize;
11190 rtx new_addr, new_const;
11191 machine_mode new_mode;
11196 /* Clear bits outside mode width. */
11197 ival &= GET_MODE_MASK (<MODE>mode);
11199 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11201 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11203 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11205 if (bitsize <= GET_MODE_BITSIZE (QImode))
11207 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11209 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11214 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11217 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11218 new_const = gen_int_mode (ival, new_mode);
11220 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11223 ;; %%% This used to optimize known byte-wide and operations to memory,
11224 ;; and sometimes to QImode registers. If this is considered useful,
11225 ;; it should be done with splitters.
11227 (define_expand "and<mode>3"
11228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11229 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11230 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11233 machine_mode mode = <MODE>mode;
11235 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11236 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11237 operands[2] = force_reg (<MODE>mode, operands[2]);
11239 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11240 && const_int_operand (operands[2], <MODE>mode)
11241 && register_operand (operands[0], <MODE>mode)
11242 && !(TARGET_ZERO_EXTEND_WITH_AND
11243 && optimize_function_for_speed_p (cfun)))
11245 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11247 if (ival == GET_MODE_MASK (SImode))
11249 else if (ival == GET_MODE_MASK (HImode))
11251 else if (ival == GET_MODE_MASK (QImode))
11255 if (mode != <MODE>mode)
11256 emit_insn (gen_extend_insn
11257 (operands[0], gen_lowpart (mode, operands[1]),
11258 <MODE>mode, mode, 1));
11260 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11265 (define_insn_and_split "*and<dwi>3_doubleword"
11266 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11268 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11269 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11270 (clobber (reg:CC FLAGS_REG))]
11271 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11273 "&& reload_completed"
11274 [(const_int:DWIH 0)]
11276 bool emit_insn_deleted_note_p = false;
11278 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11280 if (operands[2] == const0_rtx)
11281 emit_move_insn (operands[0], const0_rtx);
11282 else if (operands[2] == constm1_rtx)
11283 emit_insn_deleted_note_p = true;
11285 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11287 if (operands[5] == const0_rtx)
11288 emit_move_insn (operands[3], const0_rtx);
11289 else if (operands[5] == constm1_rtx)
11291 if (emit_insn_deleted_note_p)
11292 emit_note (NOTE_INSN_DELETED);
11295 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11300 (define_insn "*anddi_1"
11301 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11303 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11304 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11305 (clobber (reg:CC FLAGS_REG))]
11306 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11308 and{l}\t{%k2, %k0|%k0, %k2}
11309 and{q}\t{%2, %0|%0, %2}
11310 and{q}\t{%2, %0|%0, %2}
11313 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11314 (set_attr "type" "alu,alu,alu,imovx,msklog")
11315 (set_attr "length_immediate" "*,*,*,0,*")
11316 (set (attr "prefix_rex")
11318 (and (eq_attr "type" "imovx")
11319 (and (match_test "INTVAL (operands[2]) == 0xff")
11320 (match_operand 1 "ext_QIreg_operand")))
11322 (const_string "*")))
11323 (set_attr "mode" "SI,DI,DI,SI,DI")])
11325 (define_insn_and_split "*anddi_1_btr"
11326 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11328 (match_operand:DI 1 "nonimmediate_operand" "%0")
11329 (match_operand:DI 2 "const_int_operand" "n")))
11330 (clobber (reg:CC FLAGS_REG))]
11331 "TARGET_64BIT && TARGET_USE_BT
11332 && ix86_binary_operator_ok (AND, DImode, operands)
11333 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11335 "&& reload_completed"
11336 [(parallel [(set (zero_extract:DI (match_dup 0)
11340 (clobber (reg:CC FLAGS_REG))])]
11341 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11342 [(set_attr "type" "alu1")
11343 (set_attr "prefix_0f" "1")
11344 (set_attr "znver1_decode" "double")
11345 (set_attr "mode" "DI")])
11347 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11349 [(set (match_operand:DI 0 "register_operand")
11350 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11351 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11352 (clobber (reg:CC FLAGS_REG))]
11354 [(parallel [(set (match_dup 0)
11355 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11356 (clobber (reg:CC FLAGS_REG))])]
11358 if (GET_CODE (operands[2]) == SYMBOL_REF
11359 || GET_CODE (operands[2]) == LABEL_REF)
11361 operands[2] = shallow_copy_rtx (operands[2]);
11362 PUT_MODE (operands[2], SImode);
11364 else if (GET_CODE (operands[2]) == CONST)
11366 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11367 operands[2] = copy_rtx (operands[2]);
11368 PUT_MODE (operands[2], SImode);
11369 PUT_MODE (XEXP (operands[2], 0), SImode);
11370 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11373 operands[2] = gen_lowpart (SImode, operands[2]);
11376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11377 (define_insn "*andsi_1_zext"
11378 [(set (match_operand:DI 0 "register_operand" "=r")
11380 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11381 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11382 (clobber (reg:CC FLAGS_REG))]
11383 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11384 "and{l}\t{%2, %k0|%k0, %2}"
11385 [(set_attr "type" "alu")
11386 (set_attr "mode" "SI")])
11388 (define_insn "*and<mode>_1"
11389 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11390 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11391 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11395 and{<imodesuffix>}\t{%2, %0|%0, %2}
11396 and{<imodesuffix>}\t{%2, %0|%0, %2}
11400 (cond [(eq_attr "alternative" "3")
11401 (if_then_else (eq_attr "mode" "SI")
11402 (const_string "avx512bw")
11403 (const_string "avx512f"))
11405 (const_string "*")))
11406 (set_attr "type" "alu,alu,imovx,msklog")
11407 (set_attr "length_immediate" "*,*,0,*")
11408 (set (attr "prefix_rex")
11410 (and (eq_attr "type" "imovx")
11411 (and (match_test "INTVAL (operands[2]) == 0xff")
11412 (match_operand 1 "ext_QIreg_operand")))
11414 (const_string "*")))
11415 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11417 (define_insn "*andqi_1"
11418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11419 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11420 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11421 (clobber (reg:CC FLAGS_REG))]
11422 "ix86_binary_operator_ok (AND, QImode, operands)"
11424 and{b}\t{%2, %0|%0, %2}
11425 and{b}\t{%2, %0|%0, %2}
11426 and{l}\t{%k2, %k0|%k0, %k2}
11428 [(set_attr "type" "alu,alu,alu,msklog")
11430 (cond [(eq_attr "alternative" "2")
11431 (const_string "SI")
11432 (and (eq_attr "alternative" "3")
11433 (match_test "!TARGET_AVX512DQ"))
11434 (const_string "HI")
11436 (const_string "QI")))
11437 ;; Potential partial reg stall on alternative 2.
11438 (set (attr "preferred_for_speed")
11439 (cond [(eq_attr "alternative" "2")
11440 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11441 (symbol_ref "true")))])
11443 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11444 (define_insn_and_split "*and<mode>_1_slp"
11445 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11446 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11447 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11448 (clobber (reg:CC FLAGS_REG))]
11449 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11451 and{<imodesuffix>}\t{%2, %0|%0, %2}
11453 "&& reload_completed"
11454 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11456 [(set (strict_low_part (match_dup 0))
11457 (and:SWI12 (match_dup 0) (match_dup 2)))
11458 (clobber (reg:CC FLAGS_REG))])]
11460 [(set_attr "type" "alu")
11461 (set_attr "mode" "<MODE>")])
11464 [(set (match_operand:SWI248 0 "register_operand")
11465 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11466 (match_operand:SWI248 2 "const_int_operand")))
11467 (clobber (reg:CC FLAGS_REG))]
11469 && (!REG_P (operands[1])
11470 || REGNO (operands[0]) != REGNO (operands[1]))"
11473 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11476 if (ival == GET_MODE_MASK (SImode))
11478 else if (ival == GET_MODE_MASK (HImode))
11480 else if (ival == GET_MODE_MASK (QImode))
11483 gcc_unreachable ();
11485 /* Zero extend to SImode to avoid partial register stalls. */
11486 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11487 operands[0] = gen_lowpart (SImode, operands[0]);
11489 emit_insn (gen_extend_insn
11490 (operands[0], gen_lowpart (mode, operands[1]),
11491 GET_MODE (operands[0]), mode, 1));
11496 [(set (match_operand:SWI48 0 "register_operand")
11497 (and:SWI48 (match_dup 0)
11498 (const_int -65536)))
11499 (clobber (reg:CC FLAGS_REG))]
11500 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11501 || optimize_function_for_size_p (cfun)"
11502 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11503 "operands[1] = gen_lowpart (HImode, operands[0]);")
11506 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11507 (and:SWI248 (match_dup 0)
11509 (clobber (reg:CC FLAGS_REG))]
11510 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11511 && reload_completed"
11512 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11513 "operands[1] = gen_lowpart (QImode, operands[0]);")
11516 [(set (match_operand:SWI248 0 "QIreg_operand")
11517 (and:SWI248 (match_dup 0)
11518 (const_int -65281)))
11519 (clobber (reg:CC FLAGS_REG))]
11520 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11521 && reload_completed"
11523 [(set (zero_extract:HI (match_dup 0)
11529 (zero_extract:HI (match_dup 0)
11533 (zero_extract:HI (match_dup 0)
11535 (const_int 8)) 0)) 0))
11536 (clobber (reg:CC FLAGS_REG))])]
11537 "operands[0] = gen_lowpart (HImode, operands[0]);")
11539 (define_insn "*anddi_2"
11540 [(set (reg FLAGS_REG)
11543 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11544 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11546 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11547 (and:DI (match_dup 1) (match_dup 2)))]
11549 && ix86_match_ccmode
11551 /* If we are going to emit andl instead of andq, and the operands[2]
11552 constant might have the SImode sign bit set, make sure the sign
11553 flag isn't tested, because the instruction will set the sign flag
11554 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11555 conservatively assume it might have bit 31 set. */
11556 (satisfies_constraint_Z (operands[2])
11557 && (!CONST_INT_P (operands[2])
11558 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11559 ? CCZmode : CCNOmode)
11560 && ix86_binary_operator_ok (AND, DImode, operands)"
11562 and{l}\t{%k2, %k0|%k0, %k2}
11563 and{q}\t{%2, %0|%0, %2}
11564 and{q}\t{%2, %0|%0, %2}"
11565 [(set_attr "type" "alu")
11566 (set_attr "mode" "SI,DI,DI")])
11568 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11569 (define_insn "*andsi_2_zext"
11570 [(set (reg FLAGS_REG)
11572 (match_operand:SI 1 "nonimmediate_operand" "%0")
11573 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11575 (set (match_operand:DI 0 "register_operand" "=r")
11576 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11578 && ix86_binary_operator_ok (AND, SImode, operands)"
11579 "and{l}\t{%2, %k0|%k0, %2}"
11580 [(set_attr "type" "alu")
11581 (set_attr "mode" "SI")])
11583 (define_insn "*andqi_2_maybe_si"
11584 [(set (reg FLAGS_REG)
11586 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11587 (match_operand:QI 2 "general_operand" "qn,m,n"))
11589 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11590 (and:QI (match_dup 1) (match_dup 2)))]
11591 "ix86_binary_operator_ok (AND, QImode, operands)
11592 && ix86_match_ccmode (insn,
11593 CONST_INT_P (operands[2])
11594 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11596 if (get_attr_mode (insn) == MODE_SI)
11598 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11599 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11600 return "and{l}\t{%2, %k0|%k0, %2}";
11602 return "and{b}\t{%2, %0|%0, %2}";
11604 [(set_attr "type" "alu")
11606 (cond [(eq_attr "alternative" "2")
11607 (const_string "SI")
11608 (and (match_test "optimize_insn_for_size_p ()")
11609 (and (match_operand 0 "ext_QIreg_operand")
11610 (match_operand 2 "const_0_to_127_operand")))
11611 (const_string "SI")
11613 (const_string "QI")))
11614 ;; Potential partial reg stall on alternative 2.
11615 (set (attr "preferred_for_speed")
11616 (cond [(eq_attr "alternative" "2")
11617 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11618 (symbol_ref "true")))])
11620 (define_insn "*and<mode>_2"
11621 [(set (reg FLAGS_REG)
11622 (compare (and:SWI124
11623 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11624 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11626 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11627 (and:SWI124 (match_dup 1) (match_dup 2)))]
11628 "ix86_match_ccmode (insn, CCNOmode)
11629 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11630 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11631 [(set_attr "type" "alu")
11632 (set_attr "mode" "<MODE>")])
11634 (define_insn "*andqi_ext<mode>_0"
11635 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11638 (match_operator:SWI248 3 "extract_operator"
11639 [(match_operand 2 "int248_register_operand" "Q,Q")
11642 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11643 (clobber (reg:CC FLAGS_REG))]
11645 "and{b}\t{%h2, %0|%0, %h2}"
11646 [(set_attr "isa" "*,nox64")
11647 (set_attr "type" "alu")
11648 (set_attr "mode" "QI")])
11650 (define_expand "andqi_ext_1"
11652 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11658 (zero_extract:HI (match_operand:HI 1 "register_operand")
11661 (match_operand:QI 2 "const_int_operand")) 0))
11662 (clobber (reg:CC FLAGS_REG))])])
11664 (define_insn "*andqi_ext<mode>_1"
11665 [(set (zero_extract:SWI248
11666 (match_operand 0 "int248_register_operand" "+Q,Q")
11672 (match_operator:SWI248 3 "extract_operator"
11673 [(match_operand 1 "int248_register_operand" "0,0")
11676 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11677 (clobber (reg:CC FLAGS_REG))]
11678 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11679 rtx_equal_p (operands[0], operands[1])"
11680 "and{b}\t{%2, %h0|%h0, %2}"
11681 [(set_attr "isa" "*,nox64")
11682 (set_attr "type" "alu")
11683 (set_attr "mode" "QI")])
11685 ;; Generated by peephole translating test to and. This shows up
11686 ;; often in fp comparisons.
11687 (define_insn "*andqi_ext<mode>_1_cc"
11688 [(set (reg FLAGS_REG)
11692 (match_operator:SWI248 3 "extract_operator"
11693 [(match_operand 1 "int248_register_operand" "0,0")
11696 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11698 (set (zero_extract:SWI248
11699 (match_operand 0 "int248_register_operand" "+Q,Q")
11709 (match_dup 2)) 0))]
11710 "ix86_match_ccmode (insn, CCNOmode)
11711 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11712 && rtx_equal_p (operands[0], operands[1])"
11713 "and{b}\t{%2, %h0|%h0, %2}"
11714 [(set_attr "isa" "*,nox64")
11715 (set_attr "type" "alu")
11716 (set_attr "mode" "QI")])
11718 (define_insn "*andqi_ext<mode>_2"
11719 [(set (zero_extract:SWI248
11720 (match_operand 0 "int248_register_operand" "+Q")
11726 (match_operator:SWI248 3 "extract_operator"
11727 [(match_operand 1 "int248_register_operand" "%0")
11731 (match_operator:SWI248 4 "extract_operator"
11732 [(match_operand 2 "int248_register_operand" "Q")
11734 (const_int 8)]) 0)) 0))
11735 (clobber (reg:CC FLAGS_REG))]
11736 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11737 rtx_equal_p (operands[0], operands[1])
11738 || rtx_equal_p (operands[0], operands[2])"
11739 "and{b}\t{%h2, %h0|%h0, %h2}"
11740 [(set_attr "type" "alu")
11741 (set_attr "mode" "QI")])
11743 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11745 ;; Convert wide AND instructions with immediate operand to shorter QImode
11746 ;; equivalents when possible.
11747 ;; Don't do the splitting with memory operands, since it introduces risk
11748 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11749 ;; for size, but that can (should?) be handled by generic code instead.
11751 [(set (match_operand:SWI248 0 "QIreg_operand")
11752 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11753 (match_operand:SWI248 2 "const_int_operand")))
11754 (clobber (reg:CC FLAGS_REG))]
11756 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11757 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11759 [(set (zero_extract:HI (match_dup 0)
11765 (zero_extract:HI (match_dup 1)
11769 (clobber (reg:CC FLAGS_REG))])]
11771 operands[0] = gen_lowpart (HImode, operands[0]);
11772 operands[1] = gen_lowpart (HImode, operands[1]);
11773 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11776 ;; Since AND can be encoded with sign extended immediate, this is only
11777 ;; profitable when 7th bit is not set.
11779 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11780 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11781 (match_operand:SWI248 2 "const_int_operand")))
11782 (clobber (reg:CC FLAGS_REG))]
11784 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11785 && !(~INTVAL (operands[2]) & ~255)
11786 && !(INTVAL (operands[2]) & 128)"
11787 [(parallel [(set (strict_low_part (match_dup 0))
11788 (and:QI (match_dup 1)
11790 (clobber (reg:CC FLAGS_REG))])]
11792 operands[0] = gen_lowpart (QImode, operands[0]);
11793 operands[1] = gen_lowpart (QImode, operands[1]);
11794 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11797 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11798 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11800 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11801 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11802 (clobber (reg:CC FLAGS_REG))]
11805 "&& reload_completed"
11806 [(parallel [(set (match_dup 0)
11807 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11808 (clobber (reg:CC FLAGS_REG))])
11809 (parallel [(set (match_dup 3)
11810 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11811 (clobber (reg:CC FLAGS_REG))])]
11812 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11814 (define_insn_and_split "*andn<mode>3_doubleword"
11815 [(set (match_operand:DWI 0 "register_operand")
11817 (not:DWI (match_operand:DWI 1 "register_operand"))
11818 (match_operand:DWI 2 "nonimmediate_operand")))
11819 (clobber (reg:CC FLAGS_REG))]
11821 && ix86_pre_reload_split ()"
11824 [(set (match_dup 3) (not:DWI (match_dup 1)))
11825 (parallel [(set (match_dup 0)
11826 (and:DWI (match_dup 3) (match_dup 2)))
11827 (clobber (reg:CC FLAGS_REG))])]
11828 "operands[3] = gen_reg_rtx (<MODE>mode);")
11830 (define_insn "*andn<mode>_1"
11831 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11833 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11834 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11835 (clobber (reg:CC FLAGS_REG))]
11837 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11839 andn\t{%2, %1, %0|%0, %1, %2}
11840 andn\t{%2, %1, %0|%0, %1, %2}
11842 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11843 (set_attr "type" "bitmanip,bitmanip,msklog")
11844 (set_attr "btver2_decode" "direct, double,*")
11845 (set_attr "mode" "<MODE>")])
11847 (define_insn "*andn<mode>_1"
11848 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11850 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11851 (match_operand:SWI12 2 "register_operand" "r,k")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "TARGET_BMI || TARGET_AVX512BW"
11855 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11857 [(set_attr "isa" "bmi,avx512f")
11858 (set_attr "type" "bitmanip,msklog")
11859 (set_attr "btver2_decode" "direct,*")
11861 (cond [(eq_attr "alternative" "0")
11862 (const_string "SI")
11863 (and (eq_attr "alternative" "1")
11864 (match_test "!TARGET_AVX512DQ"))
11865 (const_string "HI")
11867 (const_string "<MODE>")))])
11869 (define_insn "*andn_<mode>_ccno"
11870 [(set (reg FLAGS_REG)
11873 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11874 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11876 (clobber (match_scratch:SWI48 0 "=r,r"))]
11877 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11878 "andn\t{%2, %1, %0|%0, %1, %2}"
11879 [(set_attr "type" "bitmanip")
11880 (set_attr "btver2_decode" "direct, double")
11881 (set_attr "mode" "<MODE>")])
11883 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11885 [(set (match_operand:SI 0 "register_operand")
11886 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11887 (match_operand:SI 2 "nonimmediate_operand")))
11888 (clobber (reg:CC FLAGS_REG))]
11890 && optimize_insn_for_size_p () && optimize_size > 1
11891 && REGNO (operands[0]) == REGNO (operands[1])
11892 && LEGACY_INT_REG_P (operands[0])
11893 && !REX_INT_REG_P (operands[2])
11894 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11895 [(set (match_dup 0) (not:SI (match_dup 1)))
11896 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11897 (clobber (reg:CC FLAGS_REG))])])
11899 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11901 [(set (match_operand 0 "flags_reg_operand")
11902 (match_operator 1 "compare_operator"
11903 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11904 (match_operand:SI 3 "nonimmediate_operand"))
11906 (clobber (match_dup 2))]
11908 && optimize_insn_for_size_p () && optimize_size > 1
11909 && LEGACY_INT_REG_P (operands[2])
11910 && !REX_INT_REG_P (operands[3])
11911 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11912 [(set (match_dup 2) (not:SI (match_dup 2)))
11913 (set (match_dup 0) (match_op_dup 1
11914 [(and:SI (match_dup 3) (match_dup 2))
11917 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11919 [(set (match_operand:SWI48 0 "register_operand")
11922 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11923 (match_operand:SWI48 2 "nonimmediate_operand"))
11925 (match_operand:SWI48 3 "nonimmediate_operand")))
11926 (clobber (reg:CC FLAGS_REG))]
11929 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11930 (clobber (reg:CC FLAGS_REG))])
11932 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11933 (clobber (reg:CC FLAGS_REG))])]
11934 "operands[4] = gen_reg_rtx (<MODE>mode);")
11936 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11938 [(set (match_operand:SWI48 0 "register_operand")
11941 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11942 (match_operand:SWI48 2 "register_operand"))
11944 (match_operand:SWI48 3 "nonimmediate_operand")))
11945 (clobber (reg:CC FLAGS_REG))]
11948 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11949 (clobber (reg:CC FLAGS_REG))])
11951 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11952 (clobber (reg:CC FLAGS_REG))])]
11953 "operands[4] = gen_reg_rtx (<MODE>mode);")
11955 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11957 [(set (match_operand:SWI48 0 "register_operand")
11960 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11961 (match_operand:SWI48 2 "nonimmediate_operand"))
11962 (match_operand:SWI48 3 "nonimmediate_operand"))
11964 (clobber (reg:CC FLAGS_REG))]
11967 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11968 (clobber (reg:CC FLAGS_REG))])
11970 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11971 (clobber (reg:CC FLAGS_REG))])]
11972 "operands[4] = gen_reg_rtx (<MODE>mode);")
11974 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11976 [(set (match_operand:SWI48 0 "register_operand")
11979 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11980 (match_operand:SWI48 2 "register_operand"))
11981 (match_operand:SWI48 3 "nonimmediate_operand"))
11983 (clobber (reg:CC FLAGS_REG))]
11986 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11987 (clobber (reg:CC FLAGS_REG))])
11989 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11990 (clobber (reg:CC FLAGS_REG))])]
11991 "operands[4] = gen_reg_rtx (<MODE>mode);")
11993 ;; Logical inclusive and exclusive OR instructions
11995 ;; %%% This used to optimize known byte-wide and operations to memory.
11996 ;; If this is considered useful, it should be done with splitters.
11998 (define_expand "<code><mode>3"
11999 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12000 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12001 (match_operand:SDWIM 2 "<general_operand>")))]
12004 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12005 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12006 operands[2] = force_reg (<MODE>mode, operands[2]);
12008 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12012 (define_insn_and_split "*<code><dwi>3_doubleword"
12013 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12015 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12016 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12020 "&& reload_completed"
12021 [(const_int:DWIH 0)]
12023 /* This insn may disappear completely when operands[2] == const0_rtx
12024 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12025 bool emit_insn_deleted_note_p = false;
12027 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12029 if (operands[2] == const0_rtx)
12030 emit_insn_deleted_note_p = true;
12031 else if (operands[2] == constm1_rtx)
12034 emit_move_insn (operands[0], constm1_rtx);
12036 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12039 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12041 if (operands[5] == const0_rtx)
12043 if (emit_insn_deleted_note_p)
12044 emit_note (NOTE_INSN_DELETED);
12046 else if (operands[5] == constm1_rtx)
12049 emit_move_insn (operands[3], constm1_rtx);
12051 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12054 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12059 (define_insn "*<code><mode>_1"
12060 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12062 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12063 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12064 (clobber (reg:CC FLAGS_REG))]
12065 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12067 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12068 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12070 [(set_attr "isa" "*,*,<kmov_isa>")
12071 (set_attr "type" "alu, alu, msklog")
12072 (set_attr "mode" "<MODE>")])
12074 (define_insn_and_split "*notxor<mode>_1"
12075 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12078 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12079 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12083 "&& reload_completed"
12085 [(set (match_dup 0)
12086 (xor:SWI248 (match_dup 1) (match_dup 2)))
12087 (clobber (reg:CC FLAGS_REG))])
12089 (not:SWI248 (match_dup 0)))]
12091 if (MASK_REG_P (operands[0]))
12093 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12097 [(set_attr "isa" "*,*,<kmov_isa>")
12098 (set_attr "type" "alu, alu, msklog")
12099 (set_attr "mode" "<MODE>")])
12101 (define_insn_and_split "*iordi_1_bts"
12102 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12104 (match_operand:DI 1 "nonimmediate_operand" "%0")
12105 (match_operand:DI 2 "const_int_operand" "n")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "TARGET_64BIT && TARGET_USE_BT
12108 && ix86_binary_operator_ok (IOR, DImode, operands)
12109 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12111 "&& reload_completed"
12112 [(parallel [(set (zero_extract:DI (match_dup 0)
12116 (clobber (reg:CC FLAGS_REG))])]
12117 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12118 [(set_attr "type" "alu1")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "znver1_decode" "double")
12121 (set_attr "mode" "DI")])
12123 (define_insn_and_split "*xordi_1_btc"
12124 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12126 (match_operand:DI 1 "nonimmediate_operand" "%0")
12127 (match_operand:DI 2 "const_int_operand" "n")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "TARGET_64BIT && TARGET_USE_BT
12130 && ix86_binary_operator_ok (XOR, DImode, operands)
12131 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12133 "&& reload_completed"
12134 [(parallel [(set (zero_extract:DI (match_dup 0)
12137 (not:DI (zero_extract:DI (match_dup 0)
12140 (clobber (reg:CC FLAGS_REG))])]
12141 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12142 [(set_attr "type" "alu1")
12143 (set_attr "prefix_0f" "1")
12144 (set_attr "znver1_decode" "double")
12145 (set_attr "mode" "DI")])
12147 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12148 (define_insn_and_split "*xor2andn"
12149 [(set (match_operand:SWI248 0 "register_operand")
12153 (match_operand:SWI248 1 "nonimmediate_operand")
12154 (match_operand:SWI248 2 "nonimmediate_operand"))
12155 (match_operand:SWI248 3 "nonimmediate_operand"))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_BMI && ix86_pre_reload_split ()"
12161 [(parallel [(set (match_dup 4)
12166 (clobber (reg:CC FLAGS_REG))])
12167 (parallel [(set (match_dup 5)
12171 (clobber (reg:CC FLAGS_REG))])
12172 (parallel [(set (match_dup 0)
12176 (clobber (reg:CC FLAGS_REG))])]
12178 operands[1] = force_reg (<MODE>mode, operands[1]);
12179 operands[3] = force_reg (<MODE>mode, operands[3]);
12180 operands[4] = gen_reg_rtx (<MODE>mode);
12181 operands[5] = gen_reg_rtx (<MODE>mode);
12184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12185 (define_insn "*<code>si_1_zext"
12186 [(set (match_operand:DI 0 "register_operand" "=r")
12188 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12189 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12192 "<logic>{l}\t{%2, %k0|%k0, %2}"
12193 [(set_attr "type" "alu")
12194 (set_attr "mode" "SI")])
12196 (define_insn "*<code>si_1_zext_imm"
12197 [(set (match_operand:DI 0 "register_operand" "=r")
12199 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12200 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12203 "<logic>{l}\t{%2, %k0|%k0, %2}"
12204 [(set_attr "type" "alu")
12205 (set_attr "mode" "SI")])
12207 (define_insn "*<code>qi_1"
12208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12209 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12210 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12214 <logic>{b}\t{%2, %0|%0, %2}
12215 <logic>{b}\t{%2, %0|%0, %2}
12216 <logic>{l}\t{%k2, %k0|%k0, %k2}
12218 [(set_attr "isa" "*,*,*,avx512f")
12219 (set_attr "type" "alu,alu,alu,msklog")
12221 (cond [(eq_attr "alternative" "2")
12222 (const_string "SI")
12223 (and (eq_attr "alternative" "3")
12224 (match_test "!TARGET_AVX512DQ"))
12225 (const_string "HI")
12227 (const_string "QI")))
12228 ;; Potential partial reg stall on alternative 2.
12229 (set (attr "preferred_for_speed")
12230 (cond [(eq_attr "alternative" "2")
12231 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12232 (symbol_ref "true")))])
12234 (define_insn_and_split "*notxorqi_1"
12235 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12237 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12238 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12239 (clobber (reg:CC FLAGS_REG))]
12240 "ix86_binary_operator_ok (XOR, QImode, operands)"
12242 "&& reload_completed"
12244 [(set (match_dup 0)
12245 (xor:QI (match_dup 1) (match_dup 2)))
12246 (clobber (reg:CC FLAGS_REG))])
12248 (not:QI (match_dup 0)))]
12250 if (mask_reg_operand (operands[0], QImode))
12252 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12256 [(set_attr "isa" "*,*,*,avx512f")
12257 (set_attr "type" "alu,alu,alu,msklog")
12259 (cond [(eq_attr "alternative" "2")
12260 (const_string "SI")
12261 (and (eq_attr "alternative" "3")
12262 (match_test "!TARGET_AVX512DQ"))
12263 (const_string "HI")
12265 (const_string "QI")))
12266 ;; Potential partial reg stall on alternative 2.
12267 (set (attr "preferred_for_speed")
12268 (cond [(eq_attr "alternative" "2")
12269 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12270 (symbol_ref "true")))])
12272 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12273 (define_insn_and_split "*<code><mode>_1_slp"
12274 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12275 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12276 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12280 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12282 "&& reload_completed"
12283 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12285 [(set (strict_low_part (match_dup 0))
12286 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12287 (clobber (reg:CC FLAGS_REG))])]
12289 [(set_attr "type" "alu")
12290 (set_attr "mode" "<MODE>")])
12292 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12293 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12294 ;; This eliminates sign extension after logic operation.
12297 [(set (match_operand:SWI248 0 "register_operand")
12298 (sign_extend:SWI248
12299 (any_logic:QI (match_operand:QI 1 "memory_operand")
12300 (match_operand:QI 2 "const_int_operand"))))]
12302 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12303 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12304 "operands[3] = gen_reg_rtx (<MODE>mode);")
12307 [(set (match_operand:SWI48 0 "register_operand")
12309 (any_logic:HI (match_operand:HI 1 "memory_operand")
12310 (match_operand:HI 2 "const_int_operand"))))]
12312 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12313 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12314 "operands[3] = gen_reg_rtx (<MODE>mode);")
12317 [(set (match_operand:DI 0 "register_operand")
12319 (any_logic:SI (match_operand:SI 1 "memory_operand")
12320 (match_operand:SI 2 "const_int_operand"))))]
12322 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12323 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12324 "operands[3] = gen_reg_rtx (DImode);")
12326 (define_insn "*<code><mode>_2"
12327 [(set (reg FLAGS_REG)
12328 (compare (any_or:SWI
12329 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12330 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12332 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12333 (any_or:SWI (match_dup 1) (match_dup 2)))]
12334 "ix86_match_ccmode (insn, CCNOmode)
12335 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12336 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12337 [(set_attr "type" "alu")
12338 (set_attr "mode" "<MODE>")])
12340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12341 ;; ??? Special case for immediate operand is missing - it is tricky.
12342 (define_insn "*<code>si_2_zext"
12343 [(set (reg FLAGS_REG)
12344 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12345 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12350 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12351 "<logic>{l}\t{%2, %k0|%k0, %2}"
12352 [(set_attr "type" "alu")
12353 (set_attr "mode" "SI")])
12355 (define_insn "*<code>si_2_zext_imm"
12356 [(set (reg FLAGS_REG)
12357 (compare (any_or:SI
12358 (match_operand:SI 1 "nonimmediate_operand" "%0")
12359 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12361 (set (match_operand:DI 0 "register_operand" "=r")
12362 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12363 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12364 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12365 "<logic>{l}\t{%2, %k0|%k0, %2}"
12366 [(set_attr "type" "alu")
12367 (set_attr "mode" "SI")])
12369 (define_insn "*<code><mode>_3"
12370 [(set (reg FLAGS_REG)
12371 (compare (any_or:SWI
12372 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12373 (match_operand:SWI 2 "<general_operand>" "<g>"))
12375 (clobber (match_scratch:SWI 0 "=<r>"))]
12376 "ix86_match_ccmode (insn, CCNOmode)
12377 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12378 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12379 [(set_attr "type" "alu")
12380 (set_attr "mode" "<MODE>")])
12382 (define_insn "*<code>qi_ext<mode>_0"
12383 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12386 (match_operator:SWI248 3 "extract_operator"
12387 [(match_operand 2 "int248_register_operand" "Q,Q")
12390 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12391 (clobber (reg:CC FLAGS_REG))]
12393 "<logic>{b}\t{%h2, %0|%0, %h2}"
12394 [(set_attr "isa" "*,nox64")
12395 (set_attr "type" "alu")
12396 (set_attr "mode" "QI")])
12398 (define_insn "*<code>qi_ext<mode>_1"
12399 [(set (zero_extract:SWI248
12400 (match_operand 0 "int248_register_operand" "+Q,Q")
12406 (match_operator:SWI248 3 "extract_operator"
12407 [(match_operand 1 "int248_register_operand" "0,0")
12410 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12413 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12414 && rtx_equal_p (operands[0], operands[1])"
12415 "<logic>{b}\t{%2, %h0|%h0, %2}"
12416 [(set_attr "isa" "*,nox64")
12417 (set_attr "type" "alu")
12418 (set_attr "mode" "QI")])
12420 (define_insn "*<code>qi_ext<mode>_2"
12421 [(set (zero_extract:SWI248
12422 (match_operand 0 "int248_register_operand" "+Q")
12428 (match_operator:SWI248 3 "extract_operator"
12429 [(match_operand 1 "int248_register_operand" "%0")
12433 (match_operator:SWI248 4 "extract_operator"
12434 [(match_operand 2 "int248_register_operand" "Q")
12436 (const_int 8)]) 0)) 0))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12439 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12440 && (rtx_equal_p (operands[0], operands[1])
12441 || rtx_equal_p (operands[0], operands[2]))"
12442 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12443 [(set_attr "type" "alu")
12444 (set_attr "mode" "QI")])
12446 (define_insn "*<code>qi_ext<mode>_3"
12447 [(set (zero_extract:SWI248
12448 (match_operand 0 "int248_register_operand" "+Q")
12451 (zero_extract:SWI248
12453 (match_operand 1 "int248_register_operand" "%0")
12454 (match_operand 2 "int248_register_operand" "Q"))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12459 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12460 && (rtx_equal_p (operands[0], operands[1])
12461 || rtx_equal_p (operands[0], operands[2]))"
12462 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12463 [(set_attr "type" "alu")
12464 (set_attr "mode" "QI")])
12466 ;; Convert wide OR instructions with immediate operand to shorter QImode
12467 ;; equivalents when possible.
12468 ;; Don't do the splitting with memory operands, since it introduces risk
12469 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12470 ;; for size, but that can (should?) be handled by generic code instead.
12472 [(set (match_operand:SWI248 0 "QIreg_operand")
12473 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12474 (match_operand:SWI248 2 "const_int_operand")))
12475 (clobber (reg:CC FLAGS_REG))]
12477 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12478 && !(INTVAL (operands[2]) & ~(255 << 8))"
12480 [(set (zero_extract:HI (match_dup 0)
12486 (zero_extract:HI (match_dup 1)
12490 (clobber (reg:CC FLAGS_REG))])]
12492 /* Handle the case where INTVAL (operands[2]) == 0. */
12493 if (operands[2] == const0_rtx)
12495 if (!rtx_equal_p (operands[0], operands[1]))
12496 emit_move_insn (operands[0], operands[1]);
12498 emit_note (NOTE_INSN_DELETED);
12501 operands[0] = gen_lowpart (HImode, operands[0]);
12502 operands[1] = gen_lowpart (HImode, operands[1]);
12503 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12506 ;; Since OR can be encoded with sign extended immediate, this is only
12507 ;; profitable when 7th bit is set.
12509 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12510 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12511 (match_operand:SWI248 2 "const_int_operand")))
12512 (clobber (reg:CC FLAGS_REG))]
12514 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12515 && !(INTVAL (operands[2]) & ~255)
12516 && (INTVAL (operands[2]) & 128)"
12517 [(parallel [(set (strict_low_part (match_dup 0))
12518 (any_or:QI (match_dup 1)
12520 (clobber (reg:CC FLAGS_REG))])]
12522 operands[0] = gen_lowpart (QImode, operands[0]);
12523 operands[1] = gen_lowpart (QImode, operands[1]);
12524 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12527 (define_expand "xorqi_ext_1_cc"
12529 [(set (reg:CCNO FLAGS_REG)
12533 (zero_extract:HI (match_operand:HI 1 "register_operand")
12536 (match_operand:QI 2 "const_int_operand"))
12538 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12544 (zero_extract:HI (match_dup 1)
12547 (match_dup 2)) 0))])])
12549 (define_insn "*xorqi_ext<mode>_1_cc"
12550 [(set (reg FLAGS_REG)
12554 (match_operator:SWI248 3 "extract_operator"
12555 [(match_operand 1 "int248_register_operand" "0,0")
12558 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12560 (set (zero_extract:SWI248
12561 (match_operand 0 "int248_register_operand" "+Q,Q")
12571 (match_dup 2)) 0))]
12572 "ix86_match_ccmode (insn, CCNOmode)
12573 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12574 && rtx_equal_p (operands[0], operands[1])"
12575 "xor{b}\t{%2, %h0|%h0, %2}"
12576 [(set_attr "isa" "*,nox64")
12577 (set_attr "type" "alu")
12578 (set_attr "mode" "QI")])
12580 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12582 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12584 (clobber (reg:CC FLAGS_REG))])
12585 (parallel [(set (match_dup 0)
12586 (any_or_plus:SWI (match_dup 0)
12587 (match_operand:SWI 1 "<general_operand>")))
12588 (clobber (reg:CC FLAGS_REG))])]
12589 "!reg_mentioned_p (operands[0], operands[1])"
12590 [(set (match_dup 0) (match_dup 1))])
12592 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12594 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12596 (clobber (reg:CC FLAGS_REG))])
12597 (parallel [(set (match_dup 0)
12598 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12599 (clobber (reg:CC FLAGS_REG))])]
12601 [(parallel [(set (match_dup 0) (const_int 0))
12602 (clobber (reg:CC FLAGS_REG))])])
12604 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12605 (define_insn_and_split "*concat<mode><dwi>3_1"
12606 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12608 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12609 (match_operand:QI 2 "const_int_operand"))
12611 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12612 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12614 "&& reload_completed"
12617 split_double_concat (<DWI>mode, operands[0], operands[3],
12618 gen_lowpart (<MODE>mode, operands[1]));
12622 (define_insn_and_split "*concat<mode><dwi>3_2"
12623 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12626 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12627 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12628 (match_operand:QI 3 "const_int_operand"))))]
12629 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12631 "&& reload_completed"
12634 split_double_concat (<DWI>mode, operands[0], operands[1],
12635 gen_lowpart (<MODE>mode, operands[2]));
12639 (define_insn_and_split "*concat<mode><dwi>3_3"
12640 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12644 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12645 (match_operand:QI 2 "const_int_operand"))
12647 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12648 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12650 "&& reload_completed"
12653 if (SSE_REG_P (operands[0]))
12655 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12656 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12659 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12662 [(set_attr "isa" "*,*,*,x64,x64")])
12664 (define_insn_and_split "*concat<mode><dwi>3_4"
12665 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12668 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12671 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12672 (match_operand:QI 3 "const_int_operand"))))]
12673 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12675 "&& reload_completed"
12678 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12681 [(set_attr "isa" "*,*,*,x64")])
12683 (define_insn_and_split "*concat<half><mode>3_5"
12684 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12686 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12687 (match_operand:QI 2 "const_int_operand"))
12688 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12689 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12690 && (<MODE>mode == DImode
12691 ? CONST_INT_P (operands[3])
12692 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12693 : CONST_INT_P (operands[3])
12694 ? INTVAL (operands[3]) >= 0
12695 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12696 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12697 && !(CONST_INT_P (operands[3])
12698 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12699 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12703 "&& reload_completed"
12706 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12707 split_double_concat (<MODE>mode, operands[0], op3,
12708 gen_lowpart (<HALF>mode, operands[1]));
12711 [(set_attr "isa" "*,nox64,x64")])
12713 (define_insn_and_split "*concat<mode><dwi>3_6"
12714 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12718 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12719 (match_operand:QI 2 "const_int_operand"))
12720 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12721 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12722 && (<DWI>mode == DImode
12723 ? CONST_INT_P (operands[3])
12724 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12725 : CONST_INT_P (operands[3])
12726 ? INTVAL (operands[3]) >= 0
12727 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12728 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12729 && !(CONST_INT_P (operands[3])
12730 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12731 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12735 "&& reload_completed"
12738 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12739 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12742 [(set_attr "isa" "*,nox64,x64,*")])
12744 (define_insn_and_split "*concat<mode><dwi>3_7"
12745 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12748 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12749 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12750 "<DWI>mode == DImode
12751 ? CONST_INT_P (operands[2])
12752 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12753 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12754 : CONST_WIDE_INT_P (operands[2])
12755 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12756 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12757 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12761 "&& reload_completed"
12765 if (<DWI>mode == DImode)
12766 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12768 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12769 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12772 [(set_attr "isa" "*,nox64,x64,*")])
12774 ;; Negation instructions
12776 (define_expand "neg<mode>2"
12777 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12778 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12780 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12782 (define_insn_and_split "*neg<dwi>2_doubleword"
12783 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12784 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12785 (clobber (reg:CC FLAGS_REG))]
12786 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12788 "&& reload_completed"
12790 [(set (reg:CCC FLAGS_REG)
12791 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12792 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12794 [(set (match_dup 2)
12795 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12798 (clobber (reg:CC FLAGS_REG))])
12800 [(set (match_dup 2)
12801 (neg:DWIH (match_dup 2)))
12802 (clobber (reg:CC FLAGS_REG))])]
12803 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12816 [(set (match_operand:SWI48 0 "general_reg_operand")
12817 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12819 [(set (reg:CCC FLAGS_REG)
12820 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12821 (const_int 0)] UNSPEC_CC_NE))
12822 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12824 [(set (match_dup 0)
12825 (plus:SWI48 (plus:SWI48
12826 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12829 (clobber (reg:CC FLAGS_REG))])
12831 [(set (match_dup 0)
12832 (neg:SWI48 (match_dup 0)))
12833 (clobber (reg:CC FLAGS_REG))])]
12834 "REGNO (operands[0]) != REGNO (operands[2])
12835 && !reg_mentioned_p (operands[0], operands[1])
12836 && !reg_mentioned_p (operands[2], operands[1])"
12838 [(set (reg:CCC FLAGS_REG)
12839 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12840 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12842 [(set (match_dup 0)
12843 (minus:SWI48 (minus:SWI48
12845 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12847 (clobber (reg:CC FLAGS_REG))])]
12848 "ix86_expand_clear (operands[0]);")
12857 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12861 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12862 (clobber (reg:CC FLAGS_REG))])
12864 [(set (reg:CCC FLAGS_REG)
12865 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12866 (const_int 0)] UNSPEC_CC_NE))
12867 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12869 [(set (match_dup 0)
12870 (plus:SWI48 (plus:SWI48
12871 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12874 (clobber (reg:CC FLAGS_REG))])
12876 [(set (match_dup 0)
12877 (neg:SWI48 (match_dup 0)))
12878 (clobber (reg:CC FLAGS_REG))])]
12879 "REGNO (operands[0]) != REGNO (operands[1])"
12881 [(set (reg:CCC FLAGS_REG)
12882 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12883 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12885 [(set (match_dup 0)
12886 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12889 (clobber (reg:CC FLAGS_REG))])])
12891 (define_insn "*neg<mode>_1"
12892 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12893 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12896 "neg{<imodesuffix>}\t%0"
12897 [(set_attr "type" "negnot")
12898 (set_attr "mode" "<MODE>")])
12900 (define_insn "*negsi_1_zext"
12901 [(set (match_operand:DI 0 "register_operand" "=r")
12903 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12907 [(set_attr "type" "negnot")
12908 (set_attr "mode" "SI")])
12910 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12911 (define_insn_and_split "*neg<mode>_1_slp"
12912 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12913 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12917 neg{<imodesuffix>}\t%0
12919 "&& reload_completed"
12920 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12922 [(set (strict_low_part (match_dup 0))
12923 (neg:SWI12 (match_dup 0)))
12924 (clobber (reg:CC FLAGS_REG))])]
12926 [(set_attr "type" "negnot")
12927 (set_attr "mode" "<MODE>")])
12929 (define_insn "*neg<mode>_2"
12930 [(set (reg FLAGS_REG)
12932 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12934 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12935 (neg:SWI (match_dup 1)))]
12936 "ix86_match_ccmode (insn, CCGOCmode)
12937 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12938 "neg{<imodesuffix>}\t%0"
12939 [(set_attr "type" "negnot")
12940 (set_attr "mode" "<MODE>")])
12942 (define_insn "*negsi_2_zext"
12943 [(set (reg FLAGS_REG)
12945 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12947 (set (match_operand:DI 0 "register_operand" "=r")
12949 (neg:SI (match_dup 1))))]
12950 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12951 && ix86_unary_operator_ok (NEG, SImode, operands)"
12953 [(set_attr "type" "negnot")
12954 (set_attr "mode" "SI")])
12956 (define_insn "*neg<mode>_ccc_1"
12957 [(set (reg:CCC FLAGS_REG)
12959 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12960 (const_int 0)] UNSPEC_CC_NE))
12961 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12962 (neg:SWI (match_dup 1)))]
12964 "neg{<imodesuffix>}\t%0"
12965 [(set_attr "type" "negnot")
12966 (set_attr "mode" "<MODE>")])
12968 (define_insn "*neg<mode>_ccc_2"
12969 [(set (reg:CCC FLAGS_REG)
12971 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12972 (const_int 0)] UNSPEC_CC_NE))
12973 (clobber (match_scratch:SWI 0 "=<r>"))]
12975 "neg{<imodesuffix>}\t%0"
12976 [(set_attr "type" "negnot")
12977 (set_attr "mode" "<MODE>")])
12979 (define_expand "x86_neg<mode>_ccc"
12981 [(set (reg:CCC FLAGS_REG)
12982 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12983 (const_int 0)] UNSPEC_CC_NE))
12984 (set (match_operand:SWI48 0 "register_operand")
12985 (neg:SWI48 (match_dup 1)))])])
12987 (define_insn "*negqi_ext<mode>_2"
12988 [(set (zero_extract:SWI248
12989 (match_operand 0 "int248_register_operand" "+Q")
12995 (match_operator:SWI248 2 "extract_operator"
12996 [(match_operand 1 "int248_register_operand" "0")
12998 (const_int 8)]) 0)) 0))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
13001 rtx_equal_p (operands[0], operands[1])"
13003 [(set_attr "type" "negnot")
13004 (set_attr "mode" "QI")])
13006 ;; Negate with jump on overflow.
13007 (define_expand "negv<mode>3"
13008 [(parallel [(set (reg:CCO FLAGS_REG)
13010 [(match_operand:SWI 1 "register_operand")
13011 (match_dup 3)] UNSPEC_CC_NE))
13012 (set (match_operand:SWI 0 "register_operand")
13013 (neg:SWI (match_dup 1)))])
13014 (set (pc) (if_then_else
13015 (eq (reg:CCO FLAGS_REG) (const_int 0))
13016 (label_ref (match_operand 2))
13021 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13025 (define_insn "*negv<mode>3"
13026 [(set (reg:CCO FLAGS_REG)
13027 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13028 (match_operand:SWI 2 "const_int_operand")]
13030 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13031 (neg:SWI (match_dup 1)))]
13032 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13033 && mode_signbit_p (<MODE>mode, operands[2])"
13034 "neg{<imodesuffix>}\t%0"
13035 [(set_attr "type" "negnot")
13036 (set_attr "mode" "<MODE>")])
13038 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13040 [(set (match_operand:SWI 0 "general_reg_operand")
13041 (match_operand:SWI 1 "general_reg_operand"))
13042 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13043 (clobber (reg:CC FLAGS_REG))])
13044 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13046 [(set (match_dup 0) (match_dup 1))
13047 (parallel [(set (reg:CCZ FLAGS_REG)
13048 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13049 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13051 ;; Special expand pattern to handle integer mode abs
13053 (define_expand "abs<mode>2"
13055 [(set (match_operand:SDWIM 0 "register_operand")
13057 (match_operand:SDWIM 1 "general_operand")))
13058 (clobber (reg:CC FLAGS_REG))])]
13060 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13062 if (TARGET_EXPAND_ABS)
13064 machine_mode mode = <MODE>mode;
13065 operands[1] = force_reg (mode, operands[1]);
13067 /* Generate rtx abs using:
13068 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13070 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13071 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13072 shift_amount, NULL_RTX,
13074 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13075 operands[0], 0, OPTAB_DIRECT);
13076 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13077 operands[0], 0, OPTAB_DIRECT);
13078 if (!rtx_equal_p (minus_dst, operands[0]))
13079 emit_move_insn (operands[0], minus_dst);
13084 (define_insn_and_split "*abs<dwi>2_doubleword"
13085 [(set (match_operand:<DWI> 0 "register_operand")
13087 (match_operand:<DWI> 1 "general_operand")))
13088 (clobber (reg:CC FLAGS_REG))]
13090 && ix86_pre_reload_split ()"
13094 [(set (reg:CCC FLAGS_REG)
13095 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13096 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13098 [(set (match_dup 5)
13099 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13102 (clobber (reg:CC FLAGS_REG))])
13104 [(set (reg:CCGOC FLAGS_REG)
13106 (neg:DWIH (match_dup 5))
13109 (neg:DWIH (match_dup 5)))])
13112 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13117 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13121 operands[1] = force_reg (<DWI>mode, operands[1]);
13122 operands[2] = gen_reg_rtx (<DWI>mode);
13124 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13127 (define_insn_and_split "*nabs<dwi>2_doubleword"
13128 [(set (match_operand:<DWI> 0 "register_operand")
13131 (match_operand:<DWI> 1 "general_operand"))))
13132 (clobber (reg:CC FLAGS_REG))]
13134 && ix86_pre_reload_split ()"
13138 [(set (reg:CCC FLAGS_REG)
13139 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13140 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13142 [(set (match_dup 5)
13143 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13146 (clobber (reg:CC FLAGS_REG))])
13148 [(set (reg:CCGOC FLAGS_REG)
13150 (neg:DWIH (match_dup 5))
13153 (neg:DWIH (match_dup 5)))])
13156 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13161 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13165 operands[1] = force_reg (<DWI>mode, operands[1]);
13166 operands[2] = gen_reg_rtx (<DWI>mode);
13168 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13171 (define_insn_and_split "*abs<mode>2_1"
13172 [(set (match_operand:SWI 0 "register_operand")
13174 (match_operand:SWI 1 "general_operand")))
13175 (clobber (reg:CC FLAGS_REG))]
13177 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13178 && ix86_pre_reload_split ()"
13182 [(set (reg:CCGOC FLAGS_REG)
13184 (neg:SWI (match_dup 1))
13187 (neg:SWI (match_dup 1)))])
13190 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13194 operands[1] = force_reg (<MODE>mode, operands[1]);
13195 operands[2] = gen_reg_rtx (<MODE>mode);
13198 (define_insn_and_split "*nabs<mode>2_1"
13199 [(set (match_operand:SWI 0 "register_operand")
13202 (match_operand:SWI 1 "general_operand"))))
13203 (clobber (reg:CC FLAGS_REG))]
13205 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13206 && ix86_pre_reload_split ()"
13210 [(set (reg:CCGOC FLAGS_REG)
13212 (neg:SWI (match_dup 1))
13215 (neg:SWI (match_dup 1)))])
13218 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13222 operands[1] = force_reg (<MODE>mode, operands[1]);
13223 operands[2] = gen_reg_rtx (<MODE>mode);
13226 (define_expand "<code>tf2"
13227 [(set (match_operand:TF 0 "register_operand")
13228 (absneg:TF (match_operand:TF 1 "register_operand")))]
13230 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13232 (define_insn_and_split "*<code>tf2_1"
13233 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13235 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13236 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13239 "&& reload_completed"
13240 [(set (match_dup 0)
13241 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13245 if (MEM_P (operands[1]))
13246 std::swap (operands[1], operands[2]);
13250 if (operands_match_p (operands[0], operands[2]))
13251 std::swap (operands[1], operands[2]);
13254 [(set_attr "isa" "noavx,noavx,avx,avx")])
13256 (define_insn_and_split "*nabstf2_1"
13257 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13260 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13261 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13264 "&& reload_completed"
13265 [(set (match_dup 0)
13266 (ior:TF (match_dup 1) (match_dup 2)))]
13270 if (MEM_P (operands[1]))
13271 std::swap (operands[1], operands[2]);
13275 if (operands_match_p (operands[0], operands[2]))
13276 std::swap (operands[1], operands[2]);
13279 [(set_attr "isa" "noavx,noavx,avx,avx")])
13281 (define_expand "<code>hf2"
13282 [(set (match_operand:HF 0 "register_operand")
13283 (absneg:HF (match_operand:HF 1 "register_operand")))]
13284 "TARGET_AVX512FP16"
13285 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13287 (define_expand "<code><mode>2"
13288 [(set (match_operand:X87MODEF 0 "register_operand")
13289 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13290 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13291 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13293 ;; Changing of sign for FP values is doable using integer unit too.
13294 (define_insn "*<code><mode>2_i387_1"
13295 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13297 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13298 (clobber (reg:CC FLAGS_REG))]
13299 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13303 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13304 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13305 (clobber (reg:CC FLAGS_REG))]
13306 "TARGET_80387 && reload_completed"
13307 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13310 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13311 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13312 (clobber (reg:CC FLAGS_REG))]
13313 "TARGET_80387 && reload_completed"
13315 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13317 (define_insn_and_split "*<code>hf2_1"
13318 [(set (match_operand:HF 0 "register_operand" "=Yv")
13320 (match_operand:HF 1 "register_operand" "Yv")))
13321 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13322 (clobber (reg:CC FLAGS_REG))]
13323 "TARGET_AVX512FP16"
13325 "&& reload_completed"
13326 [(set (match_dup 0)
13327 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13329 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13330 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13333 (define_insn "*<code><mode>2_1"
13334 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13336 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13337 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13338 (clobber (reg:CC FLAGS_REG))]
13339 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13341 [(set_attr "isa" "noavx,noavx,avx,*,*")
13342 (set (attr "enabled")
13344 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13346 (eq_attr "alternative" "3,4")
13347 (symbol_ref "TARGET_MIX_SSE_I387")
13348 (const_string "*"))
13350 (eq_attr "alternative" "3,4")
13351 (symbol_ref "true")
13352 (symbol_ref "false"))))])
13355 [(set (match_operand:MODEF 0 "sse_reg_operand")
13357 (match_operand:MODEF 1 "sse_reg_operand")))
13358 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13359 (clobber (reg:CC FLAGS_REG))]
13360 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13361 && reload_completed"
13362 [(set (match_dup 0)
13363 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13365 machine_mode mode = <MODE>mode;
13366 machine_mode vmode = <ssevecmodef>mode;
13368 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13369 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13371 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13372 std::swap (operands[1], operands[2]);
13376 [(set (match_operand:MODEF 0 "fp_register_operand")
13377 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13378 (use (match_operand 2))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "TARGET_80387 && reload_completed"
13381 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13384 [(set (match_operand:MODEF 0 "general_reg_operand")
13385 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13386 (use (match_operand 2))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_80387 && reload_completed"
13390 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13392 (define_insn_and_split "*nabs<mode>2_1"
13393 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13396 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13397 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13398 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13400 "&& reload_completed"
13401 [(set (match_dup 0)
13402 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13404 machine_mode mode = <MODE>mode;
13405 machine_mode vmode = <ssevecmodef>mode;
13407 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13408 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13410 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13411 std::swap (operands[1], operands[2]);
13413 [(set_attr "isa" "noavx,noavx,avx")])
13415 ;; Conditionalize these after reload. If they match before reload, we
13416 ;; lose the clobber and ability to use integer instructions.
13418 (define_insn "*<code><mode>2_i387"
13419 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13420 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13421 "TARGET_80387 && reload_completed"
13422 "<absneg_mnemonic>"
13423 [(set_attr "type" "fsgn")
13424 (set_attr "mode" "<MODE>")])
13426 ;; Copysign instructions
13428 (define_expand "copysign<mode>3"
13429 [(match_operand:SSEMODEF 0 "register_operand")
13430 (match_operand:SSEMODEF 1 "nonmemory_operand")
13431 (match_operand:SSEMODEF 2 "register_operand")]
13432 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13433 || (TARGET_SSE && (<MODE>mode == TFmode))
13434 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13435 "ix86_expand_copysign (operands); DONE;")
13437 (define_expand "xorsign<mode>3"
13438 [(match_operand:MODEFH 0 "register_operand")
13439 (match_operand:MODEFH 1 "register_operand")
13440 (match_operand:MODEFH 2 "register_operand")]
13441 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13442 || <MODE>mode == HFmode"
13444 if (rtx_equal_p (operands[1], operands[2]))
13445 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13447 ix86_expand_xorsign (operands);
13451 ;; One complement instructions
13453 (define_expand "one_cmpl<mode>2"
13454 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13455 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13457 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13459 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13460 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13461 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13462 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13464 "&& reload_completed"
13465 [(set (match_dup 0)
13466 (not:DWIH (match_dup 1)))
13468 (not:DWIH (match_dup 3)))]
13469 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13471 (define_insn "*one_cmpl<mode>2_1"
13472 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13473 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13474 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13476 not{<imodesuffix>}\t%0
13478 [(set_attr "isa" "*,<kmov_isa>")
13479 (set_attr "type" "negnot,msklog")
13480 (set_attr "mode" "<MODE>")])
13482 (define_insn "*one_cmplsi2_1_zext"
13483 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13485 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13486 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13490 [(set_attr "isa" "x64,avx512bw_512")
13491 (set_attr "type" "negnot,msklog")
13492 (set_attr "mode" "SI,SI")])
13494 (define_insn "*one_cmplqi2_1"
13495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13496 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13497 "ix86_unary_operator_ok (NOT, QImode, operands)"
13502 [(set_attr "isa" "*,*,avx512f")
13503 (set_attr "type" "negnot,negnot,msklog")
13505 (cond [(eq_attr "alternative" "1")
13506 (const_string "SI")
13507 (and (eq_attr "alternative" "2")
13508 (match_test "!TARGET_AVX512DQ"))
13509 (const_string "HI")
13511 (const_string "QI")))
13512 ;; Potential partial reg stall on alternative 1.
13513 (set (attr "preferred_for_speed")
13514 (cond [(eq_attr "alternative" "1")
13515 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13516 (symbol_ref "true")))])
13518 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13519 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13520 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13521 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13522 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13524 not{<imodesuffix>}\t%0
13526 "&& reload_completed"
13527 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13528 (set (strict_low_part (match_dup 0))
13529 (not:SWI12 (match_dup 0)))]
13531 [(set_attr "type" "negnot")
13532 (set_attr "mode" "<MODE>")])
13534 (define_insn "*one_cmpl<mode>2_2"
13535 [(set (reg FLAGS_REG)
13536 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13539 (not:SWI (match_dup 1)))]
13540 "ix86_match_ccmode (insn, CCNOmode)
13541 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13543 [(set_attr "type" "alu1")
13544 (set_attr "mode" "<MODE>")])
13547 [(set (match_operand 0 "flags_reg_operand")
13548 (match_operator 2 "compare_operator"
13549 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13551 (set (match_operand:SWI 1 "nonimmediate_operand")
13552 (not:SWI (match_dup 3)))]
13553 "ix86_match_ccmode (insn, CCNOmode)"
13554 [(parallel [(set (match_dup 0)
13555 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13558 (xor:SWI (match_dup 3) (const_int -1)))])])
13560 (define_insn "*one_cmplsi2_2_zext"
13561 [(set (reg FLAGS_REG)
13562 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13564 (set (match_operand:DI 0 "register_operand" "=r")
13565 (zero_extend:DI (not:SI (match_dup 1))))]
13566 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13567 && ix86_unary_operator_ok (NOT, SImode, operands)"
13569 [(set_attr "type" "alu1")
13570 (set_attr "mode" "SI")])
13573 [(set (match_operand 0 "flags_reg_operand")
13574 (match_operator 2 "compare_operator"
13575 [(not:SI (match_operand:SI 3 "register_operand"))
13577 (set (match_operand:DI 1 "register_operand")
13578 (zero_extend:DI (not:SI (match_dup 3))))]
13579 "ix86_match_ccmode (insn, CCNOmode)"
13580 [(parallel [(set (match_dup 0)
13581 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13584 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13586 ;; Shift instructions
13588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13591 ;; from the assembler input.
13593 ;; This instruction shifts the target reg/mem as usual, but instead of
13594 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13595 ;; is a left shift double, bits are taken from the high order bits of
13596 ;; reg, else if the insn is a shift right double, bits are taken from the
13597 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13600 ;; Since sh[lr]d does not change the `reg' operand, that is done
13601 ;; separately, making all shifts emit pairs of shift double and normal
13602 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13603 ;; support a 63 bit shift, each shift where the count is in a reg expands
13604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13606 ;; If the shift count is a constant, we need never emit more than one
13607 ;; shift pair, instead using moves and sign extension for counts greater
13610 (define_expand "ashl<mode>3"
13611 [(set (match_operand:SDWIM 0 "<shift_operand>")
13612 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13613 (match_operand:QI 2 "nonmemory_operand")))]
13615 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13617 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13618 [(set (match_operand:<DWI> 0 "register_operand")
13620 (match_operand:<DWI> 1 "register_operand")
13623 (match_operand 2 "int248_register_operand" "c")
13624 (match_operand 3 "const_int_operand")) 0)))
13625 (clobber (reg:CC FLAGS_REG))]
13626 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13627 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13628 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13629 && ix86_pre_reload_split ()"
13633 [(set (match_dup 6)
13634 (ior:DWIH (ashift:DWIH (match_dup 6)
13635 (and:QI (match_dup 2) (match_dup 8)))
13637 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13638 (minus:QI (match_dup 9)
13639 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13640 (clobber (reg:CC FLAGS_REG))])
13642 [(set (match_dup 4)
13643 (ashift:DWIH (match_dup 5) (match_dup 2)))
13644 (clobber (reg:CC FLAGS_REG))])]
13646 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13648 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13649 operands[2] = gen_lowpart (QImode, operands[2]);
13650 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13655 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13657 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13658 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13660 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13661 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13664 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13665 xops[1] = operands[2];
13666 xops[2] = GEN_INT (INTVAL (operands[3])
13667 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13668 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13669 operands[2] = xops[0];
13672 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13673 operands[2] = gen_lowpart (QImode, operands[2]);
13675 if (!rtx_equal_p (operands[6], operands[7]))
13676 emit_move_insn (operands[6], operands[7]);
13679 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13680 [(set (match_operand:<DWI> 0 "register_operand")
13682 (match_operand:<DWI> 1 "register_operand")
13684 (match_operand:QI 2 "register_operand" "c")
13685 (match_operand:QI 3 "const_int_operand"))))
13686 (clobber (reg:CC FLAGS_REG))]
13687 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13688 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13689 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13690 && ix86_pre_reload_split ()"
13694 [(set (match_dup 6)
13695 (ior:DWIH (ashift:DWIH (match_dup 6)
13696 (and:QI (match_dup 2) (match_dup 8)))
13698 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13699 (minus:QI (match_dup 9)
13700 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13701 (clobber (reg:CC FLAGS_REG))])
13703 [(set (match_dup 4)
13704 (ashift:DWIH (match_dup 5) (match_dup 2)))
13705 (clobber (reg:CC FLAGS_REG))])]
13707 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13709 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13714 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13716 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13717 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13719 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13720 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13722 rtx tem = gen_reg_rtx (QImode);
13723 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13727 if (!rtx_equal_p (operands[6], operands[7]))
13728 emit_move_insn (operands[6], operands[7]);
13731 (define_insn "ashl<mode>3_doubleword"
13732 [(set (match_operand:DWI 0 "register_operand" "=&r")
13733 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13734 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13735 (clobber (reg:CC FLAGS_REG))]
13738 [(set_attr "type" "multi")])
13741 [(set (match_operand:DWI 0 "register_operand")
13742 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13743 (match_operand:QI 2 "nonmemory_operand")))
13744 (clobber (reg:CC FLAGS_REG))]
13745 "epilogue_completed"
13747 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13749 ;; By default we don't ask for a scratch register, because when DWImode
13750 ;; values are manipulated, registers are already at a premium. But if
13751 ;; we have one handy, we won't turn it away.
13754 [(match_scratch:DWIH 3 "r")
13755 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13757 (match_operand:<DWI> 1 "nonmemory_operand")
13758 (match_operand:QI 2 "nonmemory_operand")))
13759 (clobber (reg:CC FLAGS_REG))])
13763 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13765 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13766 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13768 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13769 (match_operand:QI 2 "const_int_operand")))
13770 (clobber (reg:CC FLAGS_REG))]
13771 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13772 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13774 "&& reload_completed"
13777 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13778 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13779 if (!rtx_equal_p (operands[3], operands[1]))
13780 emit_move_insn (operands[3], operands[1]);
13782 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13783 ix86_expand_clear (operands[0]);
13787 (define_insn "x86_64_shld"
13788 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13789 (ior:DI (ashift:DI (match_dup 0)
13790 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13795 (match_operand:DI 1 "register_operand" "r"))
13796 (minus:QI (const_int 64)
13797 (and:QI (match_dup 2) (const_int 63)))) 0)))
13798 (clobber (reg:CC FLAGS_REG))]
13800 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13801 [(set_attr "type" "ishift")
13802 (set_attr "prefix_0f" "1")
13803 (set_attr "mode" "DI")
13804 (set_attr "athlon_decode" "vector")
13805 (set_attr "amdfam10_decode" "vector")
13806 (set_attr "bdver1_decode" "vector")])
13808 (define_insn "x86_64_shld_1"
13809 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13810 (ior:DI (ashift:DI (match_dup 0)
13811 (match_operand:QI 2 "const_0_to_63_operand"))
13815 (match_operand:DI 1 "register_operand" "r"))
13816 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13817 (clobber (reg:CC FLAGS_REG))]
13819 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13820 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13821 [(set_attr "type" "ishift")
13822 (set_attr "prefix_0f" "1")
13823 (set_attr "mode" "DI")
13824 (set_attr "length_immediate" "1")
13825 (set_attr "athlon_decode" "vector")
13826 (set_attr "amdfam10_decode" "vector")
13827 (set_attr "bdver1_decode" "vector")])
13829 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13830 [(set (match_operand:DI 0 "nonimmediate_operand")
13831 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13832 (match_operand:QI 2 "const_0_to_63_operand"))
13834 (match_operand:DI 1 "nonimmediate_operand")
13835 (match_operand:QI 3 "const_0_to_63_operand"))))
13836 (clobber (reg:CC FLAGS_REG))]
13838 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13839 && ix86_pre_reload_split ()"
13844 if (rtx_equal_p (operands[4], operands[0]))
13846 operands[1] = force_reg (DImode, operands[1]);
13847 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13849 else if (rtx_equal_p (operands[1], operands[0]))
13851 operands[4] = force_reg (DImode, operands[4]);
13852 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13856 operands[1] = force_reg (DImode, operands[1]);
13857 rtx tmp = gen_reg_rtx (DImode);
13858 emit_move_insn (tmp, operands[4]);
13859 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13860 emit_move_insn (operands[0], tmp);
13865 (define_insn_and_split "*x86_64_shld_2"
13866 [(set (match_operand:DI 0 "nonimmediate_operand")
13867 (ior:DI (ashift:DI (match_dup 0)
13868 (match_operand:QI 2 "nonmemory_operand"))
13869 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13870 (minus:QI (const_int 64) (match_dup 2)))))
13871 (clobber (reg:CC FLAGS_REG))]
13872 "TARGET_64BIT && ix86_pre_reload_split ()"
13875 [(parallel [(set (match_dup 0)
13876 (ior:DI (ashift:DI (match_dup 0)
13877 (and:QI (match_dup 2) (const_int 63)))
13880 (zero_extend:TI (match_dup 1))
13881 (minus:QI (const_int 64)
13882 (and:QI (match_dup 2)
13883 (const_int 63)))) 0)))
13884 (clobber (reg:CC FLAGS_REG))])])
13886 (define_insn "x86_shld"
13887 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13888 (ior:SI (ashift:SI (match_dup 0)
13889 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13894 (match_operand:SI 1 "register_operand" "r"))
13895 (minus:QI (const_int 32)
13896 (and:QI (match_dup 2) (const_int 31)))) 0)))
13897 (clobber (reg:CC FLAGS_REG))]
13899 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13900 [(set_attr "type" "ishift")
13901 (set_attr "prefix_0f" "1")
13902 (set_attr "mode" "SI")
13903 (set_attr "pent_pair" "np")
13904 (set_attr "athlon_decode" "vector")
13905 (set_attr "amdfam10_decode" "vector")
13906 (set_attr "bdver1_decode" "vector")])
13908 (define_insn "x86_shld_1"
13909 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13910 (ior:SI (ashift:SI (match_dup 0)
13911 (match_operand:QI 2 "const_0_to_31_operand"))
13915 (match_operand:SI 1 "register_operand" "r"))
13916 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13917 (clobber (reg:CC FLAGS_REG))]
13918 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13919 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13920 [(set_attr "type" "ishift")
13921 (set_attr "prefix_0f" "1")
13922 (set_attr "length_immediate" "1")
13923 (set_attr "mode" "SI")
13924 (set_attr "pent_pair" "np")
13925 (set_attr "athlon_decode" "vector")
13926 (set_attr "amdfam10_decode" "vector")
13927 (set_attr "bdver1_decode" "vector")])
13929 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13930 [(set (match_operand:SI 0 "nonimmediate_operand")
13931 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13932 (match_operand:QI 2 "const_0_to_31_operand"))
13934 (match_operand:SI 1 "nonimmediate_operand")
13935 (match_operand:QI 3 "const_0_to_31_operand"))))
13936 (clobber (reg:CC FLAGS_REG))]
13937 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13938 && ix86_pre_reload_split ()"
13943 if (rtx_equal_p (operands[4], operands[0]))
13945 operands[1] = force_reg (SImode, operands[1]);
13946 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13948 else if (rtx_equal_p (operands[1], operands[0]))
13950 operands[4] = force_reg (SImode, operands[4]);
13951 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13955 operands[1] = force_reg (SImode, operands[1]);
13956 rtx tmp = gen_reg_rtx (SImode);
13957 emit_move_insn (tmp, operands[4]);
13958 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13959 emit_move_insn (operands[0], tmp);
13964 (define_insn_and_split "*x86_shld_2"
13965 [(set (match_operand:SI 0 "nonimmediate_operand")
13966 (ior:SI (ashift:SI (match_dup 0)
13967 (match_operand:QI 2 "nonmemory_operand"))
13968 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13969 (minus:QI (const_int 32) (match_dup 2)))))
13970 (clobber (reg:CC FLAGS_REG))]
13971 "TARGET_64BIT && ix86_pre_reload_split ()"
13974 [(parallel [(set (match_dup 0)
13975 (ior:SI (ashift:SI (match_dup 0)
13976 (and:QI (match_dup 2) (const_int 31)))
13979 (zero_extend:DI (match_dup 1))
13980 (minus:QI (const_int 32)
13981 (and:QI (match_dup 2)
13982 (const_int 31)))) 0)))
13983 (clobber (reg:CC FLAGS_REG))])])
13985 (define_expand "@x86_shift<mode>_adj_1"
13986 [(set (reg:CCZ FLAGS_REG)
13987 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13990 (set (match_operand:SWI48 0 "register_operand")
13991 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13992 (match_operand:SWI48 1 "register_operand")
13995 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13996 (match_operand:SWI48 3 "register_operand")
13999 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14001 (define_expand "@x86_shift<mode>_adj_2"
14002 [(use (match_operand:SWI48 0 "register_operand"))
14003 (use (match_operand:SWI48 1 "register_operand"))
14004 (use (match_operand:QI 2 "register_operand"))]
14007 rtx_code_label *label = gen_label_rtx ();
14010 emit_insn (gen_testqi_ccz_1 (operands[2],
14011 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14013 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14014 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14015 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14016 gen_rtx_LABEL_REF (VOIDmode, label),
14018 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14019 JUMP_LABEL (tmp) = label;
14021 emit_move_insn (operands[0], operands[1]);
14022 ix86_expand_clear (operands[1]);
14024 emit_label (label);
14025 LABEL_NUSES (label) = 1;
14030 ;; Avoid useless masking of count operand.
14031 (define_insn_and_split "*ashl<mode>3_mask"
14032 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14034 (match_operand:SWI48 1 "nonimmediate_operand")
14037 (match_operand 2 "int248_register_operand" "c,r")
14038 (match_operand 3 "const_int_operand")) 0)))
14039 (clobber (reg:CC FLAGS_REG))]
14040 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14041 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14042 == GET_MODE_BITSIZE (<MODE>mode)-1
14043 && ix86_pre_reload_split ()"
14047 [(set (match_dup 0)
14048 (ashift:SWI48 (match_dup 1)
14050 (clobber (reg:CC FLAGS_REG))])]
14052 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14053 operands[2] = gen_lowpart (QImode, operands[2]);
14055 [(set_attr "isa" "*,bmi2")])
14057 (define_insn_and_split "*ashl<mode>3_mask_1"
14058 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14060 (match_operand:SWI48 1 "nonimmediate_operand")
14062 (match_operand:QI 2 "register_operand" "c,r")
14063 (match_operand:QI 3 "const_int_operand"))))
14064 (clobber (reg:CC FLAGS_REG))]
14065 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14066 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14067 == GET_MODE_BITSIZE (<MODE>mode)-1
14068 && ix86_pre_reload_split ()"
14072 [(set (match_dup 0)
14073 (ashift:SWI48 (match_dup 1)
14075 (clobber (reg:CC FLAGS_REG))])]
14077 [(set_attr "isa" "*,bmi2")])
14079 (define_insn "*bmi2_ashl<mode>3_1"
14080 [(set (match_operand:SWI48 0 "register_operand" "=r")
14081 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14082 (match_operand:SWI48 2 "register_operand" "r")))]
14084 "shlx\t{%2, %1, %0|%0, %1, %2}"
14085 [(set_attr "type" "ishiftx")
14086 (set_attr "mode" "<MODE>")])
14088 (define_insn "*ashl<mode>3_1"
14089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14090 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14091 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14092 (clobber (reg:CC FLAGS_REG))]
14093 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14095 switch (get_attr_type (insn))
14103 gcc_assert (operands[2] == const1_rtx);
14104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14105 return "add{<imodesuffix>}\t%0, %0";
14108 if (operands[2] == const1_rtx
14109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14110 return "sal{<imodesuffix>}\t%0";
14112 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14115 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14117 (cond [(eq_attr "alternative" "1")
14118 (const_string "lea")
14119 (eq_attr "alternative" "2")
14120 (const_string "ishiftx")
14121 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14122 (match_operand 0 "register_operand"))
14123 (match_operand 2 "const1_operand"))
14124 (const_string "alu")
14125 (eq_attr "alternative" "3")
14126 (const_string "msklog")
14128 (const_string "ishift")))
14129 (set (attr "length_immediate")
14131 (ior (eq_attr "type" "alu")
14132 (and (eq_attr "type" "ishift")
14133 (and (match_operand 2 "const1_operand")
14134 (ior (match_test "TARGET_SHIFT1")
14135 (match_test "optimize_function_for_size_p (cfun)")))))
14137 (const_string "*")))
14138 (set_attr "mode" "<MODE>")])
14140 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14142 [(set (match_operand:SWI48 0 "register_operand")
14143 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14144 (match_operand:QI 2 "register_operand")))
14145 (clobber (reg:CC FLAGS_REG))]
14146 "TARGET_BMI2 && reload_completed"
14147 [(set (match_dup 0)
14148 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14149 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14151 (define_insn "*bmi2_ashlsi3_1_zext"
14152 [(set (match_operand:DI 0 "register_operand" "=r")
14154 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14155 (match_operand:SI 2 "register_operand" "r"))))]
14156 "TARGET_64BIT && TARGET_BMI2"
14157 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14158 [(set_attr "type" "ishiftx")
14159 (set_attr "mode" "SI")])
14161 (define_insn "*ashlsi3_1_zext"
14162 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14164 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14165 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14166 (clobber (reg:CC FLAGS_REG))]
14167 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14169 switch (get_attr_type (insn))
14176 gcc_assert (operands[2] == const1_rtx);
14177 return "add{l}\t%k0, %k0";
14180 if (operands[2] == const1_rtx
14181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14182 return "sal{l}\t%k0";
14184 return "sal{l}\t{%2, %k0|%k0, %2}";
14187 [(set_attr "isa" "*,*,bmi2")
14189 (cond [(eq_attr "alternative" "1")
14190 (const_string "lea")
14191 (eq_attr "alternative" "2")
14192 (const_string "ishiftx")
14193 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14194 (match_operand 2 "const1_operand"))
14195 (const_string "alu")
14197 (const_string "ishift")))
14198 (set (attr "length_immediate")
14200 (ior (eq_attr "type" "alu")
14201 (and (eq_attr "type" "ishift")
14202 (and (match_operand 2 "const1_operand")
14203 (ior (match_test "TARGET_SHIFT1")
14204 (match_test "optimize_function_for_size_p (cfun)")))))
14206 (const_string "*")))
14207 (set_attr "mode" "SI")])
14209 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14211 [(set (match_operand:DI 0 "register_operand")
14213 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14214 (match_operand:QI 2 "register_operand"))))
14215 (clobber (reg:CC FLAGS_REG))]
14216 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14217 [(set (match_dup 0)
14218 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14219 "operands[2] = gen_lowpart (SImode, operands[2]);")
14221 (define_insn "*ashlhi3_1"
14222 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14223 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14224 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14225 (clobber (reg:CC FLAGS_REG))]
14226 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14228 switch (get_attr_type (insn))
14235 gcc_assert (operands[2] == const1_rtx);
14236 return "add{w}\t%0, %0";
14239 if (operands[2] == const1_rtx
14240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14241 return "sal{w}\t%0";
14243 return "sal{w}\t{%2, %0|%0, %2}";
14246 [(set_attr "isa" "*,*,avx512f")
14248 (cond [(eq_attr "alternative" "1")
14249 (const_string "lea")
14250 (eq_attr "alternative" "2")
14251 (const_string "msklog")
14252 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14253 (match_operand 0 "register_operand"))
14254 (match_operand 2 "const1_operand"))
14255 (const_string "alu")
14257 (const_string "ishift")))
14258 (set (attr "length_immediate")
14260 (ior (eq_attr "type" "alu")
14261 (and (eq_attr "type" "ishift")
14262 (and (match_operand 2 "const1_operand")
14263 (ior (match_test "TARGET_SHIFT1")
14264 (match_test "optimize_function_for_size_p (cfun)")))))
14266 (const_string "*")))
14267 (set_attr "mode" "HI,SI,HI")])
14269 (define_insn "*ashlqi3_1"
14270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14271 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14272 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14273 (clobber (reg:CC FLAGS_REG))]
14274 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14276 switch (get_attr_type (insn))
14283 gcc_assert (operands[2] == const1_rtx);
14284 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14285 return "add{l}\t%k0, %k0";
14287 return "add{b}\t%0, %0";
14290 if (operands[2] == const1_rtx
14291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14293 if (get_attr_mode (insn) == MODE_SI)
14294 return "sal{l}\t%k0";
14296 return "sal{b}\t%0";
14300 if (get_attr_mode (insn) == MODE_SI)
14301 return "sal{l}\t{%2, %k0|%k0, %2}";
14303 return "sal{b}\t{%2, %0|%0, %2}";
14307 [(set_attr "isa" "*,*,*,avx512dq")
14309 (cond [(eq_attr "alternative" "2")
14310 (const_string "lea")
14311 (eq_attr "alternative" "3")
14312 (const_string "msklog")
14313 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14314 (match_operand 0 "register_operand"))
14315 (match_operand 2 "const1_operand"))
14316 (const_string "alu")
14318 (const_string "ishift")))
14319 (set (attr "length_immediate")
14321 (ior (eq_attr "type" "alu")
14322 (and (eq_attr "type" "ishift")
14323 (and (match_operand 2 "const1_operand")
14324 (ior (match_test "TARGET_SHIFT1")
14325 (match_test "optimize_function_for_size_p (cfun)")))))
14327 (const_string "*")))
14328 (set_attr "mode" "QI,SI,SI,QI")
14329 ;; Potential partial reg stall on alternative 1.
14330 (set (attr "preferred_for_speed")
14331 (cond [(eq_attr "alternative" "1")
14332 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14333 (symbol_ref "true")))])
14335 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14336 (define_insn_and_split "*ashl<mode>3_1_slp"
14337 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14338 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14339 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14340 (clobber (reg:CC FLAGS_REG))]
14341 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14343 if (which_alternative)
14346 switch (get_attr_type (insn))
14349 gcc_assert (operands[2] == const1_rtx);
14350 return "add{<imodesuffix>}\t%0, %0";
14353 if (operands[2] == const1_rtx
14354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14355 return "sal{<imodesuffix>}\t%0";
14357 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14360 "&& reload_completed"
14361 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14363 [(set (strict_low_part (match_dup 0))
14364 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14365 (clobber (reg:CC FLAGS_REG))])]
14367 [(set (attr "type")
14368 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14369 (match_operand 2 "const1_operand"))
14370 (const_string "alu")
14372 (const_string "ishift")))
14373 (set (attr "length_immediate")
14375 (ior (eq_attr "type" "alu")
14376 (and (eq_attr "type" "ishift")
14377 (and (match_operand 2 "const1_operand")
14378 (ior (match_test "TARGET_SHIFT1")
14379 (match_test "optimize_function_for_size_p (cfun)")))))
14381 (const_string "*")))
14382 (set_attr "mode" "<MODE>")])
14384 ;; Convert ashift to the lea pattern to avoid flags dependency.
14386 [(set (match_operand:SWI 0 "general_reg_operand")
14387 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14388 (match_operand 2 "const_0_to_3_operand")))
14389 (clobber (reg:CC FLAGS_REG))]
14391 && REGNO (operands[0]) != REGNO (operands[1])"
14392 [(set (match_dup 0)
14393 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14395 if (<MODE>mode != <LEAMODE>mode)
14397 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14398 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14400 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14403 ;; Convert ashift to the lea pattern to avoid flags dependency.
14405 [(set (match_operand:DI 0 "general_reg_operand")
14407 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14408 (match_operand 2 "const_0_to_3_operand"))))
14409 (clobber (reg:CC FLAGS_REG))]
14410 "TARGET_64BIT && reload_completed
14411 && REGNO (operands[0]) != REGNO (operands[1])"
14412 [(set (match_dup 0)
14413 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14415 operands[1] = gen_lowpart (SImode, operands[1]);
14416 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14419 ;; This pattern can't accept a variable shift count, since shifts by
14420 ;; zero don't affect the flags. We assume that shifts by constant
14421 ;; zero are optimized away.
14422 (define_insn "*ashl<mode>3_cmp"
14423 [(set (reg FLAGS_REG)
14425 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14426 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14428 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14429 (ashift:SWI (match_dup 1) (match_dup 2)))]
14430 "(optimize_function_for_size_p (cfun)
14431 || !TARGET_PARTIAL_FLAG_REG_STALL
14432 || (operands[2] == const1_rtx
14434 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14435 && ix86_match_ccmode (insn, CCGOCmode)
14436 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14438 switch (get_attr_type (insn))
14441 gcc_assert (operands[2] == const1_rtx);
14442 return "add{<imodesuffix>}\t%0, %0";
14445 if (operands[2] == const1_rtx
14446 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14447 return "sal{<imodesuffix>}\t%0";
14449 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14452 [(set (attr "type")
14453 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14454 (match_operand 0 "register_operand"))
14455 (match_operand 2 "const1_operand"))
14456 (const_string "alu")
14458 (const_string "ishift")))
14459 (set (attr "length_immediate")
14461 (ior (eq_attr "type" "alu")
14462 (and (eq_attr "type" "ishift")
14463 (and (match_operand 2 "const1_operand")
14464 (ior (match_test "TARGET_SHIFT1")
14465 (match_test "optimize_function_for_size_p (cfun)")))))
14467 (const_string "*")))
14468 (set_attr "mode" "<MODE>")])
14470 (define_insn "*ashlsi3_cmp_zext"
14471 [(set (reg FLAGS_REG)
14473 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14474 (match_operand:QI 2 "const_1_to_31_operand"))
14476 (set (match_operand:DI 0 "register_operand" "=r")
14477 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14479 && (optimize_function_for_size_p (cfun)
14480 || !TARGET_PARTIAL_FLAG_REG_STALL
14481 || (operands[2] == const1_rtx
14483 || TARGET_DOUBLE_WITH_ADD)))
14484 && ix86_match_ccmode (insn, CCGOCmode)
14485 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14487 switch (get_attr_type (insn))
14490 gcc_assert (operands[2] == const1_rtx);
14491 return "add{l}\t%k0, %k0";
14494 if (operands[2] == const1_rtx
14495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14496 return "sal{l}\t%k0";
14498 return "sal{l}\t{%2, %k0|%k0, %2}";
14501 [(set (attr "type")
14502 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14503 (match_operand 2 "const1_operand"))
14504 (const_string "alu")
14506 (const_string "ishift")))
14507 (set (attr "length_immediate")
14509 (ior (eq_attr "type" "alu")
14510 (and (eq_attr "type" "ishift")
14511 (and (match_operand 2 "const1_operand")
14512 (ior (match_test "TARGET_SHIFT1")
14513 (match_test "optimize_function_for_size_p (cfun)")))))
14515 (const_string "*")))
14516 (set_attr "mode" "SI")])
14518 (define_insn "*ashl<mode>3_cconly"
14519 [(set (reg FLAGS_REG)
14521 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14522 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14524 (clobber (match_scratch:SWI 0 "=<r>"))]
14525 "(optimize_function_for_size_p (cfun)
14526 || !TARGET_PARTIAL_FLAG_REG_STALL
14527 || (operands[2] == const1_rtx
14529 || TARGET_DOUBLE_WITH_ADD)))
14530 && ix86_match_ccmode (insn, CCGOCmode)"
14532 switch (get_attr_type (insn))
14535 gcc_assert (operands[2] == const1_rtx);
14536 return "add{<imodesuffix>}\t%0, %0";
14539 if (operands[2] == const1_rtx
14540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14541 return "sal{<imodesuffix>}\t%0";
14543 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14546 [(set (attr "type")
14547 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14548 (match_operand 0 "register_operand"))
14549 (match_operand 2 "const1_operand"))
14550 (const_string "alu")
14552 (const_string "ishift")))
14553 (set (attr "length_immediate")
14555 (ior (eq_attr "type" "alu")
14556 (and (eq_attr "type" "ishift")
14557 (and (match_operand 2 "const1_operand")
14558 (ior (match_test "TARGET_SHIFT1")
14559 (match_test "optimize_function_for_size_p (cfun)")))))
14561 (const_string "*")))
14562 (set_attr "mode" "<MODE>")])
14564 (define_insn "*ashlqi_ext<mode>_2"
14565 [(set (zero_extract:SWI248
14566 (match_operand 0 "int248_register_operand" "+Q")
14572 (match_operator:SWI248 3 "extract_operator"
14573 [(match_operand 1 "int248_register_operand" "0")
14576 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14577 (clobber (reg:CC FLAGS_REG))]
14578 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14579 rtx_equal_p (operands[0], operands[1])"
14581 switch (get_attr_type (insn))
14584 gcc_assert (operands[2] == const1_rtx);
14585 return "add{b}\t%h0, %h0";
14588 if (operands[2] == const1_rtx
14589 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14590 return "sal{b}\t%h0";
14592 return "sal{b}\t{%2, %h0|%h0, %2}";
14595 [(set (attr "type")
14596 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14597 (match_operand 2 "const1_operand"))
14598 (const_string "alu")
14600 (const_string "ishift")))
14601 (set (attr "length_immediate")
14603 (ior (eq_attr "type" "alu")
14604 (and (eq_attr "type" "ishift")
14605 (and (match_operand 2 "const1_operand")
14606 (ior (match_test "TARGET_SHIFT1")
14607 (match_test "optimize_function_for_size_p (cfun)")))))
14609 (const_string "*")))
14610 (set_attr "mode" "QI")])
14612 ;; See comment above `ashl<mode>3' about how this works.
14614 (define_expand "<insn><mode>3"
14615 [(set (match_operand:SDWIM 0 "<shift_operand>")
14616 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14617 (match_operand:QI 2 "nonmemory_operand")))]
14619 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14621 ;; Avoid useless masking of count operand.
14622 (define_insn_and_split "*<insn><mode>3_mask"
14623 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14625 (match_operand:SWI48 1 "nonimmediate_operand")
14628 (match_operand 2 "int248_register_operand" "c,r")
14629 (match_operand 3 "const_int_operand")) 0)))
14630 (clobber (reg:CC FLAGS_REG))]
14631 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14632 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14633 == GET_MODE_BITSIZE (<MODE>mode)-1
14634 && ix86_pre_reload_split ()"
14638 [(set (match_dup 0)
14639 (any_shiftrt:SWI48 (match_dup 1)
14641 (clobber (reg:CC FLAGS_REG))])]
14643 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14644 operands[2] = gen_lowpart (QImode, operands[2]);
14646 [(set_attr "isa" "*,bmi2")])
14648 (define_insn_and_split "*<insn><mode>3_mask_1"
14649 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14651 (match_operand:SWI48 1 "nonimmediate_operand")
14653 (match_operand:QI 2 "register_operand" "c,r")
14654 (match_operand:QI 3 "const_int_operand"))))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14657 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14658 == GET_MODE_BITSIZE (<MODE>mode)-1
14659 && ix86_pre_reload_split ()"
14663 [(set (match_dup 0)
14664 (any_shiftrt:SWI48 (match_dup 1)
14666 (clobber (reg:CC FLAGS_REG))])]
14668 [(set_attr "isa" "*,bmi2")])
14670 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14671 [(set (match_operand:<DWI> 0 "register_operand")
14673 (match_operand:<DWI> 1 "register_operand")
14676 (match_operand 2 "int248_register_operand" "c")
14677 (match_operand 3 "const_int_operand")) 0)))
14678 (clobber (reg:CC FLAGS_REG))]
14679 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14680 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14681 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14682 && ix86_pre_reload_split ()"
14686 [(set (match_dup 4)
14687 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14688 (and:QI (match_dup 2) (match_dup 8)))
14690 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14691 (minus:QI (match_dup 9)
14692 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14693 (clobber (reg:CC FLAGS_REG))])
14695 [(set (match_dup 6)
14696 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14697 (clobber (reg:CC FLAGS_REG))])]
14699 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14701 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14702 operands[2] = gen_lowpart (QImode, operands[2]);
14703 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14708 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14710 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14711 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14713 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14714 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14717 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14718 xops[1] = operands[2];
14719 xops[2] = GEN_INT (INTVAL (operands[3])
14720 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14721 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14722 operands[2] = xops[0];
14725 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14726 operands[2] = gen_lowpart (QImode, operands[2]);
14728 if (!rtx_equal_p (operands[4], operands[5]))
14729 emit_move_insn (operands[4], operands[5]);
14732 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14733 [(set (match_operand:<DWI> 0 "register_operand")
14735 (match_operand:<DWI> 1 "register_operand")
14737 (match_operand:QI 2 "register_operand" "c")
14738 (match_operand:QI 3 "const_int_operand"))))
14739 (clobber (reg:CC FLAGS_REG))]
14740 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14741 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14742 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14743 && ix86_pre_reload_split ()"
14747 [(set (match_dup 4)
14748 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14749 (and:QI (match_dup 2) (match_dup 8)))
14751 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14752 (minus:QI (match_dup 9)
14753 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14754 (clobber (reg:CC FLAGS_REG))])
14756 [(set (match_dup 6)
14757 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14758 (clobber (reg:CC FLAGS_REG))])]
14760 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14762 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14767 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14769 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14770 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14772 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14773 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14775 rtx tem = gen_reg_rtx (QImode);
14776 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14780 if (!rtx_equal_p (operands[4], operands[5]))
14781 emit_move_insn (operands[4], operands[5]);
14784 (define_insn_and_split "<insn><mode>3_doubleword"
14785 [(set (match_operand:DWI 0 "register_operand" "=&r")
14786 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14787 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14788 (clobber (reg:CC FLAGS_REG))]
14791 "epilogue_completed"
14793 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14794 [(set_attr "type" "multi")])
14796 ;; By default we don't ask for a scratch register, because when DWImode
14797 ;; values are manipulated, registers are already at a premium. But if
14798 ;; we have one handy, we won't turn it away.
14801 [(match_scratch:DWIH 3 "r")
14802 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14804 (match_operand:<DWI> 1 "register_operand")
14805 (match_operand:QI 2 "nonmemory_operand")))
14806 (clobber (reg:CC FLAGS_REG))])
14810 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14812 (define_insn "x86_64_shrd"
14813 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14814 (ior:DI (lshiftrt:DI (match_dup 0)
14815 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14820 (match_operand:DI 1 "register_operand" "r"))
14821 (minus:QI (const_int 64)
14822 (and:QI (match_dup 2) (const_int 63)))) 0)))
14823 (clobber (reg:CC FLAGS_REG))]
14825 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14826 [(set_attr "type" "ishift")
14827 (set_attr "prefix_0f" "1")
14828 (set_attr "mode" "DI")
14829 (set_attr "athlon_decode" "vector")
14830 (set_attr "amdfam10_decode" "vector")
14831 (set_attr "bdver1_decode" "vector")])
14833 (define_insn "x86_64_shrd_1"
14834 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14835 (ior:DI (lshiftrt:DI (match_dup 0)
14836 (match_operand:QI 2 "const_0_to_63_operand"))
14840 (match_operand:DI 1 "register_operand" "r"))
14841 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14842 (clobber (reg:CC FLAGS_REG))]
14844 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14845 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14846 [(set_attr "type" "ishift")
14847 (set_attr "prefix_0f" "1")
14848 (set_attr "length_immediate" "1")
14849 (set_attr "mode" "DI")
14850 (set_attr "athlon_decode" "vector")
14851 (set_attr "amdfam10_decode" "vector")
14852 (set_attr "bdver1_decode" "vector")])
14854 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14855 [(set (match_operand:DI 0 "nonimmediate_operand")
14856 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14857 (match_operand:QI 2 "const_0_to_63_operand"))
14859 (match_operand:DI 1 "nonimmediate_operand")
14860 (match_operand:QI 3 "const_0_to_63_operand"))))
14861 (clobber (reg:CC FLAGS_REG))]
14863 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14864 && ix86_pre_reload_split ()"
14869 if (rtx_equal_p (operands[4], operands[0]))
14871 operands[1] = force_reg (DImode, operands[1]);
14872 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14874 else if (rtx_equal_p (operands[1], operands[0]))
14876 operands[4] = force_reg (DImode, operands[4]);
14877 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14881 operands[1] = force_reg (DImode, operands[1]);
14882 rtx tmp = gen_reg_rtx (DImode);
14883 emit_move_insn (tmp, operands[4]);
14884 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14885 emit_move_insn (operands[0], tmp);
14890 (define_insn_and_split "*x86_64_shrd_2"
14891 [(set (match_operand:DI 0 "nonimmediate_operand")
14892 (ior:DI (lshiftrt:DI (match_dup 0)
14893 (match_operand:QI 2 "nonmemory_operand"))
14894 (ashift:DI (match_operand:DI 1 "register_operand")
14895 (minus:QI (const_int 64) (match_dup 2)))))
14896 (clobber (reg:CC FLAGS_REG))]
14897 "TARGET_64BIT && ix86_pre_reload_split ()"
14900 [(parallel [(set (match_dup 0)
14901 (ior:DI (lshiftrt:DI (match_dup 0)
14902 (and:QI (match_dup 2) (const_int 63)))
14905 (zero_extend:TI (match_dup 1))
14906 (minus:QI (const_int 64)
14907 (and:QI (match_dup 2)
14908 (const_int 63)))) 0)))
14909 (clobber (reg:CC FLAGS_REG))])])
14911 (define_insn "x86_shrd"
14912 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14913 (ior:SI (lshiftrt:SI (match_dup 0)
14914 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14919 (match_operand:SI 1 "register_operand" "r"))
14920 (minus:QI (const_int 32)
14921 (and:QI (match_dup 2) (const_int 31)))) 0)))
14922 (clobber (reg:CC FLAGS_REG))]
14924 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14925 [(set_attr "type" "ishift")
14926 (set_attr "prefix_0f" "1")
14927 (set_attr "mode" "SI")
14928 (set_attr "pent_pair" "np")
14929 (set_attr "athlon_decode" "vector")
14930 (set_attr "amdfam10_decode" "vector")
14931 (set_attr "bdver1_decode" "vector")])
14933 (define_insn "x86_shrd_1"
14934 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14935 (ior:SI (lshiftrt:SI (match_dup 0)
14936 (match_operand:QI 2 "const_0_to_31_operand"))
14940 (match_operand:SI 1 "register_operand" "r"))
14941 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14942 (clobber (reg:CC FLAGS_REG))]
14943 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14944 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14945 [(set_attr "type" "ishift")
14946 (set_attr "prefix_0f" "1")
14947 (set_attr "length_immediate" "1")
14948 (set_attr "mode" "SI")
14949 (set_attr "pent_pair" "np")
14950 (set_attr "athlon_decode" "vector")
14951 (set_attr "amdfam10_decode" "vector")
14952 (set_attr "bdver1_decode" "vector")])
14954 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14955 [(set (match_operand:SI 0 "nonimmediate_operand")
14956 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14957 (match_operand:QI 2 "const_0_to_31_operand"))
14959 (match_operand:SI 1 "nonimmediate_operand")
14960 (match_operand:QI 3 "const_0_to_31_operand"))))
14961 (clobber (reg:CC FLAGS_REG))]
14962 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14963 && ix86_pre_reload_split ()"
14968 if (rtx_equal_p (operands[4], operands[0]))
14970 operands[1] = force_reg (SImode, operands[1]);
14971 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14973 else if (rtx_equal_p (operands[1], operands[0]))
14975 operands[4] = force_reg (SImode, operands[4]);
14976 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14980 operands[1] = force_reg (SImode, operands[1]);
14981 rtx tmp = gen_reg_rtx (SImode);
14982 emit_move_insn (tmp, operands[4]);
14983 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14984 emit_move_insn (operands[0], tmp);
14989 (define_insn_and_split "*x86_shrd_2"
14990 [(set (match_operand:SI 0 "nonimmediate_operand")
14991 (ior:SI (lshiftrt:SI (match_dup 0)
14992 (match_operand:QI 2 "nonmemory_operand"))
14993 (ashift:SI (match_operand:SI 1 "register_operand")
14994 (minus:QI (const_int 32) (match_dup 2)))))
14995 (clobber (reg:CC FLAGS_REG))]
14996 "TARGET_64BIT && ix86_pre_reload_split ()"
14999 [(parallel [(set (match_dup 0)
15000 (ior:SI (lshiftrt:SI (match_dup 0)
15001 (and:QI (match_dup 2) (const_int 31)))
15004 (zero_extend:DI (match_dup 1))
15005 (minus:QI (const_int 32)
15006 (and:QI (match_dup 2)
15007 (const_int 31)))) 0)))
15008 (clobber (reg:CC FLAGS_REG))])])
15010 ;; Base name for insn mnemonic.
15011 (define_mode_attr cvt_mnemonic
15012 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15014 (define_insn "ashr<mode>3_cvt"
15015 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15017 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15018 (match_operand:QI 2 "const_int_operand")))
15019 (clobber (reg:CC FLAGS_REG))]
15020 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15021 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15022 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15025 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15026 [(set_attr "type" "imovx,ishift")
15027 (set_attr "prefix_0f" "0,*")
15028 (set_attr "length_immediate" "0,*")
15029 (set_attr "modrm" "0,1")
15030 (set_attr "mode" "<MODE>")])
15032 (define_insn "*ashrsi3_cvt_zext"
15033 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15035 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15036 (match_operand:QI 2 "const_int_operand"))))
15037 (clobber (reg:CC FLAGS_REG))]
15038 "TARGET_64BIT && INTVAL (operands[2]) == 31
15039 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15040 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15043 sar{l}\t{%2, %k0|%k0, %2}"
15044 [(set_attr "type" "imovx,ishift")
15045 (set_attr "prefix_0f" "0,*")
15046 (set_attr "length_immediate" "0,*")
15047 (set_attr "modrm" "0,1")
15048 (set_attr "mode" "SI")])
15050 (define_expand "@x86_shift<mode>_adj_3"
15051 [(use (match_operand:SWI48 0 "register_operand"))
15052 (use (match_operand:SWI48 1 "register_operand"))
15053 (use (match_operand:QI 2 "register_operand"))]
15056 rtx_code_label *label = gen_label_rtx ();
15059 emit_insn (gen_testqi_ccz_1 (operands[2],
15060 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15062 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15063 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15064 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15065 gen_rtx_LABEL_REF (VOIDmode, label),
15067 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15068 JUMP_LABEL (tmp) = label;
15070 emit_move_insn (operands[0], operands[1]);
15071 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15072 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15073 emit_label (label);
15074 LABEL_NUSES (label) = 1;
15079 (define_insn "*bmi2_<insn><mode>3_1"
15080 [(set (match_operand:SWI48 0 "register_operand" "=r")
15081 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15082 (match_operand:SWI48 2 "register_operand" "r")))]
15084 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15085 [(set_attr "type" "ishiftx")
15086 (set_attr "mode" "<MODE>")])
15088 (define_insn "*ashr<mode>3_1"
15089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15091 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15092 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15093 (clobber (reg:CC FLAGS_REG))]
15094 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15096 switch (get_attr_type (insn))
15102 if (operands[2] == const1_rtx
15103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15104 return "sar{<imodesuffix>}\t%0";
15106 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15109 [(set_attr "isa" "*,bmi2")
15110 (set_attr "type" "ishift,ishiftx")
15111 (set (attr "length_immediate")
15113 (and (match_operand 2 "const1_operand")
15114 (ior (match_test "TARGET_SHIFT1")
15115 (match_test "optimize_function_for_size_p (cfun)")))
15117 (const_string "*")))
15118 (set_attr "mode" "<MODE>")])
15120 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15121 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15122 (define_insn_and_split "*highpartdisi2"
15123 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15124 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15126 (clobber (reg:CC FLAGS_REG))]
15129 "&& reload_completed"
15131 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15132 (clobber (reg:CC FLAGS_REG))])]
15134 if (SSE_REG_P (operands[0]))
15136 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15137 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15138 const1_rtx, const1_rtx,
15139 GEN_INT (5), GEN_INT (5)));
15142 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15145 (define_insn "*lshr<mode>3_1"
15146 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15148 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15149 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15150 (clobber (reg:CC FLAGS_REG))]
15151 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15153 switch (get_attr_type (insn))
15160 if (operands[2] == const1_rtx
15161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15162 return "shr{<imodesuffix>}\t%0";
15164 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15167 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15168 (set_attr "type" "ishift,ishiftx,msklog")
15169 (set (attr "length_immediate")
15171 (and (and (match_operand 2 "const1_operand")
15172 (eq_attr "alternative" "0"))
15173 (ior (match_test "TARGET_SHIFT1")
15174 (match_test "optimize_function_for_size_p (cfun)")))
15176 (const_string "*")))
15177 (set_attr "mode" "<MODE>")])
15179 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15181 [(set (match_operand:SWI48 0 "register_operand")
15182 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15183 (match_operand:QI 2 "register_operand")))
15184 (clobber (reg:CC FLAGS_REG))]
15185 "TARGET_BMI2 && reload_completed"
15186 [(set (match_dup 0)
15187 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15188 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15190 (define_insn "*bmi2_<insn>si3_1_zext"
15191 [(set (match_operand:DI 0 "register_operand" "=r")
15193 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15194 (match_operand:SI 2 "register_operand" "r"))))]
15195 "TARGET_64BIT && TARGET_BMI2"
15196 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15197 [(set_attr "type" "ishiftx")
15198 (set_attr "mode" "SI")])
15200 (define_insn "*<insn>si3_1_zext"
15201 [(set (match_operand:DI 0 "register_operand" "=r,r")
15203 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15204 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15205 (clobber (reg:CC FLAGS_REG))]
15206 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15208 switch (get_attr_type (insn))
15214 if (operands[2] == const1_rtx
15215 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15216 return "<shift>{l}\t%k0";
15218 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15221 [(set_attr "isa" "*,bmi2")
15222 (set_attr "type" "ishift,ishiftx")
15223 (set (attr "length_immediate")
15225 (and (match_operand 2 "const1_operand")
15226 (ior (match_test "TARGET_SHIFT1")
15227 (match_test "optimize_function_for_size_p (cfun)")))
15229 (const_string "*")))
15230 (set_attr "mode" "SI")])
15232 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15234 [(set (match_operand:DI 0 "register_operand")
15236 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15237 (match_operand:QI 2 "register_operand"))))
15238 (clobber (reg:CC FLAGS_REG))]
15239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15240 [(set (match_dup 0)
15241 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15242 "operands[2] = gen_lowpart (SImode, operands[2]);")
15244 (define_insn "*ashr<mode>3_1"
15245 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15247 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15248 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15249 (clobber (reg:CC FLAGS_REG))]
15250 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15252 if (operands[2] == const1_rtx
15253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15254 return "sar{<imodesuffix>}\t%0";
15256 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15258 [(set_attr "type" "ishift")
15259 (set (attr "length_immediate")
15261 (and (match_operand 2 "const1_operand")
15262 (ior (match_test "TARGET_SHIFT1")
15263 (match_test "optimize_function_for_size_p (cfun)")))
15265 (const_string "*")))
15266 (set_attr "mode" "<MODE>")])
15268 (define_insn "*lshrqi3_1"
15269 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15271 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15272 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15273 (clobber (reg:CC FLAGS_REG))]
15274 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15276 switch (get_attr_type (insn))
15279 if (operands[2] == const1_rtx
15280 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15281 return "shr{b}\t%0";
15283 return "shr{b}\t{%2, %0|%0, %2}";
15287 gcc_unreachable ();
15290 [(set_attr "isa" "*,avx512dq")
15291 (set_attr "type" "ishift,msklog")
15292 (set (attr "length_immediate")
15294 (and (and (match_operand 2 "const1_operand")
15295 (eq_attr "alternative" "0"))
15296 (ior (match_test "TARGET_SHIFT1")
15297 (match_test "optimize_function_for_size_p (cfun)")))
15299 (const_string "*")))
15300 (set_attr "mode" "QI")])
15302 (define_insn "*lshrhi3_1"
15303 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15305 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15306 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15307 (clobber (reg:CC FLAGS_REG))]
15308 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15310 switch (get_attr_type (insn))
15313 if (operands[2] == const1_rtx
15314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15315 return "shr{w}\t%0";
15317 return "shr{w}\t{%2, %0|%0, %2}";
15321 gcc_unreachable ();
15324 [(set_attr "isa" "*, avx512f")
15325 (set_attr "type" "ishift,msklog")
15326 (set (attr "length_immediate")
15328 (and (and (match_operand 2 "const1_operand")
15329 (eq_attr "alternative" "0"))
15330 (ior (match_test "TARGET_SHIFT1")
15331 (match_test "optimize_function_for_size_p (cfun)")))
15333 (const_string "*")))
15334 (set_attr "mode" "HI")])
15336 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15337 (define_insn_and_split "*<insn><mode>3_1_slp"
15338 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15339 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15340 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15341 (clobber (reg:CC FLAGS_REG))]
15342 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15344 if (which_alternative)
15347 if (operands[2] == const1_rtx
15348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15349 return "<shift>{<imodesuffix>}\t%0";
15351 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15353 "&& reload_completed"
15354 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15356 [(set (strict_low_part (match_dup 0))
15357 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15358 (clobber (reg:CC FLAGS_REG))])]
15360 [(set_attr "type" "ishift")
15361 (set (attr "length_immediate")
15363 (and (match_operand 2 "const1_operand")
15364 (ior (match_test "TARGET_SHIFT1")
15365 (match_test "optimize_function_for_size_p (cfun)")))
15367 (const_string "*")))
15368 (set_attr "mode" "<MODE>")])
15370 ;; This pattern can't accept a variable shift count, since shifts by
15371 ;; zero don't affect the flags. We assume that shifts by constant
15372 ;; zero are optimized away.
15373 (define_insn "*<insn><mode>3_cmp"
15374 [(set (reg FLAGS_REG)
15377 (match_operand:SWI 1 "nonimmediate_operand" "0")
15378 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15380 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15381 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15382 "(optimize_function_for_size_p (cfun)
15383 || !TARGET_PARTIAL_FLAG_REG_STALL
15384 || (operands[2] == const1_rtx
15386 && ix86_match_ccmode (insn, CCGOCmode)
15387 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15389 if (operands[2] == const1_rtx
15390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15391 return "<shift>{<imodesuffix>}\t%0";
15393 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15395 [(set_attr "type" "ishift")
15396 (set (attr "length_immediate")
15398 (and (match_operand 2 "const1_operand")
15399 (ior (match_test "TARGET_SHIFT1")
15400 (match_test "optimize_function_for_size_p (cfun)")))
15402 (const_string "*")))
15403 (set_attr "mode" "<MODE>")])
15405 (define_insn "*<insn>si3_cmp_zext"
15406 [(set (reg FLAGS_REG)
15408 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15409 (match_operand:QI 2 "const_1_to_31_operand"))
15411 (set (match_operand:DI 0 "register_operand" "=r")
15412 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15414 && (optimize_function_for_size_p (cfun)
15415 || !TARGET_PARTIAL_FLAG_REG_STALL
15416 || (operands[2] == const1_rtx
15418 && ix86_match_ccmode (insn, CCGOCmode)
15419 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15421 if (operands[2] == const1_rtx
15422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15423 return "<shift>{l}\t%k0";
15425 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15427 [(set_attr "type" "ishift")
15428 (set (attr "length_immediate")
15430 (and (match_operand 2 "const1_operand")
15431 (ior (match_test "TARGET_SHIFT1")
15432 (match_test "optimize_function_for_size_p (cfun)")))
15434 (const_string "*")))
15435 (set_attr "mode" "SI")])
15437 (define_insn "*<insn><mode>3_cconly"
15438 [(set (reg FLAGS_REG)
15441 (match_operand:SWI 1 "register_operand" "0")
15442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15444 (clobber (match_scratch:SWI 0 "=<r>"))]
15445 "(optimize_function_for_size_p (cfun)
15446 || !TARGET_PARTIAL_FLAG_REG_STALL
15447 || (operands[2] == const1_rtx
15449 && ix86_match_ccmode (insn, CCGOCmode)"
15451 if (operands[2] == const1_rtx
15452 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15453 return "<shift>{<imodesuffix>}\t%0";
15455 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15457 [(set_attr "type" "ishift")
15458 (set (attr "length_immediate")
15460 (and (match_operand 2 "const1_operand")
15461 (ior (match_test "TARGET_SHIFT1")
15462 (match_test "optimize_function_for_size_p (cfun)")))
15464 (const_string "*")))
15465 (set_attr "mode" "<MODE>")])
15467 (define_insn "*<insn>qi_ext<mode>_2"
15468 [(set (zero_extract:SWI248
15469 (match_operand 0 "int248_register_operand" "+Q")
15475 (match_operator:SWI248 3 "extract_operator"
15476 [(match_operand 1 "int248_register_operand" "0")
15479 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15480 (clobber (reg:CC FLAGS_REG))]
15481 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15482 rtx_equal_p (operands[0], operands[1])"
15484 if (operands[2] == const1_rtx
15485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15486 return "<shift>{b}\t%h0";
15488 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15490 [(set_attr "type" "ishift")
15491 (set (attr "length_immediate")
15493 (and (match_operand 2 "const1_operand")
15494 (ior (match_test "TARGET_SHIFT1")
15495 (match_test "optimize_function_for_size_p (cfun)")))
15497 (const_string "*")))
15498 (set_attr "mode" "QI")])
15500 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15501 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15503 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15504 (match_operand:QI 2 "const_int_operand"))
15505 (match_operand:QI 3 "const_int_operand")))
15506 (clobber (reg:CC FLAGS_REG))]
15507 "INTVAL (operands[2]) == INTVAL (operands[3])
15508 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15510 "&& reload_completed"
15511 [(parallel [(set (match_dup 4)
15512 (ashift:DWIH (match_dup 4) (match_dup 2)))
15513 (clobber (reg:CC FLAGS_REG))])
15514 (parallel [(set (match_dup 4)
15515 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15516 (clobber (reg:CC FLAGS_REG))])]
15517 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15519 (define_insn_and_split "*extendv2di2_highpart_stv"
15520 [(set (match_operand:V2DI 0 "register_operand" "=v")
15522 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15523 (match_operand:QI 2 "const_int_operand"))
15524 (match_operand:QI 3 "const_int_operand")))]
15525 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15526 && INTVAL (operands[2]) == INTVAL (operands[3])
15527 && UINTVAL (operands[2]) < 32"
15529 "&& reload_completed"
15530 [(set (match_dup 0)
15531 (ashift:V2DI (match_dup 1) (match_dup 2)))
15533 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15535 ;; Rotate instructions
15537 (define_expand "<insn>ti3"
15538 [(set (match_operand:TI 0 "register_operand")
15539 (any_rotate:TI (match_operand:TI 1 "register_operand")
15540 (match_operand:QI 2 "nonmemory_operand")))]
15543 if (const_1_to_63_operand (operands[2], VOIDmode))
15544 emit_insn (gen_ix86_<insn>ti3_doubleword
15545 (operands[0], operands[1], operands[2]));
15546 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15548 operands[1] = force_reg (TImode, operands[1]);
15549 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15553 rtx amount = force_reg (QImode, operands[2]);
15554 rtx src_lo = gen_lowpart (DImode, operands[1]);
15555 rtx src_hi = gen_highpart (DImode, operands[1]);
15556 rtx tmp_lo = gen_reg_rtx (DImode);
15557 rtx tmp_hi = gen_reg_rtx (DImode);
15558 emit_move_insn (tmp_lo, src_lo);
15559 emit_move_insn (tmp_hi, src_hi);
15560 rtx (*shiftd) (rtx, rtx, rtx)
15561 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15562 emit_insn (shiftd (tmp_lo, src_hi, amount));
15563 emit_insn (shiftd (tmp_hi, src_lo, amount));
15564 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15565 rtx dst_hi = gen_highpart (DImode, operands[0]);
15566 emit_move_insn (dst_lo, tmp_lo);
15567 emit_move_insn (dst_hi, tmp_hi);
15568 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15573 (define_expand "<insn>di3"
15574 [(set (match_operand:DI 0 "shiftdi_operand")
15575 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15576 (match_operand:QI 2 "nonmemory_operand")))]
15580 ix86_expand_binary_operator (<CODE>, DImode, operands);
15581 else if (const_1_to_31_operand (operands[2], VOIDmode))
15582 emit_insn (gen_ix86_<insn>di3_doubleword
15583 (operands[0], operands[1], operands[2]));
15584 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15586 operands[1] = force_reg (DImode, operands[1]);
15587 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15595 (define_expand "<insn><mode>3"
15596 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15597 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15598 (match_operand:QI 2 "nonmemory_operand")))]
15600 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15602 ;; Avoid useless masking of count operand.
15603 (define_insn_and_split "*<insn><mode>3_mask"
15604 [(set (match_operand:SWI 0 "nonimmediate_operand")
15606 (match_operand:SWI 1 "nonimmediate_operand")
15609 (match_operand 2 "int248_register_operand" "c")
15610 (match_operand 3 "const_int_operand")) 0)))
15611 (clobber (reg:CC FLAGS_REG))]
15612 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15613 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15614 == GET_MODE_BITSIZE (<MODE>mode)-1
15615 && ix86_pre_reload_split ()"
15619 [(set (match_dup 0)
15620 (any_rotate:SWI (match_dup 1)
15622 (clobber (reg:CC FLAGS_REG))])]
15624 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15625 operands[2] = gen_lowpart (QImode, operands[2]);
15629 [(set (match_operand:SWI 0 "register_operand")
15631 (match_operand:SWI 1 "const_int_operand")
15634 (match_operand 2 "int248_register_operand")
15635 (match_operand 3 "const_int_operand")) 0)))]
15636 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15637 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15638 [(set (match_dup 4) (match_dup 1))
15640 (any_rotate:SWI (match_dup 4)
15641 (subreg:QI (match_dup 2) 0)))]
15642 "operands[4] = gen_reg_rtx (<MODE>mode);")
15644 (define_insn_and_split "*<insn><mode>3_mask_1"
15645 [(set (match_operand:SWI 0 "nonimmediate_operand")
15647 (match_operand:SWI 1 "nonimmediate_operand")
15649 (match_operand:QI 2 "register_operand" "c")
15650 (match_operand:QI 3 "const_int_operand"))))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15654 == GET_MODE_BITSIZE (<MODE>mode)-1
15655 && ix86_pre_reload_split ()"
15659 [(set (match_dup 0)
15660 (any_rotate:SWI (match_dup 1)
15662 (clobber (reg:CC FLAGS_REG))])])
15665 [(set (match_operand:SWI 0 "register_operand")
15667 (match_operand:SWI 1 "const_int_operand")
15669 (match_operand:QI 2 "register_operand")
15670 (match_operand:QI 3 "const_int_operand"))))]
15671 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15672 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15673 [(set (match_dup 4) (match_dup 1))
15675 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15676 "operands[4] = gen_reg_rtx (<MODE>mode);")
15678 ;; Implement rotation using two double-precision
15679 ;; shift instructions and a scratch register.
15681 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15682 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15683 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15684 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15685 (clobber (reg:CC FLAGS_REG))
15686 (clobber (match_scratch:DWIH 3 "=&r"))]
15690 [(set (match_dup 3) (match_dup 4))
15692 [(set (match_dup 4)
15693 (ior:DWIH (ashift:DWIH (match_dup 4)
15694 (and:QI (match_dup 2) (match_dup 6)))
15696 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15697 (minus:QI (match_dup 7)
15698 (and:QI (match_dup 2)
15699 (match_dup 6)))) 0)))
15700 (clobber (reg:CC FLAGS_REG))])
15702 [(set (match_dup 5)
15703 (ior:DWIH (ashift:DWIH (match_dup 5)
15704 (and:QI (match_dup 2) (match_dup 6)))
15706 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15707 (minus:QI (match_dup 7)
15708 (and:QI (match_dup 2)
15709 (match_dup 6)))) 0)))
15710 (clobber (reg:CC FLAGS_REG))])]
15712 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15713 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15715 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15718 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15719 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15720 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15721 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15722 (clobber (reg:CC FLAGS_REG))
15723 (clobber (match_scratch:DWIH 3 "=&r"))]
15727 [(set (match_dup 3) (match_dup 4))
15729 [(set (match_dup 4)
15730 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15731 (and:QI (match_dup 2) (match_dup 6)))
15733 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15734 (minus:QI (match_dup 7)
15735 (and:QI (match_dup 2)
15736 (match_dup 6)))) 0)))
15737 (clobber (reg:CC FLAGS_REG))])
15739 [(set (match_dup 5)
15740 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15741 (and:QI (match_dup 2) (match_dup 6)))
15743 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15744 (minus:QI (match_dup 7)
15745 (and:QI (match_dup 2)
15746 (match_dup 6)))) 0)))
15747 (clobber (reg:CC FLAGS_REG))])]
15749 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15750 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15752 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15755 (define_insn_and_split "<insn>32di2_doubleword"
15756 [(set (match_operand:DI 0 "register_operand" "=r,r")
15757 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15761 "&& reload_completed"
15762 [(set (match_dup 0) (match_dup 3))
15763 (set (match_dup 2) (match_dup 1))]
15765 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15766 if (rtx_equal_p (operands[0], operands[1]))
15768 emit_insn (gen_swapsi (operands[0], operands[2]));
15773 (define_insn_and_split "<insn>64ti2_doubleword"
15774 [(set (match_operand:TI 0 "register_operand" "=r,r")
15775 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15779 "&& reload_completed"
15780 [(set (match_dup 0) (match_dup 3))
15781 (set (match_dup 2) (match_dup 1))]
15783 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15784 if (rtx_equal_p (operands[0], operands[1]))
15786 emit_insn (gen_swapdi (operands[0], operands[2]));
15791 (define_mode_attr rorx_immediate_operand
15792 [(SI "const_0_to_31_operand")
15793 (DI "const_0_to_63_operand")])
15795 (define_insn "*bmi2_rorx<mode>3_1"
15796 [(set (match_operand:SWI48 0 "register_operand" "=r")
15798 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15799 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15800 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15801 "rorx\t{%2, %1, %0|%0, %1, %2}"
15802 [(set_attr "type" "rotatex")
15803 (set_attr "mode" "<MODE>")])
15805 (define_insn "*<insn><mode>3_1"
15806 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15808 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15809 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15810 (clobber (reg:CC FLAGS_REG))]
15811 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15813 switch (get_attr_type (insn))
15819 if (operands[2] == const1_rtx
15820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15821 return "<rotate>{<imodesuffix>}\t%0";
15823 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15826 [(set_attr "isa" "*,bmi2")
15827 (set_attr "type" "rotate,rotatex")
15828 (set (attr "preferred_for_size")
15829 (cond [(eq_attr "alternative" "0")
15830 (symbol_ref "true")]
15831 (symbol_ref "false")))
15832 (set (attr "length_immediate")
15834 (and (eq_attr "type" "rotate")
15835 (and (match_operand 2 "const1_operand")
15836 (ior (match_test "TARGET_SHIFT1")
15837 (match_test "optimize_function_for_size_p (cfun)"))))
15839 (const_string "*")))
15840 (set_attr "mode" "<MODE>")])
15842 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15844 [(set (match_operand:SWI48 0 "register_operand")
15845 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15846 (match_operand:QI 2 "const_int_operand")))
15847 (clobber (reg:CC FLAGS_REG))]
15848 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15849 [(set (match_dup 0)
15850 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15852 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15854 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15858 [(set (match_operand:SWI48 0 "register_operand")
15859 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15860 (match_operand:QI 2 "const_int_operand")))
15861 (clobber (reg:CC FLAGS_REG))]
15862 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15863 [(set (match_dup 0)
15864 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15866 (define_insn "*bmi2_rorxsi3_1_zext"
15867 [(set (match_operand:DI 0 "register_operand" "=r")
15869 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15870 (match_operand:QI 2 "const_0_to_31_operand"))))]
15871 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15872 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15873 [(set_attr "type" "rotatex")
15874 (set_attr "mode" "SI")])
15876 (define_insn "*<insn>si3_1_zext"
15877 [(set (match_operand:DI 0 "register_operand" "=r,r")
15879 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15880 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15881 (clobber (reg:CC FLAGS_REG))]
15882 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15884 switch (get_attr_type (insn))
15890 if (operands[2] == const1_rtx
15891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15892 return "<rotate>{l}\t%k0";
15894 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15897 [(set_attr "isa" "*,bmi2")
15898 (set_attr "type" "rotate,rotatex")
15899 (set (attr "preferred_for_size")
15900 (cond [(eq_attr "alternative" "0")
15901 (symbol_ref "true")]
15902 (symbol_ref "false")))
15903 (set (attr "length_immediate")
15905 (and (eq_attr "type" "rotate")
15906 (and (match_operand 2 "const1_operand")
15907 (ior (match_test "TARGET_SHIFT1")
15908 (match_test "optimize_function_for_size_p (cfun)"))))
15910 (const_string "*")))
15911 (set_attr "mode" "SI")])
15913 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15915 [(set (match_operand:DI 0 "register_operand")
15917 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15918 (match_operand:QI 2 "const_int_operand"))))
15919 (clobber (reg:CC FLAGS_REG))]
15920 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15921 && !optimize_function_for_size_p (cfun)"
15922 [(set (match_dup 0)
15923 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15925 int bitsize = GET_MODE_BITSIZE (SImode);
15927 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15931 [(set (match_operand:DI 0 "register_operand")
15933 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15934 (match_operand:QI 2 "const_int_operand"))))
15935 (clobber (reg:CC FLAGS_REG))]
15936 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15937 && !optimize_function_for_size_p (cfun)"
15938 [(set (match_dup 0)
15939 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15941 (define_insn "*<insn><mode>3_1"
15942 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15943 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15944 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15945 (clobber (reg:CC FLAGS_REG))]
15946 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15948 if (operands[2] == const1_rtx
15949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15950 return "<rotate>{<imodesuffix>}\t%0";
15952 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15954 [(set_attr "type" "rotate")
15955 (set (attr "length_immediate")
15957 (and (match_operand 2 "const1_operand")
15958 (ior (match_test "TARGET_SHIFT1")
15959 (match_test "optimize_function_for_size_p (cfun)")))
15961 (const_string "*")))
15962 (set_attr "mode" "<MODE>")])
15964 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15965 (define_insn_and_split "*<insn><mode>3_1_slp"
15966 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15967 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15968 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15969 (clobber (reg:CC FLAGS_REG))]
15970 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15972 if (which_alternative)
15975 if (operands[2] == const1_rtx
15976 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15977 return "<rotate>{<imodesuffix>}\t%0";
15979 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15981 "&& reload_completed"
15982 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15984 [(set (strict_low_part (match_dup 0))
15985 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15986 (clobber (reg:CC FLAGS_REG))])]
15988 [(set_attr "type" "rotate")
15989 (set (attr "length_immediate")
15991 (and (match_operand 2 "const1_operand")
15992 (ior (match_test "TARGET_SHIFT1")
15993 (match_test "optimize_function_for_size_p (cfun)")))
15995 (const_string "*")))
15996 (set_attr "mode" "<MODE>")])
15999 [(set (match_operand:HI 0 "QIreg_operand")
16000 (any_rotate:HI (match_dup 0) (const_int 8)))
16001 (clobber (reg:CC FLAGS_REG))]
16003 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16004 [(parallel [(set (strict_low_part (match_dup 0))
16005 (bswap:HI (match_dup 0)))
16006 (clobber (reg:CC FLAGS_REG))])])
16008 ;; Rotations through carry flag
16009 (define_insn "rcrsi2"
16010 [(set (match_operand:SI 0 "register_operand" "=r")
16012 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16014 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16016 (clobber (reg:CC FLAGS_REG))]
16019 [(set_attr "type" "ishift1")
16020 (set_attr "memory" "none")
16021 (set_attr "length_immediate" "0")
16022 (set_attr "mode" "SI")])
16024 (define_insn "rcrdi2"
16025 [(set (match_operand:DI 0 "register_operand" "=r")
16027 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16029 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16031 (clobber (reg:CC FLAGS_REG))]
16034 [(set_attr "type" "ishift1")
16035 (set_attr "length_immediate" "0")
16036 (set_attr "mode" "DI")])
16038 ;; Versions of sar and shr that set the carry flag.
16039 (define_insn "<insn><mode>3_carry"
16040 [(set (reg:CCC FLAGS_REG)
16041 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16043 (const_int 0)] UNSPEC_CC_NE))
16044 (set (match_operand:SWI48 0 "register_operand" "=r")
16045 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16048 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16049 return "<shift>{<imodesuffix>}\t%0";
16050 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16052 [(set_attr "type" "ishift1")
16053 (set (attr "length_immediate")
16055 (ior (match_test "TARGET_SHIFT1")
16056 (match_test "optimize_function_for_size_p (cfun)"))
16058 (const_string "*")))
16059 (set_attr "mode" "<MODE>")])
16061 ;; Bit set / bit test instructions
16063 ;; %%% bts, btr, btc
16065 ;; These instructions are *slow* when applied to memory.
16067 (define_code_attr btsc [(ior "bts") (xor "btc")])
16069 (define_insn "*<btsc><mode>"
16070 [(set (match_operand:SWI48 0 "register_operand" "=r")
16072 (ashift:SWI48 (const_int 1)
16073 (match_operand:QI 2 "register_operand" "r"))
16074 (match_operand:SWI48 1 "register_operand" "0")))
16075 (clobber (reg:CC FLAGS_REG))]
16077 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16078 [(set_attr "type" "alu1")
16079 (set_attr "prefix_0f" "1")
16080 (set_attr "znver1_decode" "double")
16081 (set_attr "mode" "<MODE>")])
16083 ;; Avoid useless masking of count operand.
16084 (define_insn_and_split "*<btsc><mode>_mask"
16085 [(set (match_operand:SWI48 0 "register_operand")
16091 (match_operand 1 "int248_register_operand")
16092 (match_operand 2 "const_int_operand")) 0))
16093 (match_operand:SWI48 3 "register_operand")))
16094 (clobber (reg:CC FLAGS_REG))]
16096 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16097 == GET_MODE_BITSIZE (<MODE>mode)-1
16098 && ix86_pre_reload_split ()"
16102 [(set (match_dup 0)
16104 (ashift:SWI48 (const_int 1)
16107 (clobber (reg:CC FLAGS_REG))])]
16109 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16110 operands[1] = gen_lowpart (QImode, operands[1]);
16113 (define_insn_and_split "*<btsc><mode>_mask_1"
16114 [(set (match_operand:SWI48 0 "register_operand")
16119 (match_operand:QI 1 "register_operand")
16120 (match_operand:QI 2 "const_int_operand")))
16121 (match_operand:SWI48 3 "register_operand")))
16122 (clobber (reg:CC FLAGS_REG))]
16124 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16125 == GET_MODE_BITSIZE (<MODE>mode)-1
16126 && ix86_pre_reload_split ()"
16130 [(set (match_dup 0)
16132 (ashift:SWI48 (const_int 1)
16135 (clobber (reg:CC FLAGS_REG))])])
16137 (define_insn "*btr<mode>"
16138 [(set (match_operand:SWI48 0 "register_operand" "=r")
16140 (rotate:SWI48 (const_int -2)
16141 (match_operand:QI 2 "register_operand" "r"))
16142 (match_operand:SWI48 1 "register_operand" "0")))
16143 (clobber (reg:CC FLAGS_REG))]
16145 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16146 [(set_attr "type" "alu1")
16147 (set_attr "prefix_0f" "1")
16148 (set_attr "znver1_decode" "double")
16149 (set_attr "mode" "<MODE>")])
16151 ;; Avoid useless masking of count operand.
16152 (define_insn_and_split "*btr<mode>_mask"
16153 [(set (match_operand:SWI48 0 "register_operand")
16159 (match_operand 1 "int248_register_operand")
16160 (match_operand 2 "const_int_operand")) 0))
16161 (match_operand:SWI48 3 "register_operand")))
16162 (clobber (reg:CC FLAGS_REG))]
16164 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16165 == GET_MODE_BITSIZE (<MODE>mode)-1
16166 && ix86_pre_reload_split ()"
16170 [(set (match_dup 0)
16172 (rotate:SWI48 (const_int -2)
16175 (clobber (reg:CC FLAGS_REG))])]
16177 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16178 operands[1] = gen_lowpart (QImode, operands[1]);
16181 (define_insn_and_split "*btr<mode>_mask_1"
16182 [(set (match_operand:SWI48 0 "register_operand")
16187 (match_operand:QI 1 "register_operand")
16188 (match_operand:QI 2 "const_int_operand")))
16189 (match_operand:SWI48 3 "register_operand")))
16190 (clobber (reg:CC FLAGS_REG))]
16192 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16193 == GET_MODE_BITSIZE (<MODE>mode)-1
16194 && ix86_pre_reload_split ()"
16198 [(set (match_dup 0)
16200 (rotate:SWI48 (const_int -2)
16203 (clobber (reg:CC FLAGS_REG))])])
16205 (define_insn_and_split "*btr<mode>_1"
16206 [(set (match_operand:SWI12 0 "register_operand")
16209 (rotate:SI (const_int -2)
16210 (match_operand:QI 2 "register_operand")) 0)
16211 (match_operand:SWI12 1 "nonimmediate_operand")))
16212 (clobber (reg:CC FLAGS_REG))]
16213 "TARGET_USE_BT && ix86_pre_reload_split ()"
16217 [(set (match_dup 0)
16218 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16220 (clobber (reg:CC FLAGS_REG))])]
16222 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16223 operands[1] = force_reg (<MODE>mode, operands[1]);
16224 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16227 (define_insn_and_split "*btr<mode>_2"
16228 [(set (zero_extract:HI
16229 (match_operand:SWI12 0 "nonimmediate_operand")
16231 (match_operand:QI 1 "register_operand"))
16233 (clobber (reg:CC FLAGS_REG))]
16234 "TARGET_USE_BT && ix86_pre_reload_split ()"
16236 "&& MEM_P (operands[0])"
16237 [(set (match_dup 2) (match_dup 0))
16239 [(set (match_dup 3)
16240 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16242 (clobber (reg:CC FLAGS_REG))])
16243 (set (match_dup 0) (match_dup 5))]
16245 operands[2] = gen_reg_rtx (<MODE>mode);
16246 operands[5] = gen_reg_rtx (<MODE>mode);
16247 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16248 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16252 [(set (zero_extract:HI
16253 (match_operand:SWI12 0 "register_operand")
16255 (match_operand:QI 1 "register_operand"))
16257 (clobber (reg:CC FLAGS_REG))]
16258 "TARGET_USE_BT && ix86_pre_reload_split ()"
16260 [(set (match_dup 0)
16261 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16263 (clobber (reg:CC FLAGS_REG))])]
16265 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16266 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16269 ;; These instructions are never faster than the corresponding
16270 ;; and/ior/xor operations when using immediate operand, so with
16271 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16272 ;; relevant immediates within the instruction itself, so operating
16273 ;; on bits in the high 32-bits of a register becomes easier.
16275 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16276 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16277 ;; negdf respectively, so they can never be disabled entirely.
16279 (define_insn "*btsq_imm"
16280 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16282 (match_operand:QI 1 "const_0_to_63_operand"))
16284 (clobber (reg:CC FLAGS_REG))]
16285 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16286 "bts{q}\t{%1, %0|%0, %1}"
16287 [(set_attr "type" "alu1")
16288 (set_attr "prefix_0f" "1")
16289 (set_attr "znver1_decode" "double")
16290 (set_attr "mode" "DI")])
16292 (define_insn "*btrq_imm"
16293 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16295 (match_operand:QI 1 "const_0_to_63_operand"))
16297 (clobber (reg:CC FLAGS_REG))]
16298 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16299 "btr{q}\t{%1, %0|%0, %1}"
16300 [(set_attr "type" "alu1")
16301 (set_attr "prefix_0f" "1")
16302 (set_attr "znver1_decode" "double")
16303 (set_attr "mode" "DI")])
16305 (define_insn "*btcq_imm"
16306 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16308 (match_operand:QI 1 "const_0_to_63_operand"))
16309 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16310 (clobber (reg:CC FLAGS_REG))]
16311 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16312 "btc{q}\t{%1, %0|%0, %1}"
16313 [(set_attr "type" "alu1")
16314 (set_attr "prefix_0f" "1")
16315 (set_attr "znver1_decode" "double")
16316 (set_attr "mode" "DI")])
16318 ;; Allow Nocona to avoid these instructions if a register is available.
16321 [(match_scratch:DI 2 "r")
16322 (parallel [(set (zero_extract:DI
16323 (match_operand:DI 0 "nonimmediate_operand")
16325 (match_operand:QI 1 "const_0_to_63_operand"))
16327 (clobber (reg:CC FLAGS_REG))])]
16328 "TARGET_64BIT && !TARGET_USE_BT"
16329 [(parallel [(set (match_dup 0)
16330 (ior:DI (match_dup 0) (match_dup 3)))
16331 (clobber (reg:CC FLAGS_REG))])]
16333 int i = INTVAL (operands[1]);
16335 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16337 if (!x86_64_immediate_operand (operands[3], DImode))
16339 emit_move_insn (operands[2], operands[3]);
16340 operands[3] = operands[2];
16345 [(match_scratch:DI 2 "r")
16346 (parallel [(set (zero_extract:DI
16347 (match_operand:DI 0 "nonimmediate_operand")
16349 (match_operand:QI 1 "const_0_to_63_operand"))
16351 (clobber (reg:CC FLAGS_REG))])]
16352 "TARGET_64BIT && !TARGET_USE_BT"
16353 [(parallel [(set (match_dup 0)
16354 (and:DI (match_dup 0) (match_dup 3)))
16355 (clobber (reg:CC FLAGS_REG))])]
16357 int i = INTVAL (operands[1]);
16359 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16361 if (!x86_64_immediate_operand (operands[3], DImode))
16363 emit_move_insn (operands[2], operands[3]);
16364 operands[3] = operands[2];
16369 [(match_scratch:DI 2 "r")
16370 (parallel [(set (zero_extract:DI
16371 (match_operand:DI 0 "nonimmediate_operand")
16373 (match_operand:QI 1 "const_0_to_63_operand"))
16374 (not:DI (zero_extract:DI
16375 (match_dup 0) (const_int 1) (match_dup 1))))
16376 (clobber (reg:CC FLAGS_REG))])]
16377 "TARGET_64BIT && !TARGET_USE_BT"
16378 [(parallel [(set (match_dup 0)
16379 (xor:DI (match_dup 0) (match_dup 3)))
16380 (clobber (reg:CC FLAGS_REG))])]
16382 int i = INTVAL (operands[1]);
16384 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16386 if (!x86_64_immediate_operand (operands[3], DImode))
16388 emit_move_insn (operands[2], operands[3]);
16389 operands[3] = operands[2];
16395 (define_insn "*bt<mode>"
16396 [(set (reg:CCC FLAGS_REG)
16398 (zero_extract:SWI48
16399 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16401 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16405 switch (get_attr_mode (insn))
16408 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16411 return "bt{q}\t{%q1, %0|%0, %q1}";
16414 gcc_unreachable ();
16417 [(set_attr "type" "alu1")
16418 (set_attr "prefix_0f" "1")
16421 (and (match_test "CONST_INT_P (operands[1])")
16422 (match_test "INTVAL (operands[1]) < 32"))
16423 (const_string "SI")
16424 (const_string "<MODE>")))])
16426 (define_insn_and_split "*bt<SWI48:mode>_mask"
16427 [(set (reg:CCC FLAGS_REG)
16429 (zero_extract:SWI48
16430 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16434 (match_operand:SWI248 1 "register_operand")
16435 (match_operand 2 "const_int_operand")) 0))
16438 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16439 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16440 && ix86_pre_reload_split ()"
16443 [(set (reg:CCC FLAGS_REG)
16445 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16447 "operands[1] = gen_lowpart (QImode, operands[1]);")
16449 (define_insn_and_split "*jcc_bt<mode>"
16451 (if_then_else (match_operator 0 "bt_comparison_operator"
16452 [(zero_extract:SWI48
16453 (match_operand:SWI48 1 "nonimmediate_operand")
16455 (match_operand:QI 2 "nonmemory_operand"))
16457 (label_ref (match_operand 3))
16459 (clobber (reg:CC FLAGS_REG))]
16460 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16461 && (CONST_INT_P (operands[2])
16462 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16463 && INTVAL (operands[2])
16464 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16465 : !memory_operand (operands[1], <MODE>mode))
16466 && ix86_pre_reload_split ()"
16469 [(set (reg:CCC FLAGS_REG)
16471 (zero_extract:SWI48
16477 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16478 (label_ref (match_dup 3))
16481 operands[0] = shallow_copy_rtx (operands[0]);
16482 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16485 ;; Avoid useless masking of bit offset operand.
16486 (define_insn_and_split "*jcc_bt<mode>_mask"
16488 (if_then_else (match_operator 0 "bt_comparison_operator"
16489 [(zero_extract:SWI48
16490 (match_operand:SWI48 1 "register_operand")
16493 (match_operand:QI 2 "register_operand")
16494 (match_operand 3 "const_int_operand")))])
16495 (label_ref (match_operand 4))
16497 (clobber (reg:CC FLAGS_REG))]
16498 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16499 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16500 == GET_MODE_BITSIZE (<MODE>mode)-1
16501 && ix86_pre_reload_split ()"
16504 [(set (reg:CCC FLAGS_REG)
16506 (zero_extract:SWI48
16512 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16513 (label_ref (match_dup 4))
16516 operands[0] = shallow_copy_rtx (operands[0]);
16517 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16520 ;; Avoid useless masking of bit offset operand.
16521 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16523 (if_then_else (match_operator 0 "bt_comparison_operator"
16524 [(zero_extract:SWI48
16525 (match_operand:SWI48 1 "register_operand")
16529 (match_operand:SWI248 2 "register_operand")
16530 (match_operand 3 "const_int_operand")) 0))])
16531 (label_ref (match_operand 4))
16533 (clobber (reg:CC FLAGS_REG))]
16534 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16535 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16536 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16537 && ix86_pre_reload_split ()"
16540 [(set (reg:CCC FLAGS_REG)
16542 (zero_extract:SWI48
16548 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16549 (label_ref (match_dup 4))
16552 operands[0] = shallow_copy_rtx (operands[0]);
16553 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16554 operands[2] = gen_lowpart (QImode, operands[2]);
16557 ;; Help combine recognize bt followed by cmov
16559 [(set (match_operand:SWI248 0 "register_operand")
16560 (if_then_else:SWI248
16561 (match_operator 5 "bt_comparison_operator"
16562 [(zero_extract:SWI48
16563 (match_operand:SWI48 1 "register_operand")
16565 (match_operand:QI 2 "register_operand"))
16567 (match_operand:SWI248 3 "nonimmediate_operand")
16568 (match_operand:SWI248 4 "nonimmediate_operand")))]
16569 "TARGET_USE_BT && TARGET_CMOVE
16570 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16571 && ix86_pre_reload_split ()"
16572 [(set (reg:CCC FLAGS_REG)
16574 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16577 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16581 if (GET_CODE (operands[5]) == EQ)
16582 std::swap (operands[3], operands[4]);
16585 ;; Help combine recognize bt followed by setc
16586 (define_insn_and_split "*bt<mode>_setcqi"
16587 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16588 (zero_extract:SWI48
16589 (match_operand:SWI48 1 "register_operand")
16591 (match_operand:QI 2 "register_operand")))
16592 (clobber (reg:CC FLAGS_REG))]
16593 "TARGET_USE_BT && ix86_pre_reload_split ()"
16596 [(set (reg:CCC FLAGS_REG)
16598 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16601 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16603 ;; Help combine recognize bt followed by setnc
16604 (define_insn_and_split "*bt<mode>_setncqi"
16605 [(set (match_operand:QI 0 "register_operand")
16609 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16610 (match_operand:QI 2 "register_operand")) 0))
16612 (clobber (reg:CC FLAGS_REG))]
16613 "TARGET_USE_BT && ix86_pre_reload_split ()"
16616 [(set (reg:CCC FLAGS_REG)
16618 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16621 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16623 (define_insn_and_split "*bt<mode>_setnc<mode>"
16624 [(set (match_operand:SWI48 0 "register_operand")
16627 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16628 (match_operand:QI 2 "register_operand")))
16630 (clobber (reg:CC FLAGS_REG))]
16631 "TARGET_USE_BT && ix86_pre_reload_split ()"
16634 [(set (reg:CCC FLAGS_REG)
16636 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16639 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16640 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16641 "operands[3] = gen_reg_rtx (QImode);")
16643 ;; Help combine recognize bt followed by setnc (PR target/110588)
16644 (define_insn_and_split "*bt<mode>_setncqi_2"
16645 [(set (match_operand:QI 0 "register_operand")
16647 (zero_extract:SWI48
16648 (match_operand:SWI48 1 "register_operand")
16650 (match_operand:QI 2 "register_operand"))
16652 (clobber (reg:CC FLAGS_REG))]
16653 "TARGET_USE_BT && ix86_pre_reload_split ()"
16656 [(set (reg:CCC FLAGS_REG)
16658 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16661 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16663 ;; Help combine recognize bt followed by setc
16664 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16665 [(set (match_operand:SWI48 0 "register_operand")
16666 (zero_extract:SWI48
16667 (match_operand:SWI48 1 "register_operand")
16671 (match_operand:SWI48 2 "register_operand")
16672 (match_operand 3 "const_int_operand")) 0)))
16673 (clobber (reg:CC FLAGS_REG))]
16675 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16676 == GET_MODE_BITSIZE (<MODE>mode)-1
16677 && ix86_pre_reload_split ()"
16680 [(set (reg:CCC FLAGS_REG)
16682 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16685 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16686 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16688 operands[2] = gen_lowpart (QImode, operands[2]);
16689 operands[3] = gen_reg_rtx (QImode);
16692 ;; Store-flag instructions.
16695 [(set (match_operand:QI 0 "nonimmediate_operand")
16696 (match_operator:QI 1 "add_comparison_operator"
16697 [(not:SWI (match_operand:SWI 2 "register_operand"))
16698 (match_operand:SWI 3 "nonimmediate_operand")]))]
16700 [(set (reg:CCC FLAGS_REG)
16702 (plus:SWI (match_dup 2) (match_dup 3))
16705 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16708 [(set (match_operand:QI 0 "nonimmediate_operand")
16709 (match_operator:QI 1 "shr_comparison_operator"
16710 [(match_operand:DI 2 "register_operand")
16711 (match_operand 3 "const_int_operand")]))]
16713 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16714 [(set (reg:CCZ FLAGS_REG)
16716 (lshiftrt:DI (match_dup 2) (match_dup 4))
16719 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16721 enum rtx_code new_code;
16723 operands[1] = shallow_copy_rtx (operands[1]);
16724 switch (GET_CODE (operands[1]))
16726 case GTU: new_code = NE; break;
16727 case LEU: new_code = EQ; break;
16728 default: gcc_unreachable ();
16730 PUT_CODE (operands[1], new_code);
16732 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16735 ;; For all sCOND expanders, also expand the compare or test insn that
16736 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16738 (define_insn_and_split "*setcc_di_1"
16739 [(set (match_operand:DI 0 "register_operand" "=q")
16740 (match_operator:DI 1 "ix86_comparison_operator"
16741 [(reg FLAGS_REG) (const_int 0)]))]
16742 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16744 "&& reload_completed"
16745 [(set (match_dup 2) (match_dup 1))
16746 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16748 operands[1] = shallow_copy_rtx (operands[1]);
16749 PUT_MODE (operands[1], QImode);
16750 operands[2] = gen_lowpart (QImode, operands[0]);
16753 (define_insn_and_split "*setcc_<mode>_1_and"
16754 [(set (match_operand:SWI24 0 "register_operand" "=q")
16755 (match_operator:SWI24 1 "ix86_comparison_operator"
16756 [(reg FLAGS_REG) (const_int 0)]))
16757 (clobber (reg:CC FLAGS_REG))]
16758 "!TARGET_PARTIAL_REG_STALL
16759 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16761 "&& reload_completed"
16762 [(set (match_dup 2) (match_dup 1))
16763 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16764 (clobber (reg:CC FLAGS_REG))])]
16766 operands[1] = shallow_copy_rtx (operands[1]);
16767 PUT_MODE (operands[1], QImode);
16768 operands[2] = gen_lowpart (QImode, operands[0]);
16771 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16772 [(set (match_operand:SWI24 0 "register_operand" "=q")
16773 (match_operator:SWI24 1 "ix86_comparison_operator"
16774 [(reg FLAGS_REG) (const_int 0)]))]
16775 "!TARGET_PARTIAL_REG_STALL
16776 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16778 "&& reload_completed"
16779 [(set (match_dup 2) (match_dup 1))
16780 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16782 operands[1] = shallow_copy_rtx (operands[1]);
16783 PUT_MODE (operands[1], QImode);
16784 operands[2] = gen_lowpart (QImode, operands[0]);
16787 (define_insn "*setcc_qi"
16788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16789 (match_operator:QI 1 "ix86_comparison_operator"
16790 [(reg FLAGS_REG) (const_int 0)]))]
16793 [(set_attr "type" "setcc")
16794 (set_attr "mode" "QI")])
16796 (define_insn "*setcc_qi_slp"
16797 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16798 (match_operator:QI 1 "ix86_comparison_operator"
16799 [(reg FLAGS_REG) (const_int 0)]))]
16802 [(set_attr "type" "setcc")
16803 (set_attr "mode" "QI")])
16805 ;; In general it is not safe to assume too much about CCmode registers,
16806 ;; so simplify-rtx stops when it sees a second one. Under certain
16807 ;; conditions this is safe on x86, so help combine not create
16814 [(set (match_operand:QI 0 "nonimmediate_operand")
16815 (ne:QI (match_operator 1 "ix86_comparison_operator"
16816 [(reg FLAGS_REG) (const_int 0)])
16819 [(set (match_dup 0) (match_dup 1))]
16821 operands[1] = shallow_copy_rtx (operands[1]);
16822 PUT_MODE (operands[1], QImode);
16826 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16827 (ne:QI (match_operator 1 "ix86_comparison_operator"
16828 [(reg FLAGS_REG) (const_int 0)])
16831 [(set (match_dup 0) (match_dup 1))]
16833 operands[1] = shallow_copy_rtx (operands[1]);
16834 PUT_MODE (operands[1], QImode);
16838 [(set (match_operand:QI 0 "nonimmediate_operand")
16839 (eq:QI (match_operator 1 "ix86_comparison_operator"
16840 [(reg FLAGS_REG) (const_int 0)])
16843 [(set (match_dup 0) (match_dup 1))]
16845 operands[1] = shallow_copy_rtx (operands[1]);
16846 PUT_MODE (operands[1], QImode);
16847 PUT_CODE (operands[1],
16848 ix86_reverse_condition (GET_CODE (operands[1]),
16849 GET_MODE (XEXP (operands[1], 0))));
16851 /* Make sure that (a) the CCmode we have for the flags is strong
16852 enough for the reversed compare or (b) we have a valid FP compare. */
16853 if (! ix86_comparison_operator (operands[1], VOIDmode))
16858 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16859 (eq:QI (match_operator 1 "ix86_comparison_operator"
16860 [(reg FLAGS_REG) (const_int 0)])
16863 [(set (match_dup 0) (match_dup 1))]
16865 operands[1] = shallow_copy_rtx (operands[1]);
16866 PUT_MODE (operands[1], QImode);
16867 PUT_CODE (operands[1],
16868 ix86_reverse_condition (GET_CODE (operands[1]),
16869 GET_MODE (XEXP (operands[1], 0))));
16871 /* Make sure that (a) the CCmode we have for the flags is strong
16872 enough for the reversed compare or (b) we have a valid FP compare. */
16873 if (! ix86_comparison_operator (operands[1], VOIDmode))
16877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16878 ;; subsequent logical operations are used to imitate conditional moves.
16879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16882 (define_insn "setcc_<mode>_sse"
16883 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16884 (match_operator:MODEF 3 "sse_comparison_operator"
16885 [(match_operand:MODEF 1 "register_operand" "0,x")
16886 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16887 "SSE_FLOAT_MODE_P (<MODE>mode)"
16889 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16890 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16891 [(set_attr "isa" "noavx,avx")
16892 (set_attr "gpr32" "1,0")
16893 (set_attr "type" "ssecmp")
16894 (set_attr "length_immediate" "1")
16895 (set_attr "prefix" "orig,vex")
16896 (set_attr "mode" "<MODE>")])
16898 (define_insn "setcc_hf_mask"
16899 [(set (match_operand:QI 0 "register_operand" "=k")
16901 [(match_operand:HF 1 "register_operand" "v")
16902 (match_operand:HF 2 "nonimmediate_operand" "vm")
16903 (match_operand:SI 3 "const_0_to_31_operand")]
16905 "TARGET_AVX512FP16"
16906 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16907 [(set_attr "type" "ssecmp")
16908 (set_attr "prefix" "evex")
16909 (set_attr "mode" "HF")])
16912 ;; Basic conditional jump instructions.
16917 (match_operator 1 "add_comparison_operator"
16918 [(not:SWI (match_operand:SWI 2 "register_operand"))
16919 (match_operand:SWI 3 "nonimmediate_operand")])
16920 (label_ref (match_operand 0))
16923 [(set (reg:CCC FLAGS_REG)
16925 (plus:SWI (match_dup 2) (match_dup 3))
16928 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16929 (label_ref (match_operand 0))
16935 (match_operator 1 "shr_comparison_operator"
16936 [(match_operand:DI 2 "register_operand")
16937 (match_operand 3 "const_int_operand")])
16938 (label_ref (match_operand 0))
16941 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16942 [(set (reg:CCZ FLAGS_REG)
16944 (lshiftrt:DI (match_dup 2) (match_dup 4))
16947 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16948 (label_ref (match_operand 0))
16951 enum rtx_code new_code;
16953 operands[1] = shallow_copy_rtx (operands[1]);
16954 switch (GET_CODE (operands[1]))
16956 case GTU: new_code = NE; break;
16957 case LEU: new_code = EQ; break;
16958 default: gcc_unreachable ();
16960 PUT_CODE (operands[1], new_code);
16962 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16965 ;; We ignore the overflow flag for signed branch instructions.
16967 (define_insn "*jcc"
16969 (if_then_else (match_operator 1 "ix86_comparison_operator"
16970 [(reg FLAGS_REG) (const_int 0)])
16971 (label_ref (match_operand 0))
16975 [(set_attr "type" "ibr")
16976 (set_attr "modrm" "0")
16977 (set (attr "length")
16979 (and (ge (minus (match_dup 0) (pc))
16981 (lt (minus (match_dup 0) (pc))
16986 ;; In general it is not safe to assume too much about CCmode registers,
16987 ;; so simplify-rtx stops when it sees a second one. Under certain
16988 ;; conditions this is safe on x86, so help combine not create
16996 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16997 [(reg FLAGS_REG) (const_int 0)])
16999 (label_ref (match_operand 1))
17003 (if_then_else (match_dup 0)
17004 (label_ref (match_dup 1))
17007 operands[0] = shallow_copy_rtx (operands[0]);
17008 PUT_MODE (operands[0], VOIDmode);
17013 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17014 [(reg FLAGS_REG) (const_int 0)])
17016 (label_ref (match_operand 1))
17020 (if_then_else (match_dup 0)
17021 (label_ref (match_dup 1))
17024 operands[0] = shallow_copy_rtx (operands[0]);
17025 PUT_MODE (operands[0], VOIDmode);
17026 PUT_CODE (operands[0],
17027 ix86_reverse_condition (GET_CODE (operands[0]),
17028 GET_MODE (XEXP (operands[0], 0))));
17030 /* Make sure that (a) the CCmode we have for the flags is strong
17031 enough for the reversed compare or (b) we have a valid FP compare. */
17032 if (! ix86_comparison_operator (operands[0], VOIDmode))
17036 ;; Unconditional and other jump instructions
17038 (define_insn "jump"
17040 (label_ref (match_operand 0)))]
17043 [(set_attr "type" "ibr")
17044 (set_attr "modrm" "0")
17045 (set (attr "length")
17047 (and (ge (minus (match_dup 0) (pc))
17049 (lt (minus (match_dup 0) (pc))
17054 (define_expand "indirect_jump"
17055 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17058 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17059 operands[0] = convert_memory_address (word_mode, operands[0]);
17060 cfun->machine->has_local_indirect_jump = true;
17063 (define_insn "*indirect_jump"
17064 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17066 "* return ix86_output_indirect_jmp (operands[0]);"
17067 [(set (attr "type")
17068 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17069 != indirect_branch_keep)")
17070 (const_string "multi")
17071 (const_string "ibr")))
17072 (set_attr "length_immediate" "0")])
17074 (define_expand "tablejump"
17075 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17076 (use (label_ref (match_operand 1)))])]
17079 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17080 relative. Convert the relative address to an absolute address. */
17084 enum rtx_code code;
17086 /* We can't use @GOTOFF for text labels on VxWorks;
17087 see gotoff_operand. */
17088 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17092 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17094 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17098 op1 = pic_offset_table_rtx;
17103 op0 = pic_offset_table_rtx;
17107 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17111 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17112 operands[0] = convert_memory_address (word_mode, operands[0]);
17113 cfun->machine->has_local_indirect_jump = true;
17116 (define_insn "*tablejump_1"
17117 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17118 (use (label_ref (match_operand 1)))]
17120 "* return ix86_output_indirect_jmp (operands[0]);"
17121 [(set (attr "type")
17122 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17123 != indirect_branch_keep)")
17124 (const_string "multi")
17125 (const_string "ibr")))
17126 (set_attr "length_immediate" "0")])
17128 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17131 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17132 (set (match_operand:QI 1 "register_operand")
17133 (match_operator:QI 2 "ix86_comparison_operator"
17134 [(reg FLAGS_REG) (const_int 0)]))
17135 (set (match_operand 3 "any_QIreg_operand")
17136 (zero_extend (match_dup 1)))]
17137 "(peep2_reg_dead_p (3, operands[1])
17138 || operands_match_p (operands[1], operands[3]))
17139 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17140 && peep2_regno_dead_p (0, FLAGS_REG)"
17141 [(set (match_dup 4) (match_dup 0))
17142 (set (strict_low_part (match_dup 5))
17145 operands[5] = gen_lowpart (QImode, operands[3]);
17146 ix86_expand_clear (operands[3]);
17150 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17151 (match_operand 4)])
17152 (set (match_operand:QI 1 "register_operand")
17153 (match_operator:QI 2 "ix86_comparison_operator"
17154 [(reg FLAGS_REG) (const_int 0)]))
17155 (set (match_operand 3 "any_QIreg_operand")
17156 (zero_extend (match_dup 1)))]
17157 "(peep2_reg_dead_p (3, operands[1])
17158 || operands_match_p (operands[1], operands[3]))
17159 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17160 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17161 && ! reg_set_p (operands[3], operands[4])
17162 && peep2_regno_dead_p (0, FLAGS_REG)"
17163 [(parallel [(set (match_dup 5) (match_dup 0))
17165 (set (strict_low_part (match_dup 6))
17168 operands[6] = gen_lowpart (QImode, operands[3]);
17169 ix86_expand_clear (operands[3]);
17173 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17174 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17175 (match_operand 5)])
17176 (set (match_operand:QI 2 "register_operand")
17177 (match_operator:QI 3 "ix86_comparison_operator"
17178 [(reg FLAGS_REG) (const_int 0)]))
17179 (set (match_operand 4 "any_QIreg_operand")
17180 (zero_extend (match_dup 2)))]
17181 "(peep2_reg_dead_p (4, operands[2])
17182 || operands_match_p (operands[2], operands[4]))
17183 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17184 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17185 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17186 && ! reg_set_p (operands[4], operands[5])
17187 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17188 && peep2_regno_dead_p (0, FLAGS_REG)"
17189 [(set (match_dup 6) (match_dup 0))
17190 (parallel [(set (match_dup 7) (match_dup 1))
17192 (set (strict_low_part (match_dup 8))
17195 operands[8] = gen_lowpart (QImode, operands[4]);
17196 ix86_expand_clear (operands[4]);
17199 ;; Similar, but match zero extend with andsi3.
17202 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17203 (set (match_operand:QI 1 "register_operand")
17204 (match_operator:QI 2 "ix86_comparison_operator"
17205 [(reg FLAGS_REG) (const_int 0)]))
17206 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17207 (and:SI (match_dup 3) (const_int 255)))
17208 (clobber (reg:CC FLAGS_REG))])]
17209 "REGNO (operands[1]) == REGNO (operands[3])
17210 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17211 && peep2_regno_dead_p (0, FLAGS_REG)"
17212 [(set (match_dup 4) (match_dup 0))
17213 (set (strict_low_part (match_dup 5))
17216 operands[5] = gen_lowpart (QImode, operands[3]);
17217 ix86_expand_clear (operands[3]);
17221 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17222 (match_operand 4)])
17223 (set (match_operand:QI 1 "register_operand")
17224 (match_operator:QI 2 "ix86_comparison_operator"
17225 [(reg FLAGS_REG) (const_int 0)]))
17226 (parallel [(set (match_operand 3 "any_QIreg_operand")
17227 (zero_extend (match_dup 1)))
17228 (clobber (reg:CC FLAGS_REG))])]
17229 "(peep2_reg_dead_p (3, operands[1])
17230 || operands_match_p (operands[1], operands[3]))
17231 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17232 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17233 && ! reg_set_p (operands[3], operands[4])
17234 && peep2_regno_dead_p (0, FLAGS_REG)"
17235 [(parallel [(set (match_dup 5) (match_dup 0))
17237 (set (strict_low_part (match_dup 6))
17240 operands[6] = gen_lowpart (QImode, operands[3]);
17241 ix86_expand_clear (operands[3]);
17245 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17246 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17247 (match_operand 5)])
17248 (set (match_operand:QI 2 "register_operand")
17249 (match_operator:QI 3 "ix86_comparison_operator"
17250 [(reg FLAGS_REG) (const_int 0)]))
17251 (parallel [(set (match_operand 4 "any_QIreg_operand")
17252 (zero_extend (match_dup 2)))
17253 (clobber (reg:CC FLAGS_REG))])]
17254 "(peep2_reg_dead_p (4, operands[2])
17255 || operands_match_p (operands[2], operands[4]))
17256 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17257 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17258 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17259 && ! reg_set_p (operands[4], operands[5])
17260 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17261 && peep2_regno_dead_p (0, FLAGS_REG)"
17262 [(set (match_dup 6) (match_dup 0))
17263 (parallel [(set (match_dup 7) (match_dup 1))
17265 (set (strict_low_part (match_dup 8))
17268 operands[8] = gen_lowpart (QImode, operands[4]);
17269 ix86_expand_clear (operands[4]);
17272 ;; Call instructions.
17274 ;; The predicates normally associated with named expanders are not properly
17275 ;; checked for calls. This is a bug in the generic code, but it isn't that
17276 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17278 ;; P6 processors will jump to the address after the decrement when %esp
17279 ;; is used as a call operand, so they will execute return address as a code.
17280 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17282 ;; Register constraint for call instruction.
17283 (define_mode_attr c [(SI "l") (DI "r")])
17285 ;; Call subroutine returning no value.
17287 (define_expand "call"
17288 [(call (match_operand:QI 0)
17290 (use (match_operand 2))]
17293 ix86_expand_call (NULL, operands[0], operands[1],
17294 operands[2], NULL, false);
17298 (define_expand "sibcall"
17299 [(call (match_operand:QI 0)
17301 (use (match_operand 2))]
17304 ix86_expand_call (NULL, operands[0], operands[1],
17305 operands[2], NULL, true);
17309 (define_insn "*call"
17310 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17311 (match_operand 1))]
17312 "!SIBLING_CALL_P (insn)"
17313 "* return ix86_output_call_insn (insn, operands[0]);"
17314 [(set_attr "type" "call")])
17316 ;; This covers both call and sibcall since only GOT slot is allowed.
17317 (define_insn "*call_got_x32"
17318 [(call (mem:QI (zero_extend:DI
17319 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17320 (match_operand 1))]
17323 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17324 return ix86_output_call_insn (insn, fnaddr);
17326 [(set_attr "type" "call")])
17328 ;; Since sibcall never returns, we can only use call-clobbered register
17330 (define_insn "*sibcall_GOT_32"
17333 (match_operand:SI 0 "register_no_elim_operand" "U")
17334 (match_operand:SI 1 "GOT32_symbol_operand"))))
17335 (match_operand 2))]
17338 && !TARGET_INDIRECT_BRANCH_REGISTER
17339 && SIBLING_CALL_P (insn)"
17341 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17342 fnaddr = gen_const_mem (SImode, fnaddr);
17343 return ix86_output_call_insn (insn, fnaddr);
17345 [(set_attr "type" "call")])
17347 (define_insn "*sibcall"
17348 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17349 (match_operand 1))]
17350 "SIBLING_CALL_P (insn)"
17351 "* return ix86_output_call_insn (insn, operands[0]);"
17352 [(set_attr "type" "call")])
17354 (define_insn "*sibcall_memory"
17355 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17357 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17358 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17359 "* return ix86_output_call_insn (insn, operands[0]);"
17360 [(set_attr "type" "call")])
17363 [(set (match_operand:W 0 "register_operand")
17364 (match_operand:W 1 "memory_operand"))
17365 (call (mem:QI (match_dup 0))
17366 (match_operand 3))]
17368 && !TARGET_INDIRECT_BRANCH_REGISTER
17369 && SIBLING_CALL_P (peep2_next_insn (1))
17370 && !reg_mentioned_p (operands[0],
17371 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17372 [(parallel [(call (mem:QI (match_dup 1))
17374 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17377 [(set (match_operand:W 0 "register_operand")
17378 (match_operand:W 1 "memory_operand"))
17379 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17380 (call (mem:QI (match_dup 0))
17381 (match_operand 3))]
17383 && !TARGET_INDIRECT_BRANCH_REGISTER
17384 && SIBLING_CALL_P (peep2_next_insn (2))
17385 && !reg_mentioned_p (operands[0],
17386 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17387 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17388 (parallel [(call (mem:QI (match_dup 1))
17390 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17392 (define_expand "call_pop"
17393 [(parallel [(call (match_operand:QI 0)
17394 (match_operand:SI 1))
17395 (set (reg:SI SP_REG)
17396 (plus:SI (reg:SI SP_REG)
17397 (match_operand:SI 3)))])]
17400 ix86_expand_call (NULL, operands[0], operands[1],
17401 operands[2], operands[3], false);
17405 (define_insn "*call_pop"
17406 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17408 (set (reg:SI SP_REG)
17409 (plus:SI (reg:SI SP_REG)
17410 (match_operand:SI 2 "immediate_operand" "i")))]
17411 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17412 "* return ix86_output_call_insn (insn, operands[0]);"
17413 [(set_attr "type" "call")])
17415 (define_insn "*sibcall_pop"
17416 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17418 (set (reg:SI SP_REG)
17419 (plus:SI (reg:SI SP_REG)
17420 (match_operand:SI 2 "immediate_operand" "i")))]
17421 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17422 "* return ix86_output_call_insn (insn, operands[0]);"
17423 [(set_attr "type" "call")])
17425 (define_insn "*sibcall_pop_memory"
17426 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17428 (set (reg:SI SP_REG)
17429 (plus:SI (reg:SI SP_REG)
17430 (match_operand:SI 2 "immediate_operand" "i")))
17431 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17433 "* return ix86_output_call_insn (insn, operands[0]);"
17434 [(set_attr "type" "call")])
17437 [(set (match_operand:SI 0 "register_operand")
17438 (match_operand:SI 1 "memory_operand"))
17439 (parallel [(call (mem:QI (match_dup 0))
17441 (set (reg:SI SP_REG)
17442 (plus:SI (reg:SI SP_REG)
17443 (match_operand:SI 4 "immediate_operand")))])]
17444 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17445 && !reg_mentioned_p (operands[0],
17446 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17447 [(parallel [(call (mem:QI (match_dup 1))
17449 (set (reg:SI SP_REG)
17450 (plus:SI (reg:SI SP_REG)
17452 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17455 [(set (match_operand:SI 0 "register_operand")
17456 (match_operand:SI 1 "memory_operand"))
17457 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17458 (parallel [(call (mem:QI (match_dup 0))
17460 (set (reg:SI SP_REG)
17461 (plus:SI (reg:SI SP_REG)
17462 (match_operand:SI 4 "immediate_operand")))])]
17463 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17464 && !reg_mentioned_p (operands[0],
17465 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17466 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17467 (parallel [(call (mem:QI (match_dup 1))
17469 (set (reg:SI SP_REG)
17470 (plus:SI (reg:SI SP_REG)
17472 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17474 ;; Combining simple memory jump instruction
17477 [(set (match_operand:W 0 "register_operand")
17478 (match_operand:W 1 "memory_operand"))
17479 (set (pc) (match_dup 0))]
17481 && !TARGET_INDIRECT_BRANCH_REGISTER
17482 && peep2_reg_dead_p (2, operands[0])"
17483 [(set (pc) (match_dup 1))])
17485 ;; Call subroutine, returning value in operand 0
17487 (define_expand "call_value"
17488 [(set (match_operand 0)
17489 (call (match_operand:QI 1)
17490 (match_operand 2)))
17491 (use (match_operand 3))]
17494 ix86_expand_call (operands[0], operands[1], operands[2],
17495 operands[3], NULL, false);
17499 (define_expand "sibcall_value"
17500 [(set (match_operand 0)
17501 (call (match_operand:QI 1)
17502 (match_operand 2)))
17503 (use (match_operand 3))]
17506 ix86_expand_call (operands[0], operands[1], operands[2],
17507 operands[3], NULL, true);
17511 (define_insn "*call_value"
17512 [(set (match_operand 0)
17513 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17514 (match_operand 2)))]
17515 "!SIBLING_CALL_P (insn)"
17516 "* return ix86_output_call_insn (insn, operands[1]);"
17517 [(set_attr "type" "callv")])
17519 ;; This covers both call and sibcall since only GOT slot is allowed.
17520 (define_insn "*call_value_got_x32"
17521 [(set (match_operand 0)
17524 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17525 (match_operand 2)))]
17528 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17529 return ix86_output_call_insn (insn, fnaddr);
17531 [(set_attr "type" "callv")])
17533 ;; Since sibcall never returns, we can only use call-clobbered register
17535 (define_insn "*sibcall_value_GOT_32"
17536 [(set (match_operand 0)
17539 (match_operand:SI 1 "register_no_elim_operand" "U")
17540 (match_operand:SI 2 "GOT32_symbol_operand"))))
17541 (match_operand 3)))]
17544 && !TARGET_INDIRECT_BRANCH_REGISTER
17545 && SIBLING_CALL_P (insn)"
17547 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17548 fnaddr = gen_const_mem (SImode, fnaddr);
17549 return ix86_output_call_insn (insn, fnaddr);
17551 [(set_attr "type" "callv")])
17553 (define_insn "*sibcall_value"
17554 [(set (match_operand 0)
17555 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17556 (match_operand 2)))]
17557 "SIBLING_CALL_P (insn)"
17558 "* return ix86_output_call_insn (insn, operands[1]);"
17559 [(set_attr "type" "callv")])
17561 (define_insn "*sibcall_value_memory"
17562 [(set (match_operand 0)
17563 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17564 (match_operand 2)))
17565 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17566 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17567 "* return ix86_output_call_insn (insn, operands[1]);"
17568 [(set_attr "type" "callv")])
17571 [(set (match_operand:W 0 "register_operand")
17572 (match_operand:W 1 "memory_operand"))
17573 (set (match_operand 2)
17574 (call (mem:QI (match_dup 0))
17575 (match_operand 3)))]
17577 && !TARGET_INDIRECT_BRANCH_REGISTER
17578 && SIBLING_CALL_P (peep2_next_insn (1))
17579 && !reg_mentioned_p (operands[0],
17580 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17581 [(parallel [(set (match_dup 2)
17582 (call (mem:QI (match_dup 1))
17584 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17587 [(set (match_operand:W 0 "register_operand")
17588 (match_operand:W 1 "memory_operand"))
17589 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17590 (set (match_operand 2)
17591 (call (mem:QI (match_dup 0))
17592 (match_operand 3)))]
17594 && !TARGET_INDIRECT_BRANCH_REGISTER
17595 && SIBLING_CALL_P (peep2_next_insn (2))
17596 && !reg_mentioned_p (operands[0],
17597 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17598 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17599 (parallel [(set (match_dup 2)
17600 (call (mem:QI (match_dup 1))
17602 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17604 (define_expand "call_value_pop"
17605 [(parallel [(set (match_operand 0)
17606 (call (match_operand:QI 1)
17607 (match_operand:SI 2)))
17608 (set (reg:SI SP_REG)
17609 (plus:SI (reg:SI SP_REG)
17610 (match_operand:SI 4)))])]
17613 ix86_expand_call (operands[0], operands[1], operands[2],
17614 operands[3], operands[4], false);
17618 (define_insn "*call_value_pop"
17619 [(set (match_operand 0)
17620 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17621 (match_operand 2)))
17622 (set (reg:SI SP_REG)
17623 (plus:SI (reg:SI SP_REG)
17624 (match_operand:SI 3 "immediate_operand" "i")))]
17625 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17626 "* return ix86_output_call_insn (insn, operands[1]);"
17627 [(set_attr "type" "callv")])
17629 (define_insn "*sibcall_value_pop"
17630 [(set (match_operand 0)
17631 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17632 (match_operand 2)))
17633 (set (reg:SI SP_REG)
17634 (plus:SI (reg:SI SP_REG)
17635 (match_operand:SI 3 "immediate_operand" "i")))]
17636 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17637 "* return ix86_output_call_insn (insn, operands[1]);"
17638 [(set_attr "type" "callv")])
17640 (define_insn "*sibcall_value_pop_memory"
17641 [(set (match_operand 0)
17642 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17643 (match_operand 2)))
17644 (set (reg:SI SP_REG)
17645 (plus:SI (reg:SI SP_REG)
17646 (match_operand:SI 3 "immediate_operand" "i")))
17647 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17649 "* return ix86_output_call_insn (insn, operands[1]);"
17650 [(set_attr "type" "callv")])
17653 [(set (match_operand:SI 0 "register_operand")
17654 (match_operand:SI 1 "memory_operand"))
17655 (parallel [(set (match_operand 2)
17656 (call (mem:QI (match_dup 0))
17657 (match_operand 3)))
17658 (set (reg:SI SP_REG)
17659 (plus:SI (reg:SI SP_REG)
17660 (match_operand:SI 4 "immediate_operand")))])]
17661 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17662 && !reg_mentioned_p (operands[0],
17663 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17664 [(parallel [(set (match_dup 2)
17665 (call (mem:QI (match_dup 1))
17667 (set (reg:SI SP_REG)
17668 (plus:SI (reg:SI SP_REG)
17670 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17673 [(set (match_operand:SI 0 "register_operand")
17674 (match_operand:SI 1 "memory_operand"))
17675 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17676 (parallel [(set (match_operand 2)
17677 (call (mem:QI (match_dup 0))
17678 (match_operand 3)))
17679 (set (reg:SI SP_REG)
17680 (plus:SI (reg:SI SP_REG)
17681 (match_operand:SI 4 "immediate_operand")))])]
17682 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17683 && !reg_mentioned_p (operands[0],
17684 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17685 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17686 (parallel [(set (match_dup 2)
17687 (call (mem:QI (match_dup 1))
17689 (set (reg:SI SP_REG)
17690 (plus:SI (reg:SI SP_REG)
17692 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17694 ;; Call subroutine returning any type.
17696 (define_expand "untyped_call"
17697 [(parallel [(call (match_operand 0)
17700 (match_operand 2)])]
17705 /* In order to give reg-stack an easier job in validating two
17706 coprocessor registers as containing a possible return value,
17707 simply pretend the untyped call returns a complex long double
17710 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17711 and should have the default ABI. */
17713 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17714 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17715 operands[0], const0_rtx,
17716 GEN_INT ((TARGET_64BIT
17717 ? (ix86_abi == SYSV_ABI
17718 ? X86_64_SSE_REGPARM_MAX
17719 : X86_64_MS_SSE_REGPARM_MAX)
17720 : X86_32_SSE_REGPARM_MAX)
17724 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17726 rtx set = XVECEXP (operands[2], 0, i);
17727 emit_move_insn (SET_DEST (set), SET_SRC (set));
17730 /* The optimizer does not know that the call sets the function value
17731 registers we stored in the result block. We avoid problems by
17732 claiming that all hard registers are used and clobbered at this
17734 emit_insn (gen_blockage ());
17739 ;; Prologue and epilogue instructions
17741 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17742 ;; all of memory. This blocks insns from being moved across this point.
17744 (define_insn "blockage"
17745 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17748 [(set_attr "length" "0")])
17750 ;; Do not schedule instructions accessing memory across this point.
17752 (define_expand "memory_blockage"
17753 [(set (match_dup 0)
17754 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17757 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17758 MEM_VOLATILE_P (operands[0]) = 1;
17761 (define_insn "*memory_blockage"
17762 [(set (match_operand:BLK 0)
17763 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17766 [(set_attr "length" "0")])
17768 ;; As USE insns aren't meaningful after reload, this is used instead
17769 ;; to prevent deleting instructions setting registers for PIC code
17770 (define_insn "prologue_use"
17771 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17774 [(set_attr "length" "0")])
17776 ;; Insn emitted into the body of a function to return from a function.
17777 ;; This is only done if the function's epilogue is known to be simple.
17778 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17780 (define_expand "return"
17782 "ix86_can_use_return_insn_p ()"
17784 if (crtl->args.pops_args)
17786 rtx popc = GEN_INT (crtl->args.pops_args);
17787 emit_jump_insn (gen_simple_return_pop_internal (popc));
17792 ;; We need to disable this for TARGET_SEH, as otherwise
17793 ;; shrink-wrapped prologue gets enabled too. This might exceed
17794 ;; the maximum size of prologue in unwind information.
17795 ;; Also disallow shrink-wrapping if using stack slot to pass the
17796 ;; static chain pointer - the first instruction has to be pushl %esi
17797 ;; and it can't be moved around, as we use alternate entry points
17799 ;; Also disallow for ms_hook_prologue functions which have frame
17800 ;; pointer set up in function label which is correctly handled in
17801 ;; ix86_expand_{prologue|epligoue}() only.
17803 (define_expand "simple_return"
17805 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17807 if (crtl->args.pops_args)
17809 rtx popc = GEN_INT (crtl->args.pops_args);
17810 emit_jump_insn (gen_simple_return_pop_internal (popc));
17815 (define_insn "simple_return_internal"
17818 "* return ix86_output_function_return (false);"
17819 [(set_attr "length" "1")
17820 (set_attr "atom_unit" "jeu")
17821 (set_attr "length_immediate" "0")
17822 (set_attr "modrm" "0")])
17824 (define_insn "interrupt_return"
17826 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17829 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17832 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17833 ;; instruction Athlon and K8 have.
17835 (define_insn "simple_return_internal_long"
17837 (unspec [(const_int 0)] UNSPEC_REP)]
17839 "* return ix86_output_function_return (true);"
17840 [(set_attr "length" "2")
17841 (set_attr "atom_unit" "jeu")
17842 (set_attr "length_immediate" "0")
17843 (set_attr "prefix_rep" "1")
17844 (set_attr "modrm" "0")])
17846 (define_insn_and_split "simple_return_pop_internal"
17848 (use (match_operand:SI 0 "const_int_operand"))]
17851 "&& cfun->machine->function_return_type != indirect_branch_keep"
17853 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17854 [(set_attr "length" "3")
17855 (set_attr "atom_unit" "jeu")
17856 (set_attr "length_immediate" "2")
17857 (set_attr "modrm" "0")])
17859 (define_expand "simple_return_indirect_internal"
17862 (use (match_operand 0 "register_operand"))])])
17864 (define_insn "*simple_return_indirect_internal<mode>"
17866 (use (match_operand:W 0 "register_operand" "r"))]
17868 "* return ix86_output_indirect_function_return (operands[0]);"
17869 [(set (attr "type")
17870 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17871 != indirect_branch_keep)")
17872 (const_string "multi")
17873 (const_string "ibr")))
17874 (set_attr "length_immediate" "0")])
17880 [(set_attr "length" "1")
17881 (set_attr "length_immediate" "0")
17882 (set_attr "modrm" "0")])
17884 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17885 (define_insn "nops"
17886 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17890 int num = INTVAL (operands[0]);
17892 gcc_assert (IN_RANGE (num, 1, 8));
17895 fputs ("\tnop\n", asm_out_file);
17899 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17900 (set_attr "length_immediate" "0")
17901 (set_attr "modrm" "0")])
17903 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17904 ;; branch prediction penalty for the third jump in a 16-byte
17908 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17911 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17912 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17914 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17915 The align insn is used to avoid 3 jump instructions in the row to improve
17916 branch prediction and the benefits hardly outweigh the cost of extra 8
17917 nops on the average inserted by full alignment pseudo operation. */
17921 [(set_attr "length" "16")])
17923 (define_expand "prologue"
17926 "ix86_expand_prologue (); DONE;")
17928 (define_expand "set_got"
17930 [(set (match_operand:SI 0 "register_operand")
17931 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17932 (clobber (reg:CC FLAGS_REG))])]
17935 if (flag_pic && !TARGET_VXWORKS_RTP)
17936 ix86_pc_thunk_call_expanded = true;
17939 (define_insn "*set_got"
17940 [(set (match_operand:SI 0 "register_operand" "=r")
17941 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17942 (clobber (reg:CC FLAGS_REG))]
17944 "* return output_set_got (operands[0], NULL_RTX);"
17945 [(set_attr "type" "multi")
17946 (set_attr "length" "12")])
17948 (define_expand "set_got_labelled"
17950 [(set (match_operand:SI 0 "register_operand")
17951 (unspec:SI [(label_ref (match_operand 1))]
17953 (clobber (reg:CC FLAGS_REG))])]
17956 if (flag_pic && !TARGET_VXWORKS_RTP)
17957 ix86_pc_thunk_call_expanded = true;
17960 (define_insn "*set_got_labelled"
17961 [(set (match_operand:SI 0 "register_operand" "=r")
17962 (unspec:SI [(label_ref (match_operand 1))]
17964 (clobber (reg:CC FLAGS_REG))]
17966 "* return output_set_got (operands[0], operands[1]);"
17967 [(set_attr "type" "multi")
17968 (set_attr "length" "12")])
17970 (define_insn "set_got_rex64"
17971 [(set (match_operand:DI 0 "register_operand" "=r")
17972 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17974 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17975 [(set_attr "type" "lea")
17976 (set_attr "length_address" "4")
17977 (set_attr "mode" "DI")])
17979 (define_insn "set_rip_rex64"
17980 [(set (match_operand:DI 0 "register_operand" "=r")
17981 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17983 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17984 [(set_attr "type" "lea")
17985 (set_attr "length_address" "4")
17986 (set_attr "mode" "DI")])
17988 (define_insn "set_got_offset_rex64"
17989 [(set (match_operand:DI 0 "register_operand" "=r")
17991 [(label_ref (match_operand 1))]
17992 UNSPEC_SET_GOT_OFFSET))]
17994 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17995 [(set_attr "type" "imov")
17996 (set_attr "length_immediate" "0")
17997 (set_attr "length_address" "8")
17998 (set_attr "mode" "DI")])
18000 (define_expand "epilogue"
18003 "ix86_expand_epilogue (1); DONE;")
18005 (define_expand "sibcall_epilogue"
18008 "ix86_expand_epilogue (0); DONE;")
18010 (define_expand "eh_return"
18011 [(use (match_operand 0 "register_operand"))]
18014 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18016 /* Tricky bit: we write the address of the handler to which we will
18017 be returning into someone else's stack frame, one word below the
18018 stack address we wish to restore. */
18019 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18020 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18021 /* Return address is always in word_mode. */
18022 tmp = gen_rtx_MEM (word_mode, tmp);
18023 if (GET_MODE (ra) != word_mode)
18024 ra = convert_to_mode (word_mode, ra, 1);
18025 emit_move_insn (tmp, ra);
18027 emit_jump_insn (gen_eh_return_internal ());
18032 (define_insn_and_split "eh_return_internal"
18036 "epilogue_completed"
18038 "ix86_expand_epilogue (2); DONE;")
18040 (define_expand "@leave_<mode>"
18042 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18043 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18044 (clobber (mem:BLK (scratch)))])]
18046 "operands[0] = GEN_INT (<MODE_SIZE>);")
18048 (define_insn "*leave"
18049 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18050 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18051 (clobber (mem:BLK (scratch)))]
18054 [(set_attr "type" "leave")])
18056 (define_insn "*leave_rex64"
18057 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18058 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18059 (clobber (mem:BLK (scratch)))]
18062 [(set_attr "type" "leave")])
18064 ;; Handle -fsplit-stack.
18066 (define_expand "split_stack_prologue"
18070 ix86_expand_split_stack_prologue ();
18074 ;; In order to support the call/return predictor, we use a return
18075 ;; instruction which the middle-end doesn't see.
18076 (define_insn "split_stack_return"
18077 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18078 UNSPECV_SPLIT_STACK_RETURN)]
18081 if (operands[0] == const0_rtx)
18086 [(set_attr "atom_unit" "jeu")
18087 (set_attr "modrm" "0")
18088 (set (attr "length")
18089 (if_then_else (match_operand:SI 0 "const0_operand")
18092 (set (attr "length_immediate")
18093 (if_then_else (match_operand:SI 0 "const0_operand")
18097 ;; If there are operand 0 bytes available on the stack, jump to
18100 (define_expand "split_stack_space_check"
18101 [(set (pc) (if_then_else
18102 (ltu (minus (reg SP_REG)
18103 (match_operand 0 "register_operand"))
18105 (label_ref (match_operand 1))
18109 rtx reg = gen_reg_rtx (Pmode);
18111 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18113 operands[2] = ix86_split_stack_guard ();
18114 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18119 ;; Bit manipulation instructions.
18121 (define_expand "ffs<mode>2"
18122 [(set (match_dup 2) (const_int -1))
18123 (parallel [(set (match_dup 3) (match_dup 4))
18124 (set (match_operand:SWI48 0 "register_operand")
18126 (match_operand:SWI48 1 "nonimmediate_operand")))])
18127 (set (match_dup 0) (if_then_else:SWI48
18128 (eq (match_dup 3) (const_int 0))
18131 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18132 (clobber (reg:CC FLAGS_REG))])]
18135 machine_mode flags_mode;
18137 if (<MODE>mode == SImode && !TARGET_CMOVE)
18139 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18143 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18145 operands[2] = gen_reg_rtx (<MODE>mode);
18146 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18147 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18150 (define_insn_and_split "ffssi2_no_cmove"
18151 [(set (match_operand:SI 0 "register_operand" "=r")
18152 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18153 (clobber (match_scratch:SI 2 "=&q"))
18154 (clobber (reg:CC FLAGS_REG))]
18157 "&& reload_completed"
18158 [(parallel [(set (match_dup 4) (match_dup 5))
18159 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18160 (set (strict_low_part (match_dup 3))
18161 (eq:QI (match_dup 4) (const_int 0)))
18162 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18163 (clobber (reg:CC FLAGS_REG))])
18164 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18165 (clobber (reg:CC FLAGS_REG))])
18166 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18167 (clobber (reg:CC FLAGS_REG))])]
18169 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18171 operands[3] = gen_lowpart (QImode, operands[2]);
18172 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18173 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18175 ix86_expand_clear (operands[2]);
18178 (define_insn_and_split "*tzcnt<mode>_1"
18179 [(set (reg:CCC FLAGS_REG)
18180 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18182 (set (match_operand:SWI48 0 "register_operand" "=r")
18183 (ctz:SWI48 (match_dup 1)))]
18185 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18186 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18187 && optimize_function_for_speed_p (cfun)
18188 && !reg_mentioned_p (operands[0], operands[1])"
18190 [(set (reg:CCC FLAGS_REG)
18191 (compare:CCC (match_dup 1) (const_int 0)))
18193 (ctz:SWI48 (match_dup 1)))
18194 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18195 "ix86_expand_clear (operands[0]);"
18196 [(set_attr "type" "alu1")
18197 (set_attr "prefix_0f" "1")
18198 (set_attr "prefix_rep" "1")
18199 (set_attr "btver2_decode" "double")
18200 (set_attr "mode" "<MODE>")])
18202 ; False dependency happens when destination is only updated by tzcnt,
18203 ; lzcnt or popcnt. There is no false dependency when destination is
18204 ; also used in source.
18205 (define_insn "*tzcnt<mode>_1_falsedep"
18206 [(set (reg:CCC FLAGS_REG)
18207 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18209 (set (match_operand:SWI48 0 "register_operand" "=r")
18210 (ctz:SWI48 (match_dup 1)))
18211 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18212 UNSPEC_INSN_FALSE_DEP)]
18214 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18215 [(set_attr "type" "alu1")
18216 (set_attr "prefix_0f" "1")
18217 (set_attr "prefix_rep" "1")
18218 (set_attr "btver2_decode" "double")
18219 (set_attr "mode" "<MODE>")])
18221 (define_insn "*bsf<mode>_1"
18222 [(set (reg:CCZ FLAGS_REG)
18223 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18225 (set (match_operand:SWI48 0 "register_operand" "=r")
18226 (ctz:SWI48 (match_dup 1)))]
18228 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18229 [(set_attr "type" "alu1")
18230 (set_attr "prefix_0f" "1")
18231 (set_attr "btver2_decode" "double")
18232 (set_attr "znver1_decode" "vector")
18233 (set_attr "mode" "<MODE>")])
18235 (define_insn_and_split "ctz<mode>2"
18236 [(set (match_operand:SWI48 0 "register_operand" "=r")
18238 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18239 (clobber (reg:CC FLAGS_REG))]
18243 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18244 else if (optimize_function_for_size_p (cfun))
18246 else if (TARGET_CPU_P (GENERIC))
18247 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18248 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18250 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18252 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18253 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18254 && optimize_function_for_speed_p (cfun)
18255 && !reg_mentioned_p (operands[0], operands[1])"
18257 [(set (match_dup 0)
18258 (ctz:SWI48 (match_dup 1)))
18259 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18260 (clobber (reg:CC FLAGS_REG))])]
18261 "ix86_expand_clear (operands[0]);"
18262 [(set_attr "type" "alu1")
18263 (set_attr "prefix_0f" "1")
18264 (set (attr "prefix_rep")
18266 (ior (match_test "TARGET_BMI")
18267 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18268 (match_test "TARGET_CPU_P (GENERIC)")))
18270 (const_string "0")))
18271 (set_attr "mode" "<MODE>")])
18273 ; False dependency happens when destination is only updated by tzcnt,
18274 ; lzcnt or popcnt. There is no false dependency when destination is
18275 ; also used in source.
18276 (define_insn "*ctz<mode>2_falsedep"
18277 [(set (match_operand:SWI48 0 "register_operand" "=r")
18279 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18280 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18281 UNSPEC_INSN_FALSE_DEP)
18282 (clobber (reg:CC FLAGS_REG))]
18286 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18287 else if (TARGET_CPU_P (GENERIC))
18288 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18289 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18291 gcc_unreachable ();
18293 [(set_attr "type" "alu1")
18294 (set_attr "prefix_0f" "1")
18295 (set_attr "prefix_rep" "1")
18296 (set_attr "mode" "<MODE>")])
18298 (define_insn_and_split "*ctzsi2_zext"
18299 [(set (match_operand:DI 0 "register_operand" "=r")
18303 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18305 (clobber (reg:CC FLAGS_REG))]
18306 "TARGET_BMI && TARGET_64BIT"
18307 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18308 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18309 && optimize_function_for_speed_p (cfun)
18310 && !reg_mentioned_p (operands[0], operands[1])"
18312 [(set (match_dup 0)
18313 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18314 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18315 (clobber (reg:CC FLAGS_REG))])]
18316 "ix86_expand_clear (operands[0]);"
18317 [(set_attr "type" "alu1")
18318 (set_attr "prefix_0f" "1")
18319 (set_attr "prefix_rep" "1")
18320 (set_attr "mode" "SI")])
18322 ; False dependency happens when destination is only updated by tzcnt,
18323 ; lzcnt or popcnt. There is no false dependency when destination is
18324 ; also used in source.
18325 (define_insn "*ctzsi2_zext_falsedep"
18326 [(set (match_operand:DI 0 "register_operand" "=r")
18330 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18332 (unspec [(match_operand:DI 2 "register_operand" "0")]
18333 UNSPEC_INSN_FALSE_DEP)
18334 (clobber (reg:CC FLAGS_REG))]
18335 "TARGET_BMI && TARGET_64BIT"
18336 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18337 [(set_attr "type" "alu1")
18338 (set_attr "prefix_0f" "1")
18339 (set_attr "prefix_rep" "1")
18340 (set_attr "mode" "SI")])
18342 (define_insn_and_split "*ctzsidi2_<s>ext"
18343 [(set (match_operand:DI 0 "register_operand" "=r")
18346 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18347 (clobber (reg:CC FLAGS_REG))]
18351 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18352 else if (TARGET_CPU_P (GENERIC)
18353 && !optimize_function_for_size_p (cfun))
18354 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18355 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18356 return "bsf{l}\t{%1, %k0|%k0, %1}";
18358 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18359 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18360 && optimize_function_for_speed_p (cfun)
18361 && !reg_mentioned_p (operands[0], operands[1])"
18363 [(set (match_dup 0)
18364 (any_extend:DI (ctz:SI (match_dup 1))))
18365 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18366 (clobber (reg:CC FLAGS_REG))])]
18367 "ix86_expand_clear (operands[0]);"
18368 [(set_attr "type" "alu1")
18369 (set_attr "prefix_0f" "1")
18370 (set (attr "prefix_rep")
18372 (ior (match_test "TARGET_BMI")
18373 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18374 (match_test "TARGET_CPU_P (GENERIC)")))
18376 (const_string "0")))
18377 (set_attr "mode" "SI")])
18379 (define_insn "*ctzsidi2_<s>ext_falsedep"
18380 [(set (match_operand:DI 0 "register_operand" "=r")
18383 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18384 (unspec [(match_operand:DI 2 "register_operand" "0")]
18385 UNSPEC_INSN_FALSE_DEP)
18386 (clobber (reg:CC FLAGS_REG))]
18390 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18391 else if (TARGET_CPU_P (GENERIC))
18392 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18393 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18395 gcc_unreachable ();
18397 [(set_attr "type" "alu1")
18398 (set_attr "prefix_0f" "1")
18399 (set_attr "prefix_rep" "1")
18400 (set_attr "mode" "SI")])
18402 (define_insn "bsr_rex64"
18403 [(set (reg:CCZ FLAGS_REG)
18404 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18406 (set (match_operand:DI 0 "register_operand" "=r")
18407 (minus:DI (const_int 63)
18408 (clz:DI (match_dup 1))))]
18410 "bsr{q}\t{%1, %0|%0, %1}"
18411 [(set_attr "type" "alu1")
18412 (set_attr "prefix_0f" "1")
18413 (set_attr "znver1_decode" "vector")
18414 (set_attr "mode" "DI")])
18416 (define_insn "bsr_rex64_1"
18417 [(set (match_operand:DI 0 "register_operand" "=r")
18418 (minus:DI (const_int 63)
18419 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18420 (clobber (reg:CC FLAGS_REG))]
18421 "!TARGET_LZCNT && TARGET_64BIT"
18422 "bsr{q}\t{%1, %0|%0, %1}"
18423 [(set_attr "type" "alu1")
18424 (set_attr "prefix_0f" "1")
18425 (set_attr "znver1_decode" "vector")
18426 (set_attr "mode" "DI")])
18428 (define_insn "bsr_rex64_1_zext"
18429 [(set (match_operand:DI 0 "register_operand" "=r")
18431 (minus:SI (const_int 63)
18433 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18435 (clobber (reg:CC FLAGS_REG))]
18436 "!TARGET_LZCNT && TARGET_64BIT"
18437 "bsr{q}\t{%1, %0|%0, %1}"
18438 [(set_attr "type" "alu1")
18439 (set_attr "prefix_0f" "1")
18440 (set_attr "znver1_decode" "vector")
18441 (set_attr "mode" "DI")])
18444 [(set (reg:CCZ FLAGS_REG)
18445 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18447 (set (match_operand:SI 0 "register_operand" "=r")
18448 (minus:SI (const_int 31)
18449 (clz:SI (match_dup 1))))]
18451 "bsr{l}\t{%1, %0|%0, %1}"
18452 [(set_attr "type" "alu1")
18453 (set_attr "prefix_0f" "1")
18454 (set_attr "znver1_decode" "vector")
18455 (set_attr "mode" "SI")])
18457 (define_insn "bsr_1"
18458 [(set (match_operand:SI 0 "register_operand" "=r")
18459 (minus:SI (const_int 31)
18460 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18461 (clobber (reg:CC FLAGS_REG))]
18463 "bsr{l}\t{%1, %0|%0, %1}"
18464 [(set_attr "type" "alu1")
18465 (set_attr "prefix_0f" "1")
18466 (set_attr "znver1_decode" "vector")
18467 (set_attr "mode" "SI")])
18469 (define_insn "bsr_zext_1"
18470 [(set (match_operand:DI 0 "register_operand" "=r")
18474 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18475 (clobber (reg:CC FLAGS_REG))]
18476 "!TARGET_LZCNT && TARGET_64BIT"
18477 "bsr{l}\t{%1, %k0|%k0, %1}"
18478 [(set_attr "type" "alu1")
18479 (set_attr "prefix_0f" "1")
18480 (set_attr "znver1_decode" "vector")
18481 (set_attr "mode" "SI")])
18483 ; As bsr is undefined behavior on zero and for other input
18484 ; values it is in range 0 to 63, we can optimize away sign-extends.
18485 (define_insn_and_split "*bsr_rex64_2"
18486 [(set (match_operand:DI 0 "register_operand")
18491 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18494 (clobber (reg:CC FLAGS_REG))]
18495 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18498 [(parallel [(set (reg:CCZ FLAGS_REG)
18499 (compare:CCZ (match_dup 1) (const_int 0)))
18501 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18502 (parallel [(set (match_dup 0)
18503 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18504 (clobber (reg:CC FLAGS_REG))])]
18506 operands[2] = gen_reg_rtx (DImode);
18507 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18510 (define_insn_and_split "*bsr_2"
18511 [(set (match_operand:DI 0 "register_operand")
18516 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18518 (clobber (reg:CC FLAGS_REG))]
18519 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18522 [(parallel [(set (reg:CCZ FLAGS_REG)
18523 (compare:CCZ (match_dup 1) (const_int 0)))
18525 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18526 (parallel [(set (match_dup 0)
18527 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18528 (clobber (reg:CC FLAGS_REG))])]
18529 "operands[2] = gen_reg_rtx (SImode);")
18531 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18532 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18533 ; in [0, 63] or [0, 31] range.
18535 [(set (match_operand:SI 0 "register_operand")
18537 (match_operand:SI 2 "const_int_operand")
18539 (minus:SI (const_int 63)
18541 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18544 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18545 [(set (match_dup 3)
18546 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18548 (plus:SI (match_dup 5) (match_dup 4)))]
18550 operands[3] = gen_reg_rtx (DImode);
18551 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18552 if (INTVAL (operands[2]) == 63)
18554 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18555 emit_move_insn (operands[0], operands[5]);
18558 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18562 [(set (match_operand:SI 0 "register_operand")
18564 (match_operand:SI 2 "const_int_operand")
18566 (minus:SI (const_int 31)
18567 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18569 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18570 [(set (match_dup 3)
18571 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18573 (plus:SI (match_dup 3) (match_dup 4)))]
18575 if (INTVAL (operands[2]) == 31)
18577 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18580 operands[3] = gen_reg_rtx (SImode);
18581 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18585 [(set (match_operand:DI 0 "register_operand")
18587 (match_operand:DI 2 "const_int_operand")
18590 (minus:SI (const_int 63)
18592 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18597 && ix86_pre_reload_split ()
18598 && ((unsigned HOST_WIDE_INT)
18599 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18600 == UINTVAL (operands[2]) - 63)"
18601 [(set (match_dup 3)
18602 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18604 (plus:DI (match_dup 3) (match_dup 4)))]
18606 if (INTVAL (operands[2]) == 63)
18608 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18611 operands[3] = gen_reg_rtx (DImode);
18612 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18616 [(set (match_operand:DI 0 "register_operand")
18618 (match_operand:DI 2 "const_int_operand")
18621 (minus:SI (const_int 31)
18622 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18623 (const_int 31)))))]
18626 && ix86_pre_reload_split ()
18627 && ((unsigned HOST_WIDE_INT)
18628 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18629 == UINTVAL (operands[2]) - 31)"
18630 [(set (match_dup 3)
18631 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18633 (plus:DI (match_dup 3) (match_dup 4)))]
18635 if (INTVAL (operands[2]) == 31)
18637 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18640 operands[3] = gen_reg_rtx (DImode);
18641 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18644 (define_expand "clz<mode>2"
18646 [(set (reg:CCZ FLAGS_REG)
18647 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18649 (set (match_dup 3) (minus:SWI48
18651 (clz:SWI48 (match_dup 1))))])
18653 [(set (match_operand:SWI48 0 "register_operand")
18654 (xor:SWI48 (match_dup 3) (match_dup 2)))
18655 (clobber (reg:CC FLAGS_REG))])]
18660 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18663 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18664 operands[3] = gen_reg_rtx (<MODE>mode);
18667 (define_insn_and_split "clz<mode>2_lzcnt"
18668 [(set (match_operand:SWI48 0 "register_operand" "=r")
18670 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18671 (clobber (reg:CC FLAGS_REG))]
18673 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18674 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18675 && optimize_function_for_speed_p (cfun)
18676 && !reg_mentioned_p (operands[0], operands[1])"
18678 [(set (match_dup 0)
18679 (clz:SWI48 (match_dup 1)))
18680 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18681 (clobber (reg:CC FLAGS_REG))])]
18682 "ix86_expand_clear (operands[0]);"
18683 [(set_attr "prefix_rep" "1")
18684 (set_attr "type" "bitmanip")
18685 (set_attr "mode" "<MODE>")])
18687 ; False dependency happens when destination is only updated by tzcnt,
18688 ; lzcnt or popcnt. There is no false dependency when destination is
18689 ; also used in source.
18690 (define_insn "*clz<mode>2_lzcnt_falsedep"
18691 [(set (match_operand:SWI48 0 "register_operand" "=r")
18693 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18694 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18695 UNSPEC_INSN_FALSE_DEP)
18696 (clobber (reg:CC FLAGS_REG))]
18698 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18699 [(set_attr "prefix_rep" "1")
18700 (set_attr "type" "bitmanip")
18701 (set_attr "mode" "<MODE>")])
18703 (define_insn_and_split "*clzsi2_lzcnt_zext"
18704 [(set (match_operand:DI 0 "register_operand" "=r")
18708 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18710 (clobber (reg:CC FLAGS_REG))]
18711 "TARGET_LZCNT && TARGET_64BIT"
18712 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18713 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18714 && optimize_function_for_speed_p (cfun)
18715 && !reg_mentioned_p (operands[0], operands[1])"
18717 [(set (match_dup 0)
18718 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18719 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18720 (clobber (reg:CC FLAGS_REG))])]
18721 "ix86_expand_clear (operands[0]);"
18722 [(set_attr "prefix_rep" "1")
18723 (set_attr "type" "bitmanip")
18724 (set_attr "mode" "SI")])
18726 ; False dependency happens when destination is only updated by tzcnt,
18727 ; lzcnt or popcnt. There is no false dependency when destination is
18728 ; also used in source.
18729 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18730 [(set (match_operand:DI 0 "register_operand" "=r")
18734 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18736 (unspec [(match_operand:DI 2 "register_operand" "0")]
18737 UNSPEC_INSN_FALSE_DEP)
18738 (clobber (reg:CC FLAGS_REG))]
18740 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18741 [(set_attr "prefix_rep" "1")
18742 (set_attr "type" "bitmanip")
18743 (set_attr "mode" "SI")])
18745 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18746 [(set (match_operand:DI 0 "register_operand" "=r")
18748 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18749 (clobber (reg:CC FLAGS_REG))]
18750 "TARGET_LZCNT && TARGET_64BIT"
18751 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18752 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18753 && optimize_function_for_speed_p (cfun)
18754 && !reg_mentioned_p (operands[0], operands[1])"
18756 [(set (match_dup 0)
18757 (zero_extend:DI (clz:SI (match_dup 1))))
18758 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18759 (clobber (reg:CC FLAGS_REG))])]
18760 "ix86_expand_clear (operands[0]);"
18761 [(set_attr "prefix_rep" "1")
18762 (set_attr "type" "bitmanip")
18763 (set_attr "mode" "SI")])
18765 ; False dependency happens when destination is only updated by tzcnt,
18766 ; lzcnt or popcnt. There is no false dependency when destination is
18767 ; also used in source.
18768 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18769 [(set (match_operand:DI 0 "register_operand" "=r")
18771 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18772 (unspec [(match_operand:DI 2 "register_operand" "0")]
18773 UNSPEC_INSN_FALSE_DEP)
18774 (clobber (reg:CC FLAGS_REG))]
18776 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18777 [(set_attr "prefix_rep" "1")
18778 (set_attr "type" "bitmanip")
18779 (set_attr "mode" "SI")])
18781 (define_int_iterator LT_ZCNT
18782 [(UNSPEC_TZCNT "TARGET_BMI")
18783 (UNSPEC_LZCNT "TARGET_LZCNT")])
18785 (define_int_attr lt_zcnt
18786 [(UNSPEC_TZCNT "tzcnt")
18787 (UNSPEC_LZCNT "lzcnt")])
18789 (define_int_attr lt_zcnt_type
18790 [(UNSPEC_TZCNT "alu1")
18791 (UNSPEC_LZCNT "bitmanip")])
18793 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18794 ;; provides operand size as output when source operand is zero.
18796 (define_insn_and_split "<lt_zcnt>_<mode>"
18797 [(set (match_operand:SWI48 0 "register_operand" "=r")
18799 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18800 (clobber (reg:CC FLAGS_REG))]
18802 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18803 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18804 && optimize_function_for_speed_p (cfun)
18805 && !reg_mentioned_p (operands[0], operands[1])"
18807 [(set (match_dup 0)
18808 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18809 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18810 (clobber (reg:CC FLAGS_REG))])]
18811 "ix86_expand_clear (operands[0]);"
18812 [(set_attr "type" "<lt_zcnt_type>")
18813 (set_attr "prefix_0f" "1")
18814 (set_attr "prefix_rep" "1")
18815 (set_attr "mode" "<MODE>")])
18817 ; False dependency happens when destination is only updated by tzcnt,
18818 ; lzcnt or popcnt. There is no false dependency when destination is
18819 ; also used in source.
18820 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18821 [(set (match_operand:SWI48 0 "register_operand" "=r")
18823 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18824 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18825 UNSPEC_INSN_FALSE_DEP)
18826 (clobber (reg:CC FLAGS_REG))]
18828 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18829 [(set_attr "type" "<lt_zcnt_type>")
18830 (set_attr "prefix_0f" "1")
18831 (set_attr "prefix_rep" "1")
18832 (set_attr "mode" "<MODE>")])
18834 (define_insn "<lt_zcnt>_hi"
18835 [(set (match_operand:HI 0 "register_operand" "=r")
18837 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18838 (clobber (reg:CC FLAGS_REG))]
18840 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18841 [(set_attr "type" "<lt_zcnt_type>")
18842 (set_attr "prefix_0f" "1")
18843 (set_attr "prefix_rep" "1")
18844 (set_attr "mode" "HI")])
18846 ;; BMI instructions.
18848 (define_insn "bmi_bextr_<mode>"
18849 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18850 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18851 (match_operand:SWI48 2 "register_operand" "r,r")]
18853 (clobber (reg:CC FLAGS_REG))]
18855 "bextr\t{%2, %1, %0|%0, %1, %2}"
18856 [(set_attr "type" "bitmanip")
18857 (set_attr "btver2_decode" "direct, double")
18858 (set_attr "mode" "<MODE>")])
18860 (define_insn "*bmi_bextr_<mode>_ccz"
18861 [(set (reg:CCZ FLAGS_REG)
18863 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18864 (match_operand:SWI48 2 "register_operand" "r,r")]
18867 (clobber (match_scratch:SWI48 0 "=r,r"))]
18869 "bextr\t{%2, %1, %0|%0, %1, %2}"
18870 [(set_attr "type" "bitmanip")
18871 (set_attr "btver2_decode" "direct, double")
18872 (set_attr "mode" "<MODE>")])
18874 (define_insn "*bmi_blsi_<mode>"
18875 [(set (match_operand:SWI48 0 "register_operand" "=r")
18878 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18880 (clobber (reg:CC FLAGS_REG))]
18882 "blsi\t{%1, %0|%0, %1}"
18883 [(set_attr "type" "bitmanip")
18884 (set_attr "btver2_decode" "double")
18885 (set_attr "mode" "<MODE>")])
18887 (define_insn "*bmi_blsi_<mode>_cmp"
18888 [(set (reg FLAGS_REG)
18891 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18894 (set (match_operand:SWI48 0 "register_operand" "=r")
18895 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18896 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18897 "blsi\t{%1, %0|%0, %1}"
18898 [(set_attr "type" "bitmanip")
18899 (set_attr "btver2_decode" "double")
18900 (set_attr "mode" "<MODE>")])
18902 (define_insn "*bmi_blsi_<mode>_ccno"
18903 [(set (reg FLAGS_REG)
18906 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18909 (clobber (match_scratch:SWI48 0 "=r"))]
18910 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18911 "blsi\t{%1, %0|%0, %1}"
18912 [(set_attr "type" "bitmanip")
18913 (set_attr "btver2_decode" "double")
18914 (set_attr "mode" "<MODE>")])
18916 (define_insn "*bmi_blsmsk_<mode>"
18917 [(set (match_operand:SWI48 0 "register_operand" "=r")
18920 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18923 (clobber (reg:CC FLAGS_REG))]
18925 "blsmsk\t{%1, %0|%0, %1}"
18926 [(set_attr "type" "bitmanip")
18927 (set_attr "btver2_decode" "double")
18928 (set_attr "mode" "<MODE>")])
18930 (define_insn "*bmi_blsr_<mode>"
18931 [(set (match_operand:SWI48 0 "register_operand" "=r")
18934 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18937 (clobber (reg:CC FLAGS_REG))]
18939 "blsr\t{%1, %0|%0, %1}"
18940 [(set_attr "type" "bitmanip")
18941 (set_attr "btver2_decode" "double")
18942 (set_attr "mode" "<MODE>")])
18944 (define_insn "*bmi_blsr_<mode>_cmp"
18945 [(set (reg:CCZ FLAGS_REG)
18949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18953 (set (match_operand:SWI48 0 "register_operand" "=r")
18960 "blsr\t{%1, %0|%0, %1}"
18961 [(set_attr "type" "bitmanip")
18962 (set_attr "btver2_decode" "double")
18963 (set_attr "mode" "<MODE>")])
18965 (define_insn "*bmi_blsr_<mode>_ccz"
18966 [(set (reg:CCZ FLAGS_REG)
18970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18974 (clobber (match_scratch:SWI48 0 "=r"))]
18976 "blsr\t{%1, %0|%0, %1}"
18977 [(set_attr "type" "bitmanip")
18978 (set_attr "btver2_decode" "double")
18979 (set_attr "mode" "<MODE>")])
18981 ;; BMI2 instructions.
18982 (define_expand "bmi2_bzhi_<mode>3"
18984 [(set (match_operand:SWI48 0 "register_operand")
18985 (if_then_else:SWI48
18986 (ne:QI (match_operand:QI 2 "register_operand")
18988 (zero_extract:SWI48
18989 (match_operand:SWI48 1 "nonimmediate_operand")
18990 (umin:QI (match_dup 2) (match_dup 3))
18993 (clobber (reg:CC FLAGS_REG))])]
18996 operands[2] = gen_lowpart (QImode, operands[2]);
18997 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19000 (define_insn "*bmi2_bzhi_<mode>3"
19001 [(set (match_operand:SWI48 0 "register_operand" "=r")
19002 (if_then_else:SWI48
19003 (ne:QI (match_operand:QI 2 "register_operand" "q")
19005 (zero_extract:SWI48
19006 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19007 (umin:QI (match_dup 2)
19008 (match_operand:QI 3 "const_int_operand"))
19011 (clobber (reg:CC FLAGS_REG))]
19012 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19013 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19014 [(set_attr "type" "bitmanip")
19015 (set_attr "prefix" "vex")
19016 (set_attr "mode" "<MODE>")])
19018 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19019 [(set (reg:CCZ FLAGS_REG)
19021 (if_then_else:SWI48
19022 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19023 (zero_extract:SWI48
19024 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19025 (umin:QI (match_dup 2)
19026 (match_operand:QI 3 "const_int_operand"))
19030 (clobber (match_scratch:SWI48 0 "=r"))]
19031 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19032 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19033 [(set_attr "type" "bitmanip")
19034 (set_attr "prefix" "vex")
19035 (set_attr "mode" "<MODE>")])
19037 (define_insn "*bmi2_bzhi_<mode>3_2"
19038 [(set (match_operand:SWI48 0 "register_operand" "=r")
19041 (ashift:SWI48 (const_int 1)
19042 (match_operand:QI 2 "register_operand" "r"))
19044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19045 (clobber (reg:CC FLAGS_REG))]
19047 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19048 [(set_attr "type" "bitmanip")
19049 (set_attr "prefix" "vex")
19050 (set_attr "mode" "<MODE>")])
19052 (define_insn "*bmi2_bzhi_<mode>3_3"
19053 [(set (match_operand:SWI48 0 "register_operand" "=r")
19056 (ashift:SWI48 (const_int -1)
19057 (match_operand:QI 2 "register_operand" "r")))
19058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19059 (clobber (reg:CC FLAGS_REG))]
19061 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19062 [(set_attr "type" "bitmanip")
19063 (set_attr "prefix" "vex")
19064 (set_attr "mode" "<MODE>")])
19066 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19067 [(set (match_operand:DI 0 "register_operand" "=r")
19071 (ashift:SI (const_int 1)
19072 (match_operand:QI 2 "register_operand" "r"))
19074 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19075 (clobber (reg:CC FLAGS_REG))]
19076 "TARGET_64BIT && TARGET_BMI2"
19077 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19078 [(set_attr "type" "bitmanip")
19079 (set_attr "prefix" "vex")
19080 (set_attr "mode" "DI")])
19082 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19083 [(set (match_operand:DI 0 "register_operand" "=r")
19087 (ashift:SI (const_int 1)
19088 (match_operand:QI 2 "register_operand" "r"))
19090 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19091 (clobber (reg:CC FLAGS_REG))]
19092 "TARGET_64BIT && TARGET_BMI2"
19093 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19094 [(set_attr "type" "bitmanip")
19095 (set_attr "prefix" "vex")
19096 (set_attr "mode" "DI")])
19098 (define_insn "bmi2_pdep_<mode>3"
19099 [(set (match_operand:SWI48 0 "register_operand" "=r")
19100 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19101 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19104 "pdep\t{%2, %1, %0|%0, %1, %2}"
19105 [(set_attr "type" "bitmanip")
19106 (set_attr "prefix" "vex")
19107 (set_attr "mode" "<MODE>")])
19109 (define_insn "bmi2_pext_<mode>3"
19110 [(set (match_operand:SWI48 0 "register_operand" "=r")
19111 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19112 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19115 "pext\t{%2, %1, %0|%0, %1, %2}"
19116 [(set_attr "type" "bitmanip")
19117 (set_attr "prefix" "vex")
19118 (set_attr "mode" "<MODE>")])
19120 ;; TBM instructions.
19121 (define_insn "@tbm_bextri_<mode>"
19122 [(set (match_operand:SWI48 0 "register_operand" "=r")
19123 (zero_extract:SWI48
19124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19125 (match_operand:QI 2 "const_0_to_255_operand")
19126 (match_operand:QI 3 "const_0_to_255_operand")))
19127 (clobber (reg:CC FLAGS_REG))]
19130 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19131 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19133 [(set_attr "type" "bitmanip")
19134 (set_attr "mode" "<MODE>")])
19136 (define_insn "*tbm_blcfill_<mode>"
19137 [(set (match_operand:SWI48 0 "register_operand" "=r")
19140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19143 (clobber (reg:CC FLAGS_REG))]
19145 "blcfill\t{%1, %0|%0, %1}"
19146 [(set_attr "type" "bitmanip")
19147 (set_attr "mode" "<MODE>")])
19149 (define_insn "*tbm_blci_<mode>"
19150 [(set (match_operand:SWI48 0 "register_operand" "=r")
19154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19157 (clobber (reg:CC FLAGS_REG))]
19159 "blci\t{%1, %0|%0, %1}"
19160 [(set_attr "type" "bitmanip")
19161 (set_attr "mode" "<MODE>")])
19163 (define_insn "*tbm_blcic_<mode>"
19164 [(set (match_operand:SWI48 0 "register_operand" "=r")
19167 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19171 (clobber (reg:CC FLAGS_REG))]
19173 "blcic\t{%1, %0|%0, %1}"
19174 [(set_attr "type" "bitmanip")
19175 (set_attr "mode" "<MODE>")])
19177 (define_insn "*tbm_blcmsk_<mode>"
19178 [(set (match_operand:SWI48 0 "register_operand" "=r")
19181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19184 (clobber (reg:CC FLAGS_REG))]
19186 "blcmsk\t{%1, %0|%0, %1}"
19187 [(set_attr "type" "bitmanip")
19188 (set_attr "mode" "<MODE>")])
19190 (define_insn "*tbm_blcs_<mode>"
19191 [(set (match_operand:SWI48 0 "register_operand" "=r")
19194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19197 (clobber (reg:CC FLAGS_REG))]
19199 "blcs\t{%1, %0|%0, %1}"
19200 [(set_attr "type" "bitmanip")
19201 (set_attr "mode" "<MODE>")])
19203 (define_insn "*tbm_blsfill_<mode>"
19204 [(set (match_operand:SWI48 0 "register_operand" "=r")
19207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19210 (clobber (reg:CC FLAGS_REG))]
19212 "blsfill\t{%1, %0|%0, %1}"
19213 [(set_attr "type" "bitmanip")
19214 (set_attr "mode" "<MODE>")])
19216 (define_insn "*tbm_blsic_<mode>"
19217 [(set (match_operand:SWI48 0 "register_operand" "=r")
19220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19224 (clobber (reg:CC FLAGS_REG))]
19226 "blsic\t{%1, %0|%0, %1}"
19227 [(set_attr "type" "bitmanip")
19228 (set_attr "mode" "<MODE>")])
19230 (define_insn "*tbm_t1mskc_<mode>"
19231 [(set (match_operand:SWI48 0 "register_operand" "=r")
19234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19238 (clobber (reg:CC FLAGS_REG))]
19240 "t1mskc\t{%1, %0|%0, %1}"
19241 [(set_attr "type" "bitmanip")
19242 (set_attr "mode" "<MODE>")])
19244 (define_insn "*tbm_tzmsk_<mode>"
19245 [(set (match_operand:SWI48 0 "register_operand" "=r")
19248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19252 (clobber (reg:CC FLAGS_REG))]
19254 "tzmsk\t{%1, %0|%0, %1}"
19255 [(set_attr "type" "bitmanip")
19256 (set_attr "mode" "<MODE>")])
19258 (define_insn_and_split "popcount<mode>2"
19259 [(set (match_operand:SWI48 0 "register_operand" "=r")
19261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19262 (clobber (reg:CC FLAGS_REG))]
19266 return "popcnt\t{%1, %0|%0, %1}";
19268 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19271 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19272 && optimize_function_for_speed_p (cfun)
19273 && !reg_mentioned_p (operands[0], operands[1])"
19275 [(set (match_dup 0)
19276 (popcount:SWI48 (match_dup 1)))
19277 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19278 (clobber (reg:CC FLAGS_REG))])]
19279 "ix86_expand_clear (operands[0]);"
19280 [(set_attr "prefix_rep" "1")
19281 (set_attr "type" "bitmanip")
19282 (set_attr "mode" "<MODE>")])
19284 ; False dependency happens when destination is only updated by tzcnt,
19285 ; lzcnt or popcnt. There is no false dependency when destination is
19286 ; also used in source.
19287 (define_insn "*popcount<mode>2_falsedep"
19288 [(set (match_operand:SWI48 0 "register_operand" "=r")
19290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19291 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19292 UNSPEC_INSN_FALSE_DEP)
19293 (clobber (reg:CC FLAGS_REG))]
19297 return "popcnt\t{%1, %0|%0, %1}";
19299 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19302 [(set_attr "prefix_rep" "1")
19303 (set_attr "type" "bitmanip")
19304 (set_attr "mode" "<MODE>")])
19306 (define_insn_and_split "*popcountsi2_zext"
19307 [(set (match_operand:DI 0 "register_operand" "=r")
19311 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19313 (clobber (reg:CC FLAGS_REG))]
19314 "TARGET_POPCNT && TARGET_64BIT"
19317 return "popcnt\t{%1, %k0|%k0, %1}";
19319 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19322 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19323 && optimize_function_for_speed_p (cfun)
19324 && !reg_mentioned_p (operands[0], operands[1])"
19326 [(set (match_dup 0)
19327 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19328 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19329 (clobber (reg:CC FLAGS_REG))])]
19330 "ix86_expand_clear (operands[0]);"
19331 [(set_attr "prefix_rep" "1")
19332 (set_attr "type" "bitmanip")
19333 (set_attr "mode" "SI")])
19335 ; False dependency happens when destination is only updated by tzcnt,
19336 ; lzcnt or popcnt. There is no false dependency when destination is
19337 ; also used in source.
19338 (define_insn "*popcountsi2_zext_falsedep"
19339 [(set (match_operand:DI 0 "register_operand" "=r")
19343 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19345 (unspec [(match_operand:DI 2 "register_operand" "0")]
19346 UNSPEC_INSN_FALSE_DEP)
19347 (clobber (reg:CC FLAGS_REG))]
19348 "TARGET_POPCNT && TARGET_64BIT"
19351 return "popcnt\t{%1, %k0|%k0, %1}";
19353 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19356 [(set_attr "prefix_rep" "1")
19357 (set_attr "type" "bitmanip")
19358 (set_attr "mode" "SI")])
19360 (define_insn_and_split "*popcountsi2_zext_2"
19361 [(set (match_operand:DI 0 "register_operand" "=r")
19363 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19364 (clobber (reg:CC FLAGS_REG))]
19365 "TARGET_POPCNT && TARGET_64BIT"
19368 return "popcnt\t{%1, %k0|%k0, %1}";
19370 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19373 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19374 && optimize_function_for_speed_p (cfun)
19375 && !reg_mentioned_p (operands[0], operands[1])"
19377 [(set (match_dup 0)
19378 (zero_extend:DI (popcount:SI (match_dup 1))))
19379 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19380 (clobber (reg:CC FLAGS_REG))])]
19381 "ix86_expand_clear (operands[0]);"
19382 [(set_attr "prefix_rep" "1")
19383 (set_attr "type" "bitmanip")
19384 (set_attr "mode" "SI")])
19386 ; False dependency happens when destination is only updated by tzcnt,
19387 ; lzcnt or popcnt. There is no false dependency when destination is
19388 ; also used in source.
19389 (define_insn "*popcountsi2_zext_2_falsedep"
19390 [(set (match_operand:DI 0 "register_operand" "=r")
19392 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19393 (unspec [(match_operand:DI 2 "register_operand" "0")]
19394 UNSPEC_INSN_FALSE_DEP)
19395 (clobber (reg:CC FLAGS_REG))]
19396 "TARGET_POPCNT && TARGET_64BIT"
19399 return "popcnt\t{%1, %k0|%k0, %1}";
19401 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19404 [(set_attr "prefix_rep" "1")
19405 (set_attr "type" "bitmanip")
19406 (set_attr "mode" "SI")])
19408 (define_insn_and_split "*popcounthi2_1"
19409 [(set (match_operand:SI 0 "register_operand")
19411 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19412 (clobber (reg:CC FLAGS_REG))]
19414 && ix86_pre_reload_split ()"
19419 rtx tmp = gen_reg_rtx (HImode);
19421 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19422 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19426 (define_insn_and_split "*popcounthi2_2"
19427 [(set (match_operand:SI 0 "register_operand")
19429 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19430 (clobber (reg:CC FLAGS_REG))]
19432 && ix86_pre_reload_split ()"
19437 rtx tmp = gen_reg_rtx (HImode);
19439 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19440 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19444 (define_insn "popcounthi2"
19445 [(set (match_operand:HI 0 "register_operand" "=r")
19447 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19448 (clobber (reg:CC FLAGS_REG))]
19452 return "popcnt\t{%1, %0|%0, %1}";
19454 return "popcnt{w}\t{%1, %0|%0, %1}";
19457 [(set_attr "prefix_rep" "1")
19458 (set_attr "type" "bitmanip")
19459 (set_attr "mode" "HI")])
19461 (define_expand "bswapdi2"
19462 [(set (match_operand:DI 0 "register_operand")
19463 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19467 operands[1] = force_reg (DImode, operands[1]);
19470 (define_expand "bswapsi2"
19471 [(set (match_operand:SI 0 "register_operand")
19472 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19477 else if (TARGET_BSWAP)
19478 operands[1] = force_reg (SImode, operands[1]);
19481 rtx x = operands[0];
19483 emit_move_insn (x, operands[1]);
19484 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19485 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19486 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19491 (define_insn "*bswap<mode>2_movbe"
19492 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19493 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19495 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19498 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19499 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19500 [(set_attr "type" "bitmanip,imov,imov")
19501 (set_attr "modrm" "0,1,1")
19502 (set_attr "prefix_0f" "*,1,1")
19503 (set_attr "prefix_extra" "*,1,1")
19504 (set_attr "mode" "<MODE>")])
19506 (define_insn "*bswap<mode>2"
19507 [(set (match_operand:SWI48 0 "register_operand" "=r")
19508 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19511 [(set_attr "type" "bitmanip")
19512 (set_attr "modrm" "0")
19513 (set_attr "mode" "<MODE>")])
19515 (define_expand "bswaphi2"
19516 [(set (match_operand:HI 0 "register_operand")
19517 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19520 (define_insn "*bswaphi2_movbe"
19521 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19522 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19524 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19526 xchg{b}\t{%h0, %b0|%b0, %h0}
19527 movbe{w}\t{%1, %0|%0, %1}
19528 movbe{w}\t{%1, %0|%0, %1}"
19529 [(set_attr "type" "imov")
19530 (set_attr "modrm" "*,1,1")
19531 (set_attr "prefix_0f" "*,1,1")
19532 (set_attr "prefix_extra" "*,1,1")
19533 (set_attr "pent_pair" "np,*,*")
19534 (set_attr "athlon_decode" "vector,*,*")
19535 (set_attr "amdfam10_decode" "double,*,*")
19536 (set_attr "bdver1_decode" "double,*,*")
19537 (set_attr "mode" "QI,HI,HI")])
19540 [(set (match_operand:HI 0 "general_reg_operand")
19541 (bswap:HI (match_dup 0)))]
19543 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19544 && peep2_regno_dead_p (0, FLAGS_REG)"
19545 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19546 (clobber (reg:CC FLAGS_REG))])])
19548 (define_insn "bswaphi_lowpart"
19549 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19550 (bswap:HI (match_dup 0)))
19551 (clobber (reg:CC FLAGS_REG))]
19554 xchg{b}\t{%h0, %b0|%b0, %h0}
19555 rol{w}\t{$8, %0|%0, 8}"
19556 [(set (attr "preferred_for_size")
19557 (cond [(eq_attr "alternative" "0")
19558 (symbol_ref "true")]
19559 (symbol_ref "false")))
19560 (set (attr "preferred_for_speed")
19561 (cond [(eq_attr "alternative" "0")
19562 (symbol_ref "TARGET_USE_XCHGB")]
19563 (symbol_ref "!TARGET_USE_XCHGB")))
19564 (set_attr "length" "2,4")
19565 (set_attr "mode" "QI,HI")])
19567 (define_expand "paritydi2"
19568 [(set (match_operand:DI 0 "register_operand")
19569 (parity:DI (match_operand:DI 1 "register_operand")))]
19572 rtx scratch = gen_reg_rtx (QImode);
19573 rtx hipart1 = gen_reg_rtx (SImode);
19574 rtx lopart1 = gen_reg_rtx (SImode);
19575 rtx xor1 = gen_reg_rtx (SImode);
19576 rtx shift2 = gen_reg_rtx (SImode);
19577 rtx hipart2 = gen_reg_rtx (HImode);
19578 rtx lopart2 = gen_reg_rtx (HImode);
19579 rtx xor2 = gen_reg_rtx (HImode);
19583 rtx shift1 = gen_reg_rtx (DImode);
19584 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19585 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19588 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19590 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19591 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19593 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19594 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19595 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19596 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19598 emit_insn (gen_parityhi2_cmp (xor2));
19600 ix86_expand_setcc (scratch, ORDERED,
19601 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19604 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19607 rtx tmp = gen_reg_rtx (SImode);
19609 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19610 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19615 (define_expand "paritysi2"
19616 [(set (match_operand:SI 0 "register_operand")
19617 (parity:SI (match_operand:SI 1 "register_operand")))]
19620 rtx scratch = gen_reg_rtx (QImode);
19621 rtx shift = gen_reg_rtx (SImode);
19622 rtx hipart = gen_reg_rtx (HImode);
19623 rtx lopart = gen_reg_rtx (HImode);
19624 rtx tmp = gen_reg_rtx (HImode);
19626 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19627 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19628 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19629 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19631 emit_insn (gen_parityhi2_cmp (tmp));
19633 ix86_expand_setcc (scratch, ORDERED,
19634 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19636 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19640 (define_expand "parityhi2"
19641 [(set (match_operand:HI 0 "register_operand")
19642 (parity:HI (match_operand:HI 1 "register_operand")))]
19645 rtx scratch = gen_reg_rtx (QImode);
19647 emit_insn (gen_parityhi2_cmp (operands[1]));
19649 ix86_expand_setcc (scratch, ORDERED,
19650 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19652 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19656 (define_expand "parityqi2"
19657 [(set (match_operand:QI 0 "register_operand")
19658 (parity:QI (match_operand:QI 1 "register_operand")))]
19661 emit_insn (gen_parityqi2_cmp (operands[1]));
19663 ix86_expand_setcc (operands[0], ORDERED,
19664 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19668 (define_insn "parityhi2_cmp"
19669 [(set (reg:CC FLAGS_REG)
19670 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19672 (clobber (match_dup 0))]
19674 "xor{b}\t{%h0, %b0|%b0, %h0}"
19675 [(set_attr "length" "2")
19676 (set_attr "mode" "QI")])
19678 (define_insn "parityqi2_cmp"
19679 [(set (reg:CC FLAGS_REG)
19680 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19684 [(set_attr "mode" "QI")])
19686 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19688 [(set (match_operand:HI 0 "register_operand")
19689 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19690 (parallel [(set (reg:CC FLAGS_REG)
19691 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19692 (clobber (match_dup 0))])]
19694 [(set (reg:CC FLAGS_REG)
19695 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19697 ;; Eliminate QImode popcount&1 using parity flag
19699 [(set (match_operand:SI 0 "register_operand")
19700 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19701 (parallel [(set (match_operand:SI 2 "register_operand")
19702 (popcount:SI (match_dup 0)))
19703 (clobber (reg:CC FLAGS_REG))])
19704 (set (reg:CCZ FLAGS_REG)
19705 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19708 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19709 [(reg:CCZ FLAGS_REG)
19711 (label_ref (match_operand 5))
19713 "REGNO (operands[2]) == REGNO (operands[3])
19714 && peep2_reg_dead_p (3, operands[0])
19715 && peep2_reg_dead_p (3, operands[2])
19716 && peep2_regno_dead_p (4, FLAGS_REG)"
19717 [(set (reg:CC FLAGS_REG)
19718 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19719 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19721 (label_ref (match_dup 5))
19724 operands[4] = shallow_copy_rtx (operands[4]);
19725 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19728 ;; Eliminate HImode popcount&1 using parity flag
19730 [(match_scratch:HI 0 "Q")
19731 (parallel [(set (match_operand:HI 1 "register_operand")
19733 (match_operand:HI 2 "nonimmediate_operand")))
19734 (clobber (reg:CC FLAGS_REG))])
19735 (set (match_operand 3 "register_operand")
19736 (zero_extend (match_dup 1)))
19737 (set (reg:CCZ FLAGS_REG)
19738 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19741 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19742 [(reg:CCZ FLAGS_REG)
19744 (label_ref (match_operand 6))
19746 "REGNO (operands[3]) == REGNO (operands[4])
19747 && peep2_reg_dead_p (3, operands[1])
19748 && peep2_reg_dead_p (3, operands[3])
19749 && peep2_regno_dead_p (4, FLAGS_REG)"
19750 [(set (match_dup 0) (match_dup 2))
19751 (parallel [(set (reg:CC FLAGS_REG)
19752 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19753 (clobber (match_dup 0))])
19754 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19756 (label_ref (match_dup 6))
19759 operands[5] = shallow_copy_rtx (operands[5]);
19760 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19763 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19765 [(match_scratch:HI 0 "Q")
19766 (parallel [(set (match_operand:HI 1 "register_operand")
19768 (match_operand:HI 2 "nonimmediate_operand")))
19769 (clobber (reg:CC FLAGS_REG))])
19770 (set (reg:CCZ FLAGS_REG)
19771 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19774 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19775 [(reg:CCZ FLAGS_REG)
19777 (label_ref (match_operand 5))
19779 "REGNO (operands[1]) == REGNO (operands[3])
19780 && peep2_reg_dead_p (2, operands[1])
19781 && peep2_reg_dead_p (2, operands[3])
19782 && peep2_regno_dead_p (3, FLAGS_REG)"
19783 [(set (match_dup 0) (match_dup 2))
19784 (parallel [(set (reg:CC FLAGS_REG)
19785 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19786 (clobber (match_dup 0))])
19787 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19789 (label_ref (match_dup 5))
19792 operands[4] = shallow_copy_rtx (operands[4]);
19793 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19797 ;; Thread-local storage patterns for ELF.
19799 ;; Note that these code sequences must appear exactly as shown
19800 ;; in order to allow linker relaxation.
19802 (define_insn "*tls_global_dynamic_32_gnu"
19803 [(set (match_operand:SI 0 "register_operand" "=a")
19805 [(match_operand:SI 1 "register_operand" "Yb")
19806 (match_operand 2 "tls_symbolic_operand")
19807 (match_operand 3 "constant_call_address_operand" "Bz")
19810 (clobber (match_scratch:SI 4 "=d"))
19811 (clobber (match_scratch:SI 5 "=c"))
19812 (clobber (reg:CC FLAGS_REG))]
19813 "!TARGET_64BIT && TARGET_GNU_TLS"
19815 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19817 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19820 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19821 if (TARGET_SUN_TLS)
19822 #ifdef HAVE_AS_IX86_TLSGDPLT
19823 return "call\t%a2@tlsgdplt";
19825 return "call\t%p3@plt";
19827 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19828 return "call\t%P3";
19829 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19831 [(set_attr "type" "multi")
19832 (set_attr "length" "12")])
19834 (define_expand "tls_global_dynamic_32"
19836 [(set (match_operand:SI 0 "register_operand")
19837 (unspec:SI [(match_operand:SI 2 "register_operand")
19838 (match_operand 1 "tls_symbolic_operand")
19839 (match_operand 3 "constant_call_address_operand")
19842 (clobber (scratch:SI))
19843 (clobber (scratch:SI))
19844 (clobber (reg:CC FLAGS_REG))])]
19846 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19848 (define_insn "*tls_global_dynamic_64_<mode>"
19849 [(set (match_operand:P 0 "register_operand" "=a")
19851 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19852 (match_operand 3)))
19853 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19859 /* The .loc directive has effect for 'the immediately following assembly
19860 instruction'. So for a sequence:
19864 the 'immediately following assembly instruction' is insn1.
19865 We want to emit an insn prefix here, but if we use .byte (as shown in
19866 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19867 inside the insn sequence, rather than to the start. After relaxation
19868 of the sequence by the linker, the .loc might point inside an insn.
19869 Use data16 prefix instead, which doesn't have this problem. */
19870 fputs ("\tdata16", asm_out_file);
19872 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19873 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19874 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19876 fputs (ASM_BYTE "0x66\n", asm_out_file);
19877 fputs ("\trex64\n", asm_out_file);
19878 if (TARGET_SUN_TLS)
19879 return "call\t%p2@plt";
19880 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19881 return "call\t%P2";
19882 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19884 [(set_attr "type" "multi")
19885 (set (attr "length")
19886 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19888 (define_insn "*tls_global_dynamic_64_largepic"
19889 [(set (match_operand:DI 0 "register_operand" "=a")
19891 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19892 (match_operand:DI 3 "immediate_operand" "i")))
19893 (match_operand 4)))
19894 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19897 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19898 && GET_CODE (operands[3]) == CONST
19899 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19900 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19903 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19904 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19905 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19906 return "call\t{*%%rax|rax}";
19908 [(set_attr "type" "multi")
19909 (set_attr "length" "22")])
19911 (define_expand "@tls_global_dynamic_64_<mode>"
19913 [(set (match_operand:P 0 "register_operand")
19915 (mem:QI (match_operand 2))
19917 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19921 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19923 (define_insn "*tls_local_dynamic_base_32_gnu"
19924 [(set (match_operand:SI 0 "register_operand" "=a")
19926 [(match_operand:SI 1 "register_operand" "Yb")
19927 (match_operand 2 "constant_call_address_operand" "Bz")
19929 UNSPEC_TLS_LD_BASE))
19930 (clobber (match_scratch:SI 3 "=d"))
19931 (clobber (match_scratch:SI 4 "=c"))
19932 (clobber (reg:CC FLAGS_REG))]
19933 "!TARGET_64BIT && TARGET_GNU_TLS"
19936 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19937 if (TARGET_SUN_TLS)
19939 if (HAVE_AS_IX86_TLSLDMPLT)
19940 return "call\t%&@tlsldmplt";
19942 return "call\t%p2@plt";
19944 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19945 return "call\t%P2";
19946 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19948 [(set_attr "type" "multi")
19949 (set_attr "length" "11")])
19951 (define_expand "tls_local_dynamic_base_32"
19953 [(set (match_operand:SI 0 "register_operand")
19955 [(match_operand:SI 1 "register_operand")
19956 (match_operand 2 "constant_call_address_operand")
19958 UNSPEC_TLS_LD_BASE))
19959 (clobber (scratch:SI))
19960 (clobber (scratch:SI))
19961 (clobber (reg:CC FLAGS_REG))])]
19963 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19965 (define_insn "*tls_local_dynamic_base_64_<mode>"
19966 [(set (match_operand:P 0 "register_operand" "=a")
19968 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19969 (match_operand 2)))
19970 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19974 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19975 if (TARGET_SUN_TLS)
19976 return "call\t%p1@plt";
19977 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19978 return "call\t%P1";
19979 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19981 [(set_attr "type" "multi")
19982 (set_attr "length" "12")])
19984 (define_insn "*tls_local_dynamic_base_64_largepic"
19985 [(set (match_operand:DI 0 "register_operand" "=a")
19987 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19988 (match_operand:DI 2 "immediate_operand" "i")))
19989 (match_operand 3)))
19990 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19991 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19992 && GET_CODE (operands[2]) == CONST
19993 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19994 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19997 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19998 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19999 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20000 return "call\t{*%%rax|rax}";
20002 [(set_attr "type" "multi")
20003 (set_attr "length" "22")])
20005 (define_expand "@tls_local_dynamic_base_64_<mode>"
20007 [(set (match_operand:P 0 "register_operand")
20009 (mem:QI (match_operand 1))
20011 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20013 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20015 ;; Local dynamic of a single variable is a lose. Show combine how
20016 ;; to convert that back to global dynamic.
20018 (define_insn_and_split "*tls_local_dynamic_32_once"
20019 [(set (match_operand:SI 0 "register_operand" "=a")
20021 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20022 (match_operand 2 "constant_call_address_operand" "Bz")
20024 UNSPEC_TLS_LD_BASE)
20025 (const:SI (unspec:SI
20026 [(match_operand 3 "tls_symbolic_operand")]
20028 (clobber (match_scratch:SI 4 "=d"))
20029 (clobber (match_scratch:SI 5 "=c"))
20030 (clobber (reg:CC FLAGS_REG))]
20035 [(set (match_dup 0)
20036 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20039 (clobber (match_dup 4))
20040 (clobber (match_dup 5))
20041 (clobber (reg:CC FLAGS_REG))])])
20043 ;; Load and add the thread base pointer from %<tp_seg>:0.
20044 (define_expand "get_thread_pointer<mode>"
20045 [(set (match_operand:PTR 0 "register_operand")
20046 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20049 /* targetm is not visible in the scope of the condition. */
20050 if (!targetm.have_tls)
20051 error ("%<__builtin_thread_pointer%> is not supported on this target");
20054 (define_insn_and_split "*load_tp_<mode>"
20055 [(set (match_operand:PTR 0 "register_operand" "=r")
20056 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20060 [(set (match_dup 0)
20063 addr_space_t as = DEFAULT_TLS_SEG_REG;
20065 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20066 set_mem_addr_space (operands[1], as);
20069 (define_insn_and_split "*load_tp_x32_zext"
20070 [(set (match_operand:DI 0 "register_operand" "=r")
20072 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20076 [(set (match_dup 0)
20077 (zero_extend:DI (match_dup 1)))]
20079 addr_space_t as = DEFAULT_TLS_SEG_REG;
20081 operands[1] = gen_const_mem (SImode, const0_rtx);
20082 set_mem_addr_space (operands[1], as);
20085 (define_insn_and_split "*add_tp_<mode>"
20086 [(set (match_operand:PTR 0 "register_operand" "=r")
20088 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20089 (match_operand:PTR 1 "register_operand" "0")))
20090 (clobber (reg:CC FLAGS_REG))]
20095 [(set (match_dup 0)
20096 (plus:PTR (match_dup 1) (match_dup 2)))
20097 (clobber (reg:CC FLAGS_REG))])]
20099 addr_space_t as = DEFAULT_TLS_SEG_REG;
20101 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20102 set_mem_addr_space (operands[2], as);
20105 (define_insn_and_split "*add_tp_x32_zext"
20106 [(set (match_operand:DI 0 "register_operand" "=r")
20108 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20109 (match_operand:SI 1 "register_operand" "0"))))
20110 (clobber (reg:CC FLAGS_REG))]
20115 [(set (match_dup 0)
20117 (plus:SI (match_dup 1) (match_dup 2))))
20118 (clobber (reg:CC FLAGS_REG))])]
20120 addr_space_t as = DEFAULT_TLS_SEG_REG;
20122 operands[2] = gen_const_mem (SImode, const0_rtx);
20123 set_mem_addr_space (operands[2], as);
20126 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20127 ;; %rax as destination of the initial executable code sequence.
20128 (define_insn "tls_initial_exec_64_sun"
20129 [(set (match_operand:DI 0 "register_operand" "=a")
20131 [(match_operand 1 "tls_symbolic_operand")]
20132 UNSPEC_TLS_IE_SUN))
20133 (clobber (reg:CC FLAGS_REG))]
20134 "TARGET_64BIT && TARGET_SUN_TLS"
20137 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20138 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20140 [(set_attr "type" "multi")])
20142 ;; GNU2 TLS patterns can be split.
20144 (define_expand "tls_dynamic_gnu2_32"
20145 [(set (match_dup 3)
20146 (plus:SI (match_operand:SI 2 "register_operand")
20148 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20151 [(set (match_operand:SI 0 "register_operand")
20152 (unspec:SI [(match_dup 1) (match_dup 3)
20153 (match_dup 2) (reg:SI SP_REG)]
20155 (clobber (reg:CC FLAGS_REG))])]
20156 "!TARGET_64BIT && TARGET_GNU2_TLS"
20158 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20159 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20162 (define_insn "*tls_dynamic_gnu2_lea_32"
20163 [(set (match_operand:SI 0 "register_operand" "=r")
20164 (plus:SI (match_operand:SI 1 "register_operand" "b")
20166 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20167 UNSPEC_TLSDESC))))]
20168 "!TARGET_64BIT && TARGET_GNU2_TLS"
20169 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20170 [(set_attr "type" "lea")
20171 (set_attr "mode" "SI")
20172 (set_attr "length" "6")
20173 (set_attr "length_address" "4")])
20175 (define_insn "*tls_dynamic_gnu2_call_32"
20176 [(set (match_operand:SI 0 "register_operand" "=a")
20177 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20178 (match_operand:SI 2 "register_operand" "0")
20179 ;; we have to make sure %ebx still points to the GOT
20180 (match_operand:SI 3 "register_operand" "b")
20183 (clobber (reg:CC FLAGS_REG))]
20184 "!TARGET_64BIT && TARGET_GNU2_TLS"
20185 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20186 [(set_attr "type" "call")
20187 (set_attr "length" "2")
20188 (set_attr "length_address" "0")])
20190 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20191 [(set (match_operand:SI 0 "register_operand" "=&a")
20193 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20194 (match_operand:SI 4)
20195 (match_operand:SI 2 "register_operand" "b")
20198 (const:SI (unspec:SI
20199 [(match_operand 1 "tls_symbolic_operand")]
20201 (clobber (reg:CC FLAGS_REG))]
20202 "!TARGET_64BIT && TARGET_GNU2_TLS"
20205 [(set (match_dup 0) (match_dup 5))]
20207 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20208 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20211 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20212 [(set (match_dup 2)
20213 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20216 [(set (match_operand:PTR 0 "register_operand")
20217 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "TARGET_64BIT && TARGET_GNU2_TLS"
20222 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20223 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20226 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20227 [(set (match_operand:PTR 0 "register_operand" "=r")
20228 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20230 "TARGET_64BIT && TARGET_GNU2_TLS"
20231 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20232 [(set_attr "type" "lea")
20233 (set_attr "mode" "<MODE>")
20234 (set_attr "length" "7")
20235 (set_attr "length_address" "4")])
20237 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20238 [(set (match_operand:PTR 0 "register_operand" "=a")
20239 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20240 (match_operand:PTR 2 "register_operand" "0")
20243 (clobber (reg:CC FLAGS_REG))]
20244 "TARGET_64BIT && TARGET_GNU2_TLS"
20245 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20246 [(set_attr "type" "call")
20247 (set_attr "length" "2")
20248 (set_attr "length_address" "0")])
20250 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20251 [(set (match_operand:PTR 0 "register_operand" "=&a")
20253 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20254 (match_operand:PTR 3)
20257 (const:PTR (unspec:PTR
20258 [(match_operand 1 "tls_symbolic_operand")]
20260 (clobber (reg:CC FLAGS_REG))]
20261 "TARGET_64BIT && TARGET_GNU2_TLS"
20264 [(set (match_dup 0) (match_dup 4))]
20266 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20267 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20271 [(match_operand 0 "tls_address_pattern")]
20272 "TARGET_TLS_DIRECT_SEG_REFS"
20274 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20277 ;; These patterns match the binary 387 instructions for addM3, subM3,
20278 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20279 ;; SFmode. The first is the normal insn, the second the same insn but
20280 ;; with one operand a conversion, and the third the same insn but with
20281 ;; the other operand a conversion. The conversion may be SFmode or
20282 ;; SImode if the target mode DFmode, but only SImode if the target mode
20285 ;; Gcc is slightly more smart about handling normal two address instructions
20286 ;; so use special patterns for add and mull.
20288 (define_insn "*fop_xf_comm_i387"
20289 [(set (match_operand:XF 0 "register_operand" "=f")
20290 (match_operator:XF 3 "binary_fp_operator"
20291 [(match_operand:XF 1 "register_operand" "%0")
20292 (match_operand:XF 2 "register_operand" "f")]))]
20294 && COMMUTATIVE_ARITH_P (operands[3])"
20295 "* return output_387_binary_op (insn, operands);"
20296 [(set (attr "type")
20297 (if_then_else (match_operand:XF 3 "mult_operator")
20298 (const_string "fmul")
20299 (const_string "fop")))
20300 (set_attr "mode" "XF")])
20302 (define_insn "*fop_<mode>_comm"
20303 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20304 (match_operator:MODEF 3 "binary_fp_operator"
20305 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20306 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20307 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20308 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20309 && COMMUTATIVE_ARITH_P (operands[3])
20310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20311 "* return output_387_binary_op (insn, operands);"
20312 [(set (attr "type")
20313 (if_then_else (eq_attr "alternative" "1,2")
20314 (if_then_else (match_operand:MODEF 3 "mult_operator")
20315 (const_string "ssemul")
20316 (const_string "sseadd"))
20317 (if_then_else (match_operand:MODEF 3 "mult_operator")
20318 (const_string "fmul")
20319 (const_string "fop"))))
20320 (set_attr "isa" "*,noavx,avx")
20321 (set_attr "prefix" "orig,orig,vex")
20322 (set_attr "mode" "<MODE>")
20323 (set (attr "enabled")
20325 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20327 (eq_attr "alternative" "0")
20328 (symbol_ref "TARGET_MIX_SSE_I387
20329 && X87_ENABLE_ARITH (<MODE>mode)")
20330 (const_string "*"))
20332 (eq_attr "alternative" "0")
20333 (symbol_ref "true")
20334 (symbol_ref "false"))))])
20336 (define_insn "*<insn>hf"
20337 [(set (match_operand:HF 0 "register_operand" "=v")
20338 (plusminusmultdiv:HF
20339 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20340 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20343 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20344 [(set_attr "prefix" "evex")
20345 (set_attr "mode" "HF")])
20347 (define_insn "*rcpsf2_sse"
20348 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20349 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20351 "TARGET_SSE && TARGET_SSE_MATH"
20353 %vrcpss\t{%d1, %0|%0, %d1}
20354 %vrcpss\t{%d1, %0|%0, %d1}
20355 rcpss\t{%1, %d0|%d0, %1}
20356 vrcpss\t{%1, %d0|%d0, %1}"
20357 [(set_attr "isa" "*,*,noavx,avx")
20358 (set_attr "gpr32" "1,1,1,0")
20359 (set_attr "type" "sse")
20360 (set_attr "atom_sse_attr" "rcp")
20361 (set_attr "btver2_sse_attr" "rcp")
20362 (set_attr "prefix" "maybe_vex")
20363 (set_attr "mode" "SF")
20364 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20365 (set (attr "preferred_for_speed")
20366 (cond [(match_test "TARGET_AVX")
20367 (symbol_ref "true")
20368 (eq_attr "alternative" "1,2,3")
20369 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20371 (symbol_ref "true")))])
20373 (define_insn "rcphf2"
20374 [(set (match_operand:HF 0 "register_operand" "=v,v")
20375 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20377 "TARGET_AVX512FP16"
20379 vrcpsh\t{%d1, %0|%0, %d1}
20380 vrcpsh\t{%1, %d0|%d0, %1}"
20381 [(set_attr "type" "sse")
20382 (set_attr "prefix" "evex")
20383 (set_attr "mode" "HF")
20384 (set_attr "avx_partial_xmm_update" "false,true")])
20386 (define_insn "*fop_xf_1_i387"
20387 [(set (match_operand:XF 0 "register_operand" "=f,f")
20388 (match_operator:XF 3 "binary_fp_operator"
20389 [(match_operand:XF 1 "register_operand" "0,f")
20390 (match_operand:XF 2 "register_operand" "f,0")]))]
20392 && !COMMUTATIVE_ARITH_P (operands[3])"
20393 "* return output_387_binary_op (insn, operands);"
20394 [(set (attr "type")
20395 (if_then_else (match_operand:XF 3 "div_operator")
20396 (const_string "fdiv")
20397 (const_string "fop")))
20398 (set_attr "mode" "XF")])
20400 (define_insn "*fop_<mode>_1"
20401 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20402 (match_operator:MODEF 3 "binary_fp_operator"
20403 [(match_operand:MODEF 1
20404 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20405 (match_operand:MODEF 2
20406 "nonimmediate_operand" "fm,0,xm,vm")]))]
20407 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20408 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20409 && !COMMUTATIVE_ARITH_P (operands[3])
20410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20411 "* return output_387_binary_op (insn, operands);"
20412 [(set (attr "type")
20413 (if_then_else (eq_attr "alternative" "2,3")
20414 (if_then_else (match_operand:MODEF 3 "div_operator")
20415 (const_string "ssediv")
20416 (const_string "sseadd"))
20417 (if_then_else (match_operand:MODEF 3 "div_operator")
20418 (const_string "fdiv")
20419 (const_string "fop"))))
20420 (set_attr "isa" "*,*,noavx,avx")
20421 (set_attr "prefix" "orig,orig,orig,vex")
20422 (set_attr "mode" "<MODE>")
20423 (set (attr "enabled")
20425 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20427 (eq_attr "alternative" "0,1")
20428 (symbol_ref "TARGET_MIX_SSE_I387
20429 && X87_ENABLE_ARITH (<MODE>mode)")
20430 (const_string "*"))
20432 (eq_attr "alternative" "0,1")
20433 (symbol_ref "true")
20434 (symbol_ref "false"))))])
20436 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20437 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20438 (match_operator:X87MODEF 3 "binary_fp_operator"
20440 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20441 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20442 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20443 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20444 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20445 || optimize_function_for_size_p (cfun))"
20446 "* return output_387_binary_op (insn, operands);"
20447 [(set (attr "type")
20448 (cond [(match_operand:X87MODEF 3 "mult_operator")
20449 (const_string "fmul")
20450 (match_operand:X87MODEF 3 "div_operator")
20451 (const_string "fdiv")
20453 (const_string "fop")))
20454 (set_attr "fp_int_src" "true")
20455 (set_attr "mode" "<SWI24:MODE>")])
20457 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20458 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20459 (match_operator:X87MODEF 3 "binary_fp_operator"
20460 [(match_operand:X87MODEF 1 "register_operand" "0")
20462 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20463 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20464 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20465 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20466 || optimize_function_for_size_p (cfun))"
20467 "* return output_387_binary_op (insn, operands);"
20468 [(set (attr "type")
20469 (cond [(match_operand:X87MODEF 3 "mult_operator")
20470 (const_string "fmul")
20471 (match_operand:X87MODEF 3 "div_operator")
20472 (const_string "fdiv")
20474 (const_string "fop")))
20475 (set_attr "fp_int_src" "true")
20476 (set_attr "mode" "<SWI24:MODE>")])
20478 (define_insn "*fop_xf_4_i387"
20479 [(set (match_operand:XF 0 "register_operand" "=f,f")
20480 (match_operator:XF 3 "binary_fp_operator"
20482 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20483 (match_operand:XF 2 "register_operand" "0,f")]))]
20485 "* return output_387_binary_op (insn, operands);"
20486 [(set (attr "type")
20487 (cond [(match_operand:XF 3 "mult_operator")
20488 (const_string "fmul")
20489 (match_operand:XF 3 "div_operator")
20490 (const_string "fdiv")
20492 (const_string "fop")))
20493 (set_attr "mode" "<MODE>")])
20495 (define_insn "*fop_df_4_i387"
20496 [(set (match_operand:DF 0 "register_operand" "=f,f")
20497 (match_operator:DF 3 "binary_fp_operator"
20499 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20500 (match_operand:DF 2 "register_operand" "0,f")]))]
20501 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20502 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20503 "* return output_387_binary_op (insn, operands);"
20504 [(set (attr "type")
20505 (cond [(match_operand:DF 3 "mult_operator")
20506 (const_string "fmul")
20507 (match_operand:DF 3 "div_operator")
20508 (const_string "fdiv")
20510 (const_string "fop")))
20511 (set_attr "mode" "SF")])
20513 (define_insn "*fop_xf_5_i387"
20514 [(set (match_operand:XF 0 "register_operand" "=f,f")
20515 (match_operator:XF 3 "binary_fp_operator"
20516 [(match_operand:XF 1 "register_operand" "0,f")
20518 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20520 "* return output_387_binary_op (insn, operands);"
20521 [(set (attr "type")
20522 (cond [(match_operand:XF 3 "mult_operator")
20523 (const_string "fmul")
20524 (match_operand:XF 3 "div_operator")
20525 (const_string "fdiv")
20527 (const_string "fop")))
20528 (set_attr "mode" "<MODE>")])
20530 (define_insn "*fop_df_5_i387"
20531 [(set (match_operand:DF 0 "register_operand" "=f,f")
20532 (match_operator:DF 3 "binary_fp_operator"
20533 [(match_operand:DF 1 "register_operand" "0,f")
20535 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20536 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20537 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20538 "* return output_387_binary_op (insn, operands);"
20539 [(set (attr "type")
20540 (cond [(match_operand:DF 3 "mult_operator")
20541 (const_string "fmul")
20542 (match_operand:DF 3 "div_operator")
20543 (const_string "fdiv")
20545 (const_string "fop")))
20546 (set_attr "mode" "SF")])
20548 (define_insn "*fop_xf_6_i387"
20549 [(set (match_operand:XF 0 "register_operand" "=f,f")
20550 (match_operator:XF 3 "binary_fp_operator"
20552 (match_operand:MODEF 1 "register_operand" "0,f"))
20554 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20556 "* return output_387_binary_op (insn, operands);"
20557 [(set (attr "type")
20558 (cond [(match_operand:XF 3 "mult_operator")
20559 (const_string "fmul")
20560 (match_operand:XF 3 "div_operator")
20561 (const_string "fdiv")
20563 (const_string "fop")))
20564 (set_attr "mode" "<MODE>")])
20566 (define_insn "*fop_df_6_i387"
20567 [(set (match_operand:DF 0 "register_operand" "=f,f")
20568 (match_operator:DF 3 "binary_fp_operator"
20570 (match_operand:SF 1 "register_operand" "0,f"))
20572 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20573 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20574 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20575 "* return output_387_binary_op (insn, operands);"
20576 [(set (attr "type")
20577 (cond [(match_operand:DF 3 "mult_operator")
20578 (const_string "fmul")
20579 (match_operand:DF 3 "div_operator")
20580 (const_string "fdiv")
20582 (const_string "fop")))
20583 (set_attr "mode" "SF")])
20585 ;; FPU special functions.
20587 ;; This pattern implements a no-op XFmode truncation for
20588 ;; all fancy i386 XFmode math functions.
20590 (define_insn "truncxf<mode>2_i387_noop_unspec"
20591 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20592 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20593 UNSPEC_TRUNC_NOOP))]
20594 "TARGET_USE_FANCY_MATH_387"
20595 "* return output_387_reg_move (insn, operands);"
20596 [(set_attr "type" "fmov")
20597 (set_attr "mode" "<MODE>")])
20599 (define_insn "sqrtxf2"
20600 [(set (match_operand:XF 0 "register_operand" "=f")
20601 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20602 "TARGET_USE_FANCY_MATH_387"
20604 [(set_attr "type" "fpspc")
20605 (set_attr "mode" "XF")
20606 (set_attr "athlon_decode" "direct")
20607 (set_attr "amdfam10_decode" "direct")
20608 (set_attr "bdver1_decode" "direct")])
20610 (define_insn "*rsqrtsf2_sse"
20611 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20612 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20614 "TARGET_SSE && TARGET_SSE_MATH"
20616 %vrsqrtss\t{%d1, %0|%0, %d1}
20617 %vrsqrtss\t{%d1, %0|%0, %d1}
20618 rsqrtss\t{%1, %d0|%d0, %1}
20619 vrsqrtss\t{%1, %d0|%d0, %1}"
20620 [(set_attr "isa" "*,*,noavx,avx")
20621 (set_attr "gpr32" "1,1,1,0")
20622 (set_attr "type" "sse")
20623 (set_attr "atom_sse_attr" "rcp")
20624 (set_attr "btver2_sse_attr" "rcp")
20625 (set_attr "prefix" "maybe_vex")
20626 (set_attr "mode" "SF")
20627 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20628 (set (attr "preferred_for_speed")
20629 (cond [(match_test "TARGET_AVX")
20630 (symbol_ref "true")
20631 (eq_attr "alternative" "1,2,3")
20632 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20634 (symbol_ref "true")))])
20636 (define_expand "rsqrtsf2"
20637 [(set (match_operand:SF 0 "register_operand")
20638 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20640 "TARGET_SSE && TARGET_SSE_MATH"
20642 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20646 (define_insn "rsqrthf2"
20647 [(set (match_operand:HF 0 "register_operand" "=v,v")
20648 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20650 "TARGET_AVX512FP16"
20652 vrsqrtsh\t{%d1, %0|%0, %d1}
20653 vrsqrtsh\t{%1, %d0|%d0, %1}"
20654 [(set_attr "type" "sse")
20655 (set_attr "prefix" "evex")
20656 (set_attr "avx_partial_xmm_update" "false,true")
20657 (set_attr "mode" "HF")])
20659 (define_insn "sqrthf2"
20660 [(set (match_operand:HF 0 "register_operand" "=v,v")
20662 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20663 "TARGET_AVX512FP16"
20665 vsqrtsh\t{%d1, %0|%0, %d1}
20666 vsqrtsh\t{%1, %d0|%d0, %1}"
20667 [(set_attr "type" "sse")
20668 (set_attr "prefix" "evex")
20669 (set_attr "avx_partial_xmm_update" "false,true")
20670 (set_attr "mode" "HF")])
20672 (define_insn "*sqrt<mode>2_sse"
20673 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20675 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20678 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20679 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20680 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20681 [(set_attr "type" "sse")
20682 (set_attr "atom_sse_attr" "sqrt")
20683 (set_attr "btver2_sse_attr" "sqrt")
20684 (set_attr "prefix" "maybe_vex")
20685 (set_attr "avx_partial_xmm_update" "false,false,true")
20686 (set_attr "mode" "<MODE>")
20687 (set (attr "preferred_for_speed")
20688 (cond [(match_test "TARGET_AVX")
20689 (symbol_ref "true")
20690 (eq_attr "alternative" "1,2")
20691 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20693 (symbol_ref "true")))])
20695 (define_expand "sqrt<mode>2"
20696 [(set (match_operand:MODEF 0 "register_operand")
20698 (match_operand:MODEF 1 "nonimmediate_operand")))]
20699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20702 if (<MODE>mode == SFmode
20703 && TARGET_SSE && TARGET_SSE_MATH
20704 && TARGET_RECIP_SQRT
20705 && !optimize_function_for_size_p (cfun)
20706 && flag_finite_math_only && !flag_trapping_math
20707 && flag_unsafe_math_optimizations)
20709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20715 rtx op0 = gen_reg_rtx (XFmode);
20716 rtx op1 = gen_reg_rtx (XFmode);
20718 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20719 emit_insn (gen_sqrtxf2 (op0, op1));
20720 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20725 (define_expand "hypot<mode>3"
20726 [(use (match_operand:MODEF 0 "register_operand"))
20727 (use (match_operand:MODEF 1 "general_operand"))
20728 (use (match_operand:MODEF 2 "general_operand"))]
20729 "TARGET_USE_FANCY_MATH_387
20730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20731 || TARGET_MIX_SSE_I387)
20732 && flag_finite_math_only
20733 && flag_unsafe_math_optimizations"
20735 rtx op0 = gen_reg_rtx (XFmode);
20736 rtx op1 = gen_reg_rtx (XFmode);
20737 rtx op2 = gen_reg_rtx (XFmode);
20739 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20742 emit_insn (gen_mulxf3 (op1, op1, op1));
20743 emit_insn (gen_mulxf3 (op2, op2, op2));
20744 emit_insn (gen_addxf3 (op0, op2, op1));
20745 emit_insn (gen_sqrtxf2 (op0, op0));
20747 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20751 (define_insn "x86_fnstsw_1"
20752 [(set (match_operand:HI 0 "register_operand" "=a")
20753 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20756 [(set_attr "length" "2")
20757 (set_attr "mode" "SI")
20758 (set_attr "unit" "i387")])
20760 (define_insn "fpremxf4_i387"
20761 [(set (match_operand:XF 0 "register_operand" "=f")
20762 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20763 (match_operand:XF 3 "register_operand" "1")]
20765 (set (match_operand:XF 1 "register_operand" "=f")
20766 (unspec:XF [(match_dup 2) (match_dup 3)]
20768 (set (reg:CCFP FPSR_REG)
20769 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20771 "TARGET_USE_FANCY_MATH_387"
20773 [(set_attr "type" "fpspc")
20774 (set_attr "znver1_decode" "vector")
20775 (set_attr "mode" "XF")])
20777 (define_expand "fmodxf3"
20778 [(use (match_operand:XF 0 "register_operand"))
20779 (use (match_operand:XF 1 "general_operand"))
20780 (use (match_operand:XF 2 "general_operand"))]
20781 "TARGET_USE_FANCY_MATH_387"
20783 rtx_code_label *label = gen_label_rtx ();
20785 rtx op1 = gen_reg_rtx (XFmode);
20786 rtx op2 = gen_reg_rtx (XFmode);
20788 emit_move_insn (op2, operands[2]);
20789 emit_move_insn (op1, operands[1]);
20791 emit_label (label);
20792 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20793 ix86_emit_fp_unordered_jump (label);
20794 LABEL_NUSES (label) = 1;
20796 emit_move_insn (operands[0], op1);
20800 (define_expand "fmod<mode>3"
20801 [(use (match_operand:MODEF 0 "register_operand"))
20802 (use (match_operand:MODEF 1 "general_operand"))
20803 (use (match_operand:MODEF 2 "general_operand"))]
20804 "TARGET_USE_FANCY_MATH_387"
20806 rtx (*gen_truncxf) (rtx, rtx);
20808 rtx_code_label *label = gen_label_rtx ();
20810 rtx op1 = gen_reg_rtx (XFmode);
20811 rtx op2 = gen_reg_rtx (XFmode);
20813 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20814 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20816 emit_label (label);
20817 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20818 ix86_emit_fp_unordered_jump (label);
20819 LABEL_NUSES (label) = 1;
20821 /* Truncate the result properly for strict SSE math. */
20822 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20823 && !TARGET_MIX_SSE_I387)
20824 gen_truncxf = gen_truncxf<mode>2;
20826 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20828 emit_insn (gen_truncxf (operands[0], op1));
20832 (define_insn "fprem1xf4_i387"
20833 [(set (match_operand:XF 0 "register_operand" "=f")
20834 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20835 (match_operand:XF 3 "register_operand" "1")]
20837 (set (match_operand:XF 1 "register_operand" "=f")
20838 (unspec:XF [(match_dup 2) (match_dup 3)]
20840 (set (reg:CCFP FPSR_REG)
20841 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20843 "TARGET_USE_FANCY_MATH_387"
20845 [(set_attr "type" "fpspc")
20846 (set_attr "znver1_decode" "vector")
20847 (set_attr "mode" "XF")])
20849 (define_expand "remainderxf3"
20850 [(use (match_operand:XF 0 "register_operand"))
20851 (use (match_operand:XF 1 "general_operand"))
20852 (use (match_operand:XF 2 "general_operand"))]
20853 "TARGET_USE_FANCY_MATH_387"
20855 rtx_code_label *label = gen_label_rtx ();
20857 rtx op1 = gen_reg_rtx (XFmode);
20858 rtx op2 = gen_reg_rtx (XFmode);
20860 emit_move_insn (op2, operands[2]);
20861 emit_move_insn (op1, operands[1]);
20863 emit_label (label);
20864 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20865 ix86_emit_fp_unordered_jump (label);
20866 LABEL_NUSES (label) = 1;
20868 emit_move_insn (operands[0], op1);
20872 (define_expand "remainder<mode>3"
20873 [(use (match_operand:MODEF 0 "register_operand"))
20874 (use (match_operand:MODEF 1 "general_operand"))
20875 (use (match_operand:MODEF 2 "general_operand"))]
20876 "TARGET_USE_FANCY_MATH_387"
20878 rtx (*gen_truncxf) (rtx, rtx);
20880 rtx_code_label *label = gen_label_rtx ();
20882 rtx op1 = gen_reg_rtx (XFmode);
20883 rtx op2 = gen_reg_rtx (XFmode);
20885 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20886 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20888 emit_label (label);
20890 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20891 ix86_emit_fp_unordered_jump (label);
20892 LABEL_NUSES (label) = 1;
20894 /* Truncate the result properly for strict SSE math. */
20895 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20896 && !TARGET_MIX_SSE_I387)
20897 gen_truncxf = gen_truncxf<mode>2;
20899 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20901 emit_insn (gen_truncxf (operands[0], op1));
20905 (define_int_iterator SINCOS
20909 (define_int_attr sincos
20910 [(UNSPEC_SIN "sin")
20911 (UNSPEC_COS "cos")])
20913 (define_insn "<sincos>xf2"
20914 [(set (match_operand:XF 0 "register_operand" "=f")
20915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20917 "TARGET_USE_FANCY_MATH_387
20918 && flag_unsafe_math_optimizations"
20920 [(set_attr "type" "fpspc")
20921 (set_attr "znver1_decode" "vector")
20922 (set_attr "mode" "XF")])
20924 (define_expand "<sincos><mode>2"
20925 [(set (match_operand:MODEF 0 "register_operand")
20926 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20928 "TARGET_USE_FANCY_MATH_387
20929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20930 || TARGET_MIX_SSE_I387)
20931 && flag_unsafe_math_optimizations"
20933 rtx op0 = gen_reg_rtx (XFmode);
20934 rtx op1 = gen_reg_rtx (XFmode);
20936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20937 emit_insn (gen_<sincos>xf2 (op0, op1));
20938 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20942 (define_insn "sincosxf3"
20943 [(set (match_operand:XF 0 "register_operand" "=f")
20944 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20945 UNSPEC_SINCOS_COS))
20946 (set (match_operand:XF 1 "register_operand" "=f")
20947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20948 "TARGET_USE_FANCY_MATH_387
20949 && flag_unsafe_math_optimizations"
20951 [(set_attr "type" "fpspc")
20952 (set_attr "znver1_decode" "vector")
20953 (set_attr "mode" "XF")])
20955 (define_expand "sincos<mode>3"
20956 [(use (match_operand:MODEF 0 "register_operand"))
20957 (use (match_operand:MODEF 1 "register_operand"))
20958 (use (match_operand:MODEF 2 "general_operand"))]
20959 "TARGET_USE_FANCY_MATH_387
20960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961 || TARGET_MIX_SSE_I387)
20962 && flag_unsafe_math_optimizations"
20964 rtx op0 = gen_reg_rtx (XFmode);
20965 rtx op1 = gen_reg_rtx (XFmode);
20966 rtx op2 = gen_reg_rtx (XFmode);
20968 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20969 emit_insn (gen_sincosxf3 (op0, op1, op2));
20970 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20971 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20975 (define_insn "fptanxf4_i387"
20976 [(set (match_operand:SF 0 "register_operand" "=f")
20977 (match_operand:SF 3 "const1_operand"))
20978 (set (match_operand:XF 1 "register_operand" "=f")
20979 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20981 "TARGET_USE_FANCY_MATH_387
20982 && flag_unsafe_math_optimizations"
20984 [(set_attr "type" "fpspc")
20985 (set_attr "znver1_decode" "vector")
20986 (set_attr "mode" "XF")])
20988 (define_expand "tanxf2"
20989 [(use (match_operand:XF 0 "register_operand"))
20990 (use (match_operand:XF 1 "register_operand"))]
20991 "TARGET_USE_FANCY_MATH_387
20992 && flag_unsafe_math_optimizations"
20994 rtx one = gen_reg_rtx (SFmode);
20995 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20996 CONST1_RTX (SFmode)));
21000 (define_expand "tan<mode>2"
21001 [(use (match_operand:MODEF 0 "register_operand"))
21002 (use (match_operand:MODEF 1 "general_operand"))]
21003 "TARGET_USE_FANCY_MATH_387
21004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21005 || TARGET_MIX_SSE_I387)
21006 && flag_unsafe_math_optimizations"
21008 rtx op0 = gen_reg_rtx (XFmode);
21009 rtx op1 = gen_reg_rtx (XFmode);
21011 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21012 emit_insn (gen_tanxf2 (op0, op1));
21013 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21017 (define_insn "atan2xf3"
21018 [(set (match_operand:XF 0 "register_operand" "=f")
21019 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21020 (match_operand:XF 1 "register_operand" "f")]
21022 (clobber (match_scratch:XF 3 "=1"))]
21023 "TARGET_USE_FANCY_MATH_387
21024 && flag_unsafe_math_optimizations"
21026 [(set_attr "type" "fpspc")
21027 (set_attr "znver1_decode" "vector")
21028 (set_attr "mode" "XF")])
21030 (define_expand "atan2<mode>3"
21031 [(use (match_operand:MODEF 0 "register_operand"))
21032 (use (match_operand:MODEF 1 "general_operand"))
21033 (use (match_operand:MODEF 2 "general_operand"))]
21034 "TARGET_USE_FANCY_MATH_387
21035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21036 || TARGET_MIX_SSE_I387)
21037 && flag_unsafe_math_optimizations"
21039 rtx op0 = gen_reg_rtx (XFmode);
21040 rtx op1 = gen_reg_rtx (XFmode);
21041 rtx op2 = gen_reg_rtx (XFmode);
21043 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21046 emit_insn (gen_atan2xf3 (op0, op1, op2));
21047 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21051 (define_expand "atanxf2"
21052 [(parallel [(set (match_operand:XF 0 "register_operand")
21053 (unspec:XF [(match_dup 2)
21054 (match_operand:XF 1 "register_operand")]
21056 (clobber (scratch:XF))])]
21057 "TARGET_USE_FANCY_MATH_387
21058 && flag_unsafe_math_optimizations"
21059 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21061 (define_expand "atan<mode>2"
21062 [(use (match_operand:MODEF 0 "register_operand"))
21063 (use (match_operand:MODEF 1 "general_operand"))]
21064 "TARGET_USE_FANCY_MATH_387
21065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21066 || TARGET_MIX_SSE_I387)
21067 && flag_unsafe_math_optimizations"
21069 rtx op0 = gen_reg_rtx (XFmode);
21070 rtx op1 = gen_reg_rtx (XFmode);
21072 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21073 emit_insn (gen_atanxf2 (op0, op1));
21074 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21078 (define_expand "asinxf2"
21079 [(set (match_dup 2)
21080 (mult:XF (match_operand:XF 1 "register_operand")
21082 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21083 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21084 (parallel [(set (match_operand:XF 0 "register_operand")
21085 (unspec:XF [(match_dup 5) (match_dup 1)]
21087 (clobber (scratch:XF))])]
21088 "TARGET_USE_FANCY_MATH_387
21089 && flag_unsafe_math_optimizations"
21093 for (i = 2; i < 6; i++)
21094 operands[i] = gen_reg_rtx (XFmode);
21096 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21099 (define_expand "asin<mode>2"
21100 [(use (match_operand:MODEF 0 "register_operand"))
21101 (use (match_operand:MODEF 1 "general_operand"))]
21102 "TARGET_USE_FANCY_MATH_387
21103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21104 || TARGET_MIX_SSE_I387)
21105 && flag_unsafe_math_optimizations"
21107 rtx op0 = gen_reg_rtx (XFmode);
21108 rtx op1 = gen_reg_rtx (XFmode);
21110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21111 emit_insn (gen_asinxf2 (op0, op1));
21112 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21116 (define_expand "acosxf2"
21117 [(set (match_dup 2)
21118 (mult:XF (match_operand:XF 1 "register_operand")
21120 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21121 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21122 (parallel [(set (match_operand:XF 0 "register_operand")
21123 (unspec:XF [(match_dup 1) (match_dup 5)]
21125 (clobber (scratch:XF))])]
21126 "TARGET_USE_FANCY_MATH_387
21127 && flag_unsafe_math_optimizations"
21131 for (i = 2; i < 6; i++)
21132 operands[i] = gen_reg_rtx (XFmode);
21134 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21137 (define_expand "acos<mode>2"
21138 [(use (match_operand:MODEF 0 "register_operand"))
21139 (use (match_operand:MODEF 1 "general_operand"))]
21140 "TARGET_USE_FANCY_MATH_387
21141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21142 || TARGET_MIX_SSE_I387)
21143 && flag_unsafe_math_optimizations"
21145 rtx op0 = gen_reg_rtx (XFmode);
21146 rtx op1 = gen_reg_rtx (XFmode);
21148 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21149 emit_insn (gen_acosxf2 (op0, op1));
21150 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21154 (define_expand "sinhxf2"
21155 [(use (match_operand:XF 0 "register_operand"))
21156 (use (match_operand:XF 1 "register_operand"))]
21157 "TARGET_USE_FANCY_MATH_387
21158 && flag_finite_math_only
21159 && flag_unsafe_math_optimizations"
21161 ix86_emit_i387_sinh (operands[0], operands[1]);
21165 (define_expand "sinh<mode>2"
21166 [(use (match_operand:MODEF 0 "register_operand"))
21167 (use (match_operand:MODEF 1 "general_operand"))]
21168 "TARGET_USE_FANCY_MATH_387
21169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21170 || TARGET_MIX_SSE_I387)
21171 && flag_finite_math_only
21172 && flag_unsafe_math_optimizations"
21174 rtx op0 = gen_reg_rtx (XFmode);
21175 rtx op1 = gen_reg_rtx (XFmode);
21177 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21178 emit_insn (gen_sinhxf2 (op0, op1));
21179 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21183 (define_expand "coshxf2"
21184 [(use (match_operand:XF 0 "register_operand"))
21185 (use (match_operand:XF 1 "register_operand"))]
21186 "TARGET_USE_FANCY_MATH_387
21187 && flag_unsafe_math_optimizations"
21189 ix86_emit_i387_cosh (operands[0], operands[1]);
21193 (define_expand "cosh<mode>2"
21194 [(use (match_operand:MODEF 0 "register_operand"))
21195 (use (match_operand:MODEF 1 "general_operand"))]
21196 "TARGET_USE_FANCY_MATH_387
21197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21198 || TARGET_MIX_SSE_I387)
21199 && flag_unsafe_math_optimizations"
21201 rtx op0 = gen_reg_rtx (XFmode);
21202 rtx op1 = gen_reg_rtx (XFmode);
21204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21205 emit_insn (gen_coshxf2 (op0, op1));
21206 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21210 (define_expand "tanhxf2"
21211 [(use (match_operand:XF 0 "register_operand"))
21212 (use (match_operand:XF 1 "register_operand"))]
21213 "TARGET_USE_FANCY_MATH_387
21214 && flag_unsafe_math_optimizations"
21216 ix86_emit_i387_tanh (operands[0], operands[1]);
21220 (define_expand "tanh<mode>2"
21221 [(use (match_operand:MODEF 0 "register_operand"))
21222 (use (match_operand:MODEF 1 "general_operand"))]
21223 "TARGET_USE_FANCY_MATH_387
21224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21225 || TARGET_MIX_SSE_I387)
21226 && flag_unsafe_math_optimizations"
21228 rtx op0 = gen_reg_rtx (XFmode);
21229 rtx op1 = gen_reg_rtx (XFmode);
21231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21232 emit_insn (gen_tanhxf2 (op0, op1));
21233 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21237 (define_expand "asinhxf2"
21238 [(use (match_operand:XF 0 "register_operand"))
21239 (use (match_operand:XF 1 "register_operand"))]
21240 "TARGET_USE_FANCY_MATH_387
21241 && flag_finite_math_only
21242 && flag_unsafe_math_optimizations"
21244 ix86_emit_i387_asinh (operands[0], operands[1]);
21248 (define_expand "asinh<mode>2"
21249 [(use (match_operand:MODEF 0 "register_operand"))
21250 (use (match_operand:MODEF 1 "general_operand"))]
21251 "TARGET_USE_FANCY_MATH_387
21252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21253 || TARGET_MIX_SSE_I387)
21254 && flag_finite_math_only
21255 && flag_unsafe_math_optimizations"
21257 rtx op0 = gen_reg_rtx (XFmode);
21258 rtx op1 = gen_reg_rtx (XFmode);
21260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21261 emit_insn (gen_asinhxf2 (op0, op1));
21262 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21266 (define_expand "acoshxf2"
21267 [(use (match_operand:XF 0 "register_operand"))
21268 (use (match_operand:XF 1 "register_operand"))]
21269 "TARGET_USE_FANCY_MATH_387
21270 && flag_unsafe_math_optimizations"
21272 ix86_emit_i387_acosh (operands[0], operands[1]);
21276 (define_expand "acosh<mode>2"
21277 [(use (match_operand:MODEF 0 "register_operand"))
21278 (use (match_operand:MODEF 1 "general_operand"))]
21279 "TARGET_USE_FANCY_MATH_387
21280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21281 || TARGET_MIX_SSE_I387)
21282 && flag_unsafe_math_optimizations"
21284 rtx op0 = gen_reg_rtx (XFmode);
21285 rtx op1 = gen_reg_rtx (XFmode);
21287 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21288 emit_insn (gen_acoshxf2 (op0, op1));
21289 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21293 (define_expand "atanhxf2"
21294 [(use (match_operand:XF 0 "register_operand"))
21295 (use (match_operand:XF 1 "register_operand"))]
21296 "TARGET_USE_FANCY_MATH_387
21297 && flag_unsafe_math_optimizations"
21299 ix86_emit_i387_atanh (operands[0], operands[1]);
21303 (define_expand "atanh<mode>2"
21304 [(use (match_operand:MODEF 0 "register_operand"))
21305 (use (match_operand:MODEF 1 "general_operand"))]
21306 "TARGET_USE_FANCY_MATH_387
21307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21308 || TARGET_MIX_SSE_I387)
21309 && flag_unsafe_math_optimizations"
21311 rtx op0 = gen_reg_rtx (XFmode);
21312 rtx op1 = gen_reg_rtx (XFmode);
21314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21315 emit_insn (gen_atanhxf2 (op0, op1));
21316 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21320 (define_insn "fyl2xxf3_i387"
21321 [(set (match_operand:XF 0 "register_operand" "=f")
21322 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21323 (match_operand:XF 2 "register_operand" "f")]
21325 (clobber (match_scratch:XF 3 "=2"))]
21326 "TARGET_USE_FANCY_MATH_387
21327 && flag_unsafe_math_optimizations"
21329 [(set_attr "type" "fpspc")
21330 (set_attr "znver1_decode" "vector")
21331 (set_attr "mode" "XF")])
21333 (define_expand "logxf2"
21334 [(parallel [(set (match_operand:XF 0 "register_operand")
21335 (unspec:XF [(match_operand:XF 1 "register_operand")
21336 (match_dup 2)] UNSPEC_FYL2X))
21337 (clobber (scratch:XF))])]
21338 "TARGET_USE_FANCY_MATH_387
21339 && flag_unsafe_math_optimizations"
21342 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21345 (define_expand "log<mode>2"
21346 [(use (match_operand:MODEF 0 "register_operand"))
21347 (use (match_operand:MODEF 1 "general_operand"))]
21348 "TARGET_USE_FANCY_MATH_387
21349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21350 || TARGET_MIX_SSE_I387)
21351 && flag_unsafe_math_optimizations"
21353 rtx op0 = gen_reg_rtx (XFmode);
21354 rtx op1 = gen_reg_rtx (XFmode);
21356 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21357 emit_insn (gen_logxf2 (op0, op1));
21358 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21362 (define_expand "log10xf2"
21363 [(parallel [(set (match_operand:XF 0 "register_operand")
21364 (unspec:XF [(match_operand:XF 1 "register_operand")
21365 (match_dup 2)] UNSPEC_FYL2X))
21366 (clobber (scratch:XF))])]
21367 "TARGET_USE_FANCY_MATH_387
21368 && flag_unsafe_math_optimizations"
21371 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21374 (define_expand "log10<mode>2"
21375 [(use (match_operand:MODEF 0 "register_operand"))
21376 (use (match_operand:MODEF 1 "general_operand"))]
21377 "TARGET_USE_FANCY_MATH_387
21378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21379 || TARGET_MIX_SSE_I387)
21380 && flag_unsafe_math_optimizations"
21382 rtx op0 = gen_reg_rtx (XFmode);
21383 rtx op1 = gen_reg_rtx (XFmode);
21385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21386 emit_insn (gen_log10xf2 (op0, op1));
21387 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21391 (define_expand "log2xf2"
21392 [(parallel [(set (match_operand:XF 0 "register_operand")
21393 (unspec:XF [(match_operand:XF 1 "register_operand")
21394 (match_dup 2)] UNSPEC_FYL2X))
21395 (clobber (scratch:XF))])]
21396 "TARGET_USE_FANCY_MATH_387
21397 && flag_unsafe_math_optimizations"
21398 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21400 (define_expand "log2<mode>2"
21401 [(use (match_operand:MODEF 0 "register_operand"))
21402 (use (match_operand:MODEF 1 "general_operand"))]
21403 "TARGET_USE_FANCY_MATH_387
21404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21405 || TARGET_MIX_SSE_I387)
21406 && flag_unsafe_math_optimizations"
21408 rtx op0 = gen_reg_rtx (XFmode);
21409 rtx op1 = gen_reg_rtx (XFmode);
21411 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21412 emit_insn (gen_log2xf2 (op0, op1));
21413 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21417 (define_insn "fyl2xp1xf3_i387"
21418 [(set (match_operand:XF 0 "register_operand" "=f")
21419 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21420 (match_operand:XF 2 "register_operand" "f")]
21422 (clobber (match_scratch:XF 3 "=2"))]
21423 "TARGET_USE_FANCY_MATH_387
21424 && flag_unsafe_math_optimizations"
21426 [(set_attr "type" "fpspc")
21427 (set_attr "znver1_decode" "vector")
21428 (set_attr "mode" "XF")])
21430 (define_expand "log1pxf2"
21431 [(use (match_operand:XF 0 "register_operand"))
21432 (use (match_operand:XF 1 "register_operand"))]
21433 "TARGET_USE_FANCY_MATH_387
21434 && flag_unsafe_math_optimizations"
21436 ix86_emit_i387_log1p (operands[0], operands[1]);
21440 (define_expand "log1p<mode>2"
21441 [(use (match_operand:MODEF 0 "register_operand"))
21442 (use (match_operand:MODEF 1 "general_operand"))]
21443 "TARGET_USE_FANCY_MATH_387
21444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21445 || TARGET_MIX_SSE_I387)
21446 && flag_unsafe_math_optimizations"
21448 rtx op0 = gen_reg_rtx (XFmode);
21449 rtx op1 = gen_reg_rtx (XFmode);
21451 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21452 emit_insn (gen_log1pxf2 (op0, op1));
21453 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21457 (define_insn "fxtractxf3_i387"
21458 [(set (match_operand:XF 0 "register_operand" "=f")
21459 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21460 UNSPEC_XTRACT_FRACT))
21461 (set (match_operand:XF 1 "register_operand" "=f")
21462 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21463 "TARGET_USE_FANCY_MATH_387
21464 && flag_unsafe_math_optimizations"
21466 [(set_attr "type" "fpspc")
21467 (set_attr "znver1_decode" "vector")
21468 (set_attr "mode" "XF")])
21470 (define_expand "logbxf2"
21471 [(parallel [(set (match_dup 2)
21472 (unspec:XF [(match_operand:XF 1 "register_operand")]
21473 UNSPEC_XTRACT_FRACT))
21474 (set (match_operand:XF 0 "register_operand")
21475 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21476 "TARGET_USE_FANCY_MATH_387
21477 && flag_unsafe_math_optimizations"
21478 "operands[2] = gen_reg_rtx (XFmode);")
21480 (define_expand "logb<mode>2"
21481 [(use (match_operand:MODEF 0 "register_operand"))
21482 (use (match_operand:MODEF 1 "general_operand"))]
21483 "TARGET_USE_FANCY_MATH_387
21484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21485 || TARGET_MIX_SSE_I387)
21486 && flag_unsafe_math_optimizations"
21488 rtx op0 = gen_reg_rtx (XFmode);
21489 rtx op1 = gen_reg_rtx (XFmode);
21491 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21492 emit_insn (gen_logbxf2 (op0, op1));
21493 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21497 (define_expand "ilogbxf2"
21498 [(use (match_operand:SI 0 "register_operand"))
21499 (use (match_operand:XF 1 "register_operand"))]
21500 "TARGET_USE_FANCY_MATH_387
21501 && flag_unsafe_math_optimizations"
21505 if (optimize_insn_for_size_p ())
21508 op0 = gen_reg_rtx (XFmode);
21509 op1 = gen_reg_rtx (XFmode);
21511 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21512 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21516 (define_expand "ilogb<mode>2"
21517 [(use (match_operand:SI 0 "register_operand"))
21518 (use (match_operand:MODEF 1 "general_operand"))]
21519 "TARGET_USE_FANCY_MATH_387
21520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21521 || TARGET_MIX_SSE_I387)
21522 && flag_unsafe_math_optimizations"
21526 if (optimize_insn_for_size_p ())
21529 op0 = gen_reg_rtx (XFmode);
21530 op1 = gen_reg_rtx (XFmode);
21531 op2 = gen_reg_rtx (XFmode);
21533 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21534 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21535 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21539 (define_insn "*f2xm1xf2_i387"
21540 [(set (match_operand:XF 0 "register_operand" "=f")
21541 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21543 "TARGET_USE_FANCY_MATH_387
21544 && flag_unsafe_math_optimizations"
21546 [(set_attr "type" "fpspc")
21547 (set_attr "znver1_decode" "vector")
21548 (set_attr "mode" "XF")])
21550 (define_insn "fscalexf4_i387"
21551 [(set (match_operand:XF 0 "register_operand" "=f")
21552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21553 (match_operand:XF 3 "register_operand" "1")]
21554 UNSPEC_FSCALE_FRACT))
21555 (set (match_operand:XF 1 "register_operand" "=f")
21556 (unspec:XF [(match_dup 2) (match_dup 3)]
21557 UNSPEC_FSCALE_EXP))]
21558 "TARGET_USE_FANCY_MATH_387
21559 && flag_unsafe_math_optimizations"
21561 [(set_attr "type" "fpspc")
21562 (set_attr "znver1_decode" "vector")
21563 (set_attr "mode" "XF")])
21565 (define_expand "expNcorexf3"
21566 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21567 (match_operand:XF 2 "register_operand")))
21568 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21569 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21570 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21571 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21572 (parallel [(set (match_operand:XF 0 "register_operand")
21573 (unspec:XF [(match_dup 8) (match_dup 4)]
21574 UNSPEC_FSCALE_FRACT))
21576 (unspec:XF [(match_dup 8) (match_dup 4)]
21577 UNSPEC_FSCALE_EXP))])]
21578 "TARGET_USE_FANCY_MATH_387
21579 && flag_unsafe_math_optimizations"
21583 for (i = 3; i < 10; i++)
21584 operands[i] = gen_reg_rtx (XFmode);
21586 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21589 (define_expand "expxf2"
21590 [(use (match_operand:XF 0 "register_operand"))
21591 (use (match_operand:XF 1 "register_operand"))]
21592 "TARGET_USE_FANCY_MATH_387
21593 && flag_unsafe_math_optimizations"
21595 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21597 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21601 (define_expand "exp<mode>2"
21602 [(use (match_operand:MODEF 0 "register_operand"))
21603 (use (match_operand:MODEF 1 "general_operand"))]
21604 "TARGET_USE_FANCY_MATH_387
21605 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21606 || TARGET_MIX_SSE_I387)
21607 && flag_unsafe_math_optimizations"
21609 rtx op0 = gen_reg_rtx (XFmode);
21610 rtx op1 = gen_reg_rtx (XFmode);
21612 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21613 emit_insn (gen_expxf2 (op0, op1));
21614 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21618 (define_expand "exp10xf2"
21619 [(use (match_operand:XF 0 "register_operand"))
21620 (use (match_operand:XF 1 "register_operand"))]
21621 "TARGET_USE_FANCY_MATH_387
21622 && flag_unsafe_math_optimizations"
21624 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21626 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21630 (define_expand "exp10<mode>2"
21631 [(use (match_operand:MODEF 0 "register_operand"))
21632 (use (match_operand:MODEF 1 "general_operand"))]
21633 "TARGET_USE_FANCY_MATH_387
21634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21635 || TARGET_MIX_SSE_I387)
21636 && flag_unsafe_math_optimizations"
21638 rtx op0 = gen_reg_rtx (XFmode);
21639 rtx op1 = gen_reg_rtx (XFmode);
21641 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21642 emit_insn (gen_exp10xf2 (op0, op1));
21643 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21647 (define_expand "exp2xf2"
21648 [(use (match_operand:XF 0 "register_operand"))
21649 (use (match_operand:XF 1 "register_operand"))]
21650 "TARGET_USE_FANCY_MATH_387
21651 && flag_unsafe_math_optimizations"
21653 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21655 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21659 (define_expand "exp2<mode>2"
21660 [(use (match_operand:MODEF 0 "register_operand"))
21661 (use (match_operand:MODEF 1 "general_operand"))]
21662 "TARGET_USE_FANCY_MATH_387
21663 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21664 || TARGET_MIX_SSE_I387)
21665 && flag_unsafe_math_optimizations"
21667 rtx op0 = gen_reg_rtx (XFmode);
21668 rtx op1 = gen_reg_rtx (XFmode);
21670 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21671 emit_insn (gen_exp2xf2 (op0, op1));
21672 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21676 (define_expand "expm1xf2"
21677 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21679 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21680 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21681 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21682 (parallel [(set (match_dup 7)
21683 (unspec:XF [(match_dup 6) (match_dup 4)]
21684 UNSPEC_FSCALE_FRACT))
21686 (unspec:XF [(match_dup 6) (match_dup 4)]
21687 UNSPEC_FSCALE_EXP))])
21688 (parallel [(set (match_dup 10)
21689 (unspec:XF [(match_dup 9) (match_dup 8)]
21690 UNSPEC_FSCALE_FRACT))
21691 (set (match_dup 11)
21692 (unspec:XF [(match_dup 9) (match_dup 8)]
21693 UNSPEC_FSCALE_EXP))])
21694 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21695 (set (match_operand:XF 0 "register_operand")
21696 (plus:XF (match_dup 12) (match_dup 7)))]
21697 "TARGET_USE_FANCY_MATH_387
21698 && flag_unsafe_math_optimizations"
21702 for (i = 2; i < 13; i++)
21703 operands[i] = gen_reg_rtx (XFmode);
21705 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21706 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21709 (define_expand "expm1<mode>2"
21710 [(use (match_operand:MODEF 0 "register_operand"))
21711 (use (match_operand:MODEF 1 "general_operand"))]
21712 "TARGET_USE_FANCY_MATH_387
21713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21714 || TARGET_MIX_SSE_I387)
21715 && flag_unsafe_math_optimizations"
21717 rtx op0 = gen_reg_rtx (XFmode);
21718 rtx op1 = gen_reg_rtx (XFmode);
21720 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21721 emit_insn (gen_expm1xf2 (op0, op1));
21722 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21726 (define_insn "avx512f_scalef<mode>2"
21727 [(set (match_operand:MODEF 0 "register_operand" "=v")
21729 [(match_operand:MODEF 1 "register_operand" "v")
21730 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21733 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21734 [(set_attr "prefix" "evex")
21735 (set_attr "mode" "<MODE>")])
21737 (define_expand "ldexpxf3"
21738 [(match_operand:XF 0 "register_operand")
21739 (match_operand:XF 1 "register_operand")
21740 (match_operand:SI 2 "register_operand")]
21741 "TARGET_USE_FANCY_MATH_387
21742 && flag_unsafe_math_optimizations"
21744 rtx tmp1 = gen_reg_rtx (XFmode);
21745 rtx tmp2 = gen_reg_rtx (XFmode);
21747 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21748 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21749 operands[1], tmp1));
21753 (define_expand "ldexp<mode>3"
21754 [(use (match_operand:MODEF 0 "register_operand"))
21755 (use (match_operand:MODEF 1 "general_operand"))
21756 (use (match_operand:SI 2 "register_operand"))]
21757 "((TARGET_USE_FANCY_MATH_387
21758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21759 || TARGET_MIX_SSE_I387))
21760 || (TARGET_AVX512F && TARGET_SSE_MATH))
21761 && flag_unsafe_math_optimizations"
21763 /* Prefer avx512f version. */
21764 if (TARGET_AVX512F && TARGET_SSE_MATH)
21766 rtx op2 = gen_reg_rtx (<MODE>mode);
21767 operands[1] = force_reg (<MODE>mode, operands[1]);
21769 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21770 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21774 rtx op0 = gen_reg_rtx (XFmode);
21775 rtx op1 = gen_reg_rtx (XFmode);
21777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21778 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21779 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21784 (define_expand "scalbxf3"
21785 [(parallel [(set (match_operand:XF 0 " register_operand")
21786 (unspec:XF [(match_operand:XF 1 "register_operand")
21787 (match_operand:XF 2 "register_operand")]
21788 UNSPEC_FSCALE_FRACT))
21790 (unspec:XF [(match_dup 1) (match_dup 2)]
21791 UNSPEC_FSCALE_EXP))])]
21792 "TARGET_USE_FANCY_MATH_387
21793 && flag_unsafe_math_optimizations"
21794 "operands[3] = gen_reg_rtx (XFmode);")
21796 (define_expand "scalb<mode>3"
21797 [(use (match_operand:MODEF 0 "register_operand"))
21798 (use (match_operand:MODEF 1 "general_operand"))
21799 (use (match_operand:MODEF 2 "general_operand"))]
21800 "TARGET_USE_FANCY_MATH_387
21801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21802 || TARGET_MIX_SSE_I387)
21803 && flag_unsafe_math_optimizations"
21805 rtx op0 = gen_reg_rtx (XFmode);
21806 rtx op1 = gen_reg_rtx (XFmode);
21807 rtx op2 = gen_reg_rtx (XFmode);
21809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21811 emit_insn (gen_scalbxf3 (op0, op1, op2));
21812 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21816 (define_expand "significandxf2"
21817 [(parallel [(set (match_operand:XF 0 "register_operand")
21818 (unspec:XF [(match_operand:XF 1 "register_operand")]
21819 UNSPEC_XTRACT_FRACT))
21821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21822 "TARGET_USE_FANCY_MATH_387
21823 && flag_unsafe_math_optimizations"
21824 "operands[2] = gen_reg_rtx (XFmode);")
21826 (define_expand "significand<mode>2"
21827 [(use (match_operand:MODEF 0 "register_operand"))
21828 (use (match_operand:MODEF 1 "general_operand"))]
21829 "TARGET_USE_FANCY_MATH_387
21830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21831 || TARGET_MIX_SSE_I387)
21832 && flag_unsafe_math_optimizations"
21834 rtx op0 = gen_reg_rtx (XFmode);
21835 rtx op1 = gen_reg_rtx (XFmode);
21837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21838 emit_insn (gen_significandxf2 (op0, op1));
21839 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21844 (define_insn "sse4_1_round<mode>2"
21845 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21847 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21848 (match_operand:SI 2 "const_0_to_15_operand")]
21852 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21853 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21854 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21855 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21856 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21857 [(set_attr "type" "ssecvt")
21858 (set_attr "prefix_extra" "1,1,1,*,*")
21859 (set_attr "length_immediate" "1")
21860 (set_attr "gpr32" "1,1,0,1,1")
21861 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21862 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21863 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21864 (set_attr "mode" "<MODE>")
21865 (set (attr "preferred_for_speed")
21866 (cond [(match_test "TARGET_AVX")
21867 (symbol_ref "true")
21868 (eq_attr "alternative" "1,2")
21869 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21871 (symbol_ref "true")))])
21873 (define_insn "rintxf2"
21874 [(set (match_operand:XF 0 "register_operand" "=f")
21875 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21877 "TARGET_USE_FANCY_MATH_387"
21879 [(set_attr "type" "fpspc")
21880 (set_attr "znver1_decode" "vector")
21881 (set_attr "mode" "XF")])
21883 (define_expand "rinthf2"
21884 [(match_operand:HF 0 "register_operand")
21885 (match_operand:HF 1 "nonimmediate_operand")]
21886 "TARGET_AVX512FP16"
21888 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21890 GEN_INT (ROUND_MXCSR)));
21894 (define_expand "rint<mode>2"
21895 [(use (match_operand:MODEF 0 "register_operand"))
21896 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21897 "TARGET_USE_FANCY_MATH_387
21898 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21900 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21903 emit_insn (gen_sse4_1_round<mode>2
21904 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21906 ix86_expand_rint (operands[0], operands[1]);
21910 rtx op0 = gen_reg_rtx (XFmode);
21911 rtx op1 = gen_reg_rtx (XFmode);
21913 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21914 emit_insn (gen_rintxf2 (op0, op1));
21915 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21920 (define_expand "nearbyintxf2"
21921 [(set (match_operand:XF 0 "register_operand")
21922 (unspec:XF [(match_operand:XF 1 "register_operand")]
21924 "TARGET_USE_FANCY_MATH_387
21925 && !flag_trapping_math")
21927 (define_expand "nearbyinthf2"
21928 [(match_operand:HF 0 "register_operand")
21929 (match_operand:HF 1 "nonimmediate_operand")]
21930 "TARGET_AVX512FP16"
21932 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21934 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21938 (define_expand "nearbyint<mode>2"
21939 [(use (match_operand:MODEF 0 "register_operand"))
21940 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21941 "(TARGET_USE_FANCY_MATH_387
21942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21943 || TARGET_MIX_SSE_I387)
21944 && !flag_trapping_math)
21945 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21947 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21948 emit_insn (gen_sse4_1_round<mode>2
21949 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21953 rtx op0 = gen_reg_rtx (XFmode);
21954 rtx op1 = gen_reg_rtx (XFmode);
21956 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21957 emit_insn (gen_nearbyintxf2 (op0, op1));
21958 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21963 (define_expand "roundhf2"
21964 [(match_operand:HF 0 "register_operand")
21965 (match_operand:HF 1 "register_operand")]
21966 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21968 ix86_expand_round_sse4 (operands[0], operands[1]);
21972 (define_expand "round<mode>2"
21973 [(match_operand:X87MODEF 0 "register_operand")
21974 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21975 "(TARGET_USE_FANCY_MATH_387
21976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21977 || TARGET_MIX_SSE_I387)
21978 && flag_unsafe_math_optimizations
21979 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21980 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21981 && !flag_trapping_math && !flag_rounding_math)"
21983 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21984 && !flag_trapping_math && !flag_rounding_math)
21988 operands[1] = force_reg (<MODE>mode, operands[1]);
21989 ix86_expand_round_sse4 (operands[0], operands[1]);
21991 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21992 ix86_expand_round (operands[0], operands[1]);
21994 ix86_expand_rounddf_32 (operands[0], operands[1]);
21998 operands[1] = force_reg (<MODE>mode, operands[1]);
21999 ix86_emit_i387_round (operands[0], operands[1]);
22004 (define_insn "lrintxfdi2"
22005 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22006 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22008 (clobber (match_scratch:XF 2 "=&f"))]
22009 "TARGET_USE_FANCY_MATH_387"
22010 "* return output_fix_trunc (insn, operands, false);"
22011 [(set_attr "type" "fpspc")
22012 (set_attr "mode" "DI")])
22014 (define_insn "lrintxf<mode>2"
22015 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22018 "TARGET_USE_FANCY_MATH_387"
22019 "* return output_fix_trunc (insn, operands, false);"
22020 [(set_attr "type" "fpspc")
22021 (set_attr "mode" "<MODE>")])
22023 (define_expand "lroundhf<mode>2"
22024 [(set (match_operand:SWI248 0 "register_operand")
22025 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22026 UNSPEC_FIX_NOTRUNC))]
22027 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22029 ix86_expand_lround (operands[0], operands[1]);
22033 (define_expand "lrinthf<mode>2"
22034 [(set (match_operand:SWI48 0 "register_operand")
22035 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22036 UNSPEC_FIX_NOTRUNC))]
22037 "TARGET_AVX512FP16")
22039 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22040 [(set (match_operand:SWI48 0 "register_operand")
22041 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22042 UNSPEC_FIX_NOTRUNC))]
22043 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22045 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22046 [(match_operand:SWI248x 0 "nonimmediate_operand")
22047 (match_operand:X87MODEF 1 "register_operand")]
22048 "(TARGET_USE_FANCY_MATH_387
22049 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22050 || TARGET_MIX_SSE_I387)
22051 && flag_unsafe_math_optimizations)
22052 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22053 && <SWI248x:MODE>mode != HImode
22054 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22055 && !flag_trapping_math && !flag_rounding_math)"
22057 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22058 && <SWI248x:MODE>mode != HImode
22059 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22060 && !flag_trapping_math && !flag_rounding_math)
22061 ix86_expand_lround (operands[0], operands[1]);
22063 ix86_emit_i387_round (operands[0], operands[1]);
22067 (define_int_iterator FRNDINT_ROUNDING
22068 [UNSPEC_FRNDINT_ROUNDEVEN
22069 UNSPEC_FRNDINT_FLOOR
22070 UNSPEC_FRNDINT_CEIL
22071 UNSPEC_FRNDINT_TRUNC])
22073 (define_int_iterator FIST_ROUNDING
22077 ;; Base name for define_insn
22078 (define_int_attr rounding_insn
22079 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22080 (UNSPEC_FRNDINT_FLOOR "floor")
22081 (UNSPEC_FRNDINT_CEIL "ceil")
22082 (UNSPEC_FRNDINT_TRUNC "btrunc")
22083 (UNSPEC_FIST_FLOOR "floor")
22084 (UNSPEC_FIST_CEIL "ceil")])
22086 (define_int_attr rounding
22087 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22088 (UNSPEC_FRNDINT_FLOOR "floor")
22089 (UNSPEC_FRNDINT_CEIL "ceil")
22090 (UNSPEC_FRNDINT_TRUNC "trunc")
22091 (UNSPEC_FIST_FLOOR "floor")
22092 (UNSPEC_FIST_CEIL "ceil")])
22094 (define_int_attr ROUNDING
22095 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22096 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22097 (UNSPEC_FRNDINT_CEIL "CEIL")
22098 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22099 (UNSPEC_FIST_FLOOR "FLOOR")
22100 (UNSPEC_FIST_CEIL "CEIL")])
22102 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22103 (define_insn_and_split "frndintxf2_<rounding>"
22104 [(set (match_operand:XF 0 "register_operand")
22105 (unspec:XF [(match_operand:XF 1 "register_operand")]
22107 (clobber (reg:CC FLAGS_REG))]
22108 "TARGET_USE_FANCY_MATH_387
22109 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22110 && ix86_pre_reload_split ()"
22115 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22117 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22118 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22120 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22121 operands[2], operands[3]));
22124 [(set_attr "type" "frndint")
22125 (set_attr "i387_cw" "<rounding>")
22126 (set_attr "mode" "XF")])
22128 (define_insn "frndintxf2_<rounding>_i387"
22129 [(set (match_operand:XF 0 "register_operand" "=f")
22130 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22132 (use (match_operand:HI 2 "memory_operand" "m"))
22133 (use (match_operand:HI 3 "memory_operand" "m"))]
22134 "TARGET_USE_FANCY_MATH_387
22135 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22136 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22137 [(set_attr "type" "frndint")
22138 (set_attr "i387_cw" "<rounding>")
22139 (set_attr "mode" "XF")])
22141 (define_expand "<rounding_insn>xf2"
22142 [(parallel [(set (match_operand:XF 0 "register_operand")
22143 (unspec:XF [(match_operand:XF 1 "register_operand")]
22145 (clobber (reg:CC FLAGS_REG))])]
22146 "TARGET_USE_FANCY_MATH_387
22147 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22149 (define_expand "<rounding_insn>hf2"
22150 [(parallel [(set (match_operand:HF 0 "register_operand")
22151 (unspec:HF [(match_operand:HF 1 "register_operand")]
22153 (clobber (reg:CC FLAGS_REG))])]
22154 "TARGET_AVX512FP16"
22156 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22157 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22161 (define_expand "<rounding_insn><mode>2"
22162 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22163 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22165 (clobber (reg:CC FLAGS_REG))])]
22166 "(TARGET_USE_FANCY_MATH_387
22167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22168 || TARGET_MIX_SSE_I387)
22169 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22170 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22172 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22173 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22175 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22177 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22178 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22181 emit_insn (gen_sse4_1_round<mode>2
22182 (operands[0], operands[1],
22183 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22184 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22186 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22187 ix86_expand_floorceil (operands[0], operands[1], true);
22188 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22189 ix86_expand_floorceil (operands[0], operands[1], false);
22190 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22191 ix86_expand_trunc (operands[0], operands[1]);
22193 gcc_unreachable ();
22197 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22198 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22199 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22200 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22201 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22202 ix86_expand_truncdf_32 (operands[0], operands[1]);
22204 gcc_unreachable ();
22209 rtx op0 = gen_reg_rtx (XFmode);
22210 rtx op1 = gen_reg_rtx (XFmode);
22212 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22213 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22214 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22219 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22220 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22221 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22222 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22224 (clobber (reg:CC FLAGS_REG))]
22225 "TARGET_USE_FANCY_MATH_387
22226 && flag_unsafe_math_optimizations
22227 && ix86_pre_reload_split ()"
22232 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22234 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22235 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22237 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22238 operands[2], operands[3]));
22241 [(set_attr "type" "fistp")
22242 (set_attr "i387_cw" "<rounding>")
22243 (set_attr "mode" "<MODE>")])
22245 (define_insn "fistdi2_<rounding>"
22246 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22247 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22249 (use (match_operand:HI 2 "memory_operand" "m"))
22250 (use (match_operand:HI 3 "memory_operand" "m"))
22251 (clobber (match_scratch:XF 4 "=&f"))]
22252 "TARGET_USE_FANCY_MATH_387
22253 && flag_unsafe_math_optimizations"
22254 "* return output_fix_trunc (insn, operands, false);"
22255 [(set_attr "type" "fistp")
22256 (set_attr "i387_cw" "<rounding>")
22257 (set_attr "mode" "DI")])
22259 (define_insn "fist<mode>2_<rounding>"
22260 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22261 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22263 (use (match_operand:HI 2 "memory_operand" "m"))
22264 (use (match_operand:HI 3 "memory_operand" "m"))]
22265 "TARGET_USE_FANCY_MATH_387
22266 && flag_unsafe_math_optimizations"
22267 "* return output_fix_trunc (insn, operands, false);"
22268 [(set_attr "type" "fistp")
22269 (set_attr "i387_cw" "<rounding>")
22270 (set_attr "mode" "<MODE>")])
22272 (define_expand "l<rounding_insn>xf<mode>2"
22273 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22274 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22276 (clobber (reg:CC FLAGS_REG))])]
22277 "TARGET_USE_FANCY_MATH_387
22278 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22279 && flag_unsafe_math_optimizations")
22281 (define_expand "l<rounding_insn>hf<mode>2"
22282 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22283 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22285 "TARGET_AVX512FP16"
22287 rtx tmp = gen_reg_rtx (HFmode);
22288 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22289 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22290 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22294 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22295 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22296 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22298 (clobber (reg:CC FLAGS_REG))])]
22299 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22300 && (TARGET_SSE4_1 || !flag_trapping_math)"
22304 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22306 emit_insn (gen_sse4_1_round<MODEF:mode>2
22307 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22309 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22310 (operands[0], tmp));
22312 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22313 ix86_expand_lfloorceil (operands[0], operands[1], true);
22314 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22315 ix86_expand_lfloorceil (operands[0], operands[1], false);
22317 gcc_unreachable ();
22322 (define_insn "fxam<mode>2_i387"
22323 [(set (match_operand:HI 0 "register_operand" "=a")
22325 [(match_operand:X87MODEF 1 "register_operand" "f")]
22327 "TARGET_USE_FANCY_MATH_387"
22328 "fxam\n\tfnstsw\t%0"
22329 [(set_attr "type" "multi")
22330 (set_attr "length" "4")
22331 (set_attr "unit" "i387")
22332 (set_attr "mode" "<MODE>")])
22334 (define_expand "signbittf2"
22335 [(use (match_operand:SI 0 "register_operand"))
22336 (use (match_operand:TF 1 "register_operand"))]
22341 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22342 rtx scratch = gen_reg_rtx (QImode);
22344 emit_insn (gen_ptesttf2 (operands[1], mask));
22345 ix86_expand_setcc (scratch, NE,
22346 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22348 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22352 emit_insn (gen_sse_movmskps (operands[0],
22353 gen_lowpart (V4SFmode, operands[1])));
22354 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22359 (define_expand "signbitxf2"
22360 [(use (match_operand:SI 0 "register_operand"))
22361 (use (match_operand:XF 1 "register_operand"))]
22362 "TARGET_USE_FANCY_MATH_387"
22364 rtx scratch = gen_reg_rtx (HImode);
22366 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22367 emit_insn (gen_andsi3 (operands[0],
22368 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22372 (define_insn "movmsk_df"
22373 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22375 [(match_operand:DF 1 "register_operand" "x,x")]
22377 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22378 "%vmovmskpd\t{%1, %0|%0, %1}"
22379 [(set_attr "isa" "noavx,avx")
22380 (set_attr "type" "ssemov")
22381 (set_attr "prefix" "maybe_evex")
22382 (set_attr "mode" "DF")])
22384 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22385 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22386 (define_expand "signbitdf2"
22387 [(use (match_operand:SI 0 "register_operand"))
22388 (use (match_operand:DF 1 "register_operand"))]
22389 "TARGET_USE_FANCY_MATH_387
22390 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22392 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22394 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22395 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22399 rtx scratch = gen_reg_rtx (HImode);
22401 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22402 emit_insn (gen_andsi3 (operands[0],
22403 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22408 (define_expand "signbitsf2"
22409 [(use (match_operand:SI 0 "register_operand"))
22410 (use (match_operand:SF 1 "register_operand"))]
22411 "TARGET_USE_FANCY_MATH_387
22412 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22414 rtx scratch = gen_reg_rtx (HImode);
22416 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22417 emit_insn (gen_andsi3 (operands[0],
22418 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22422 ;; Block operation instructions
22425 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22428 [(set_attr "length" "1")
22429 (set_attr "length_immediate" "0")
22430 (set_attr "modrm" "0")])
22432 (define_expand "cpymem<mode>"
22433 [(use (match_operand:BLK 0 "memory_operand"))
22434 (use (match_operand:BLK 1 "memory_operand"))
22435 (use (match_operand:SWI48 2 "nonmemory_operand"))
22436 (use (match_operand:SWI48 3 "const_int_operand"))
22437 (use (match_operand:SI 4 "const_int_operand"))
22438 (use (match_operand:SI 5 "const_int_operand"))
22439 (use (match_operand:SI 6 ""))
22440 (use (match_operand:SI 7 ""))
22441 (use (match_operand:SI 8 ""))]
22444 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22445 operands[2], NULL, operands[3],
22446 operands[4], operands[5],
22447 operands[6], operands[7],
22448 operands[8], false))
22454 ;; Most CPUs don't like single string operations
22455 ;; Handle this case here to simplify previous expander.
22457 (define_expand "strmov"
22458 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22459 (set (match_operand 1 "memory_operand") (match_dup 4))
22460 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22461 (clobber (reg:CC FLAGS_REG))])
22462 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22463 (clobber (reg:CC FLAGS_REG))])]
22466 /* Can't use this for non-default address spaces. */
22467 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22470 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22472 /* If .md ever supports :P for Pmode, these can be directly
22473 in the pattern above. */
22474 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22475 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22477 /* Can't use this if the user has appropriated esi or edi. */
22478 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22479 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22481 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22482 operands[2], operands[3],
22483 operands[5], operands[6]));
22487 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22490 (define_expand "strmov_singleop"
22491 [(parallel [(set (match_operand 1 "memory_operand")
22492 (match_operand 3 "memory_operand"))
22493 (set (match_operand 0 "register_operand")
22495 (set (match_operand 2 "register_operand")
22496 (match_operand 5))])]
22500 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22503 (define_insn "*strmovdi_rex_1"
22504 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22505 (mem:DI (match_operand:P 3 "register_operand" "1")))
22506 (set (match_operand:P 0 "register_operand" "=D")
22507 (plus:P (match_dup 2)
22509 (set (match_operand:P 1 "register_operand" "=S")
22510 (plus:P (match_dup 3)
22513 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22514 && ix86_check_no_addr_space (insn)"
22516 [(set_attr "type" "str")
22517 (set_attr "memory" "both")
22518 (set_attr "mode" "DI")])
22520 (define_insn "*strmovsi_1"
22521 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22522 (mem:SI (match_operand:P 3 "register_operand" "1")))
22523 (set (match_operand:P 0 "register_operand" "=D")
22524 (plus:P (match_dup 2)
22526 (set (match_operand:P 1 "register_operand" "=S")
22527 (plus:P (match_dup 3)
22529 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22530 && ix86_check_no_addr_space (insn)"
22532 [(set_attr "type" "str")
22533 (set_attr "memory" "both")
22534 (set_attr "mode" "SI")])
22536 (define_insn "*strmovhi_1"
22537 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22538 (mem:HI (match_operand:P 3 "register_operand" "1")))
22539 (set (match_operand:P 0 "register_operand" "=D")
22540 (plus:P (match_dup 2)
22542 (set (match_operand:P 1 "register_operand" "=S")
22543 (plus:P (match_dup 3)
22545 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22546 && ix86_check_no_addr_space (insn)"
22548 [(set_attr "type" "str")
22549 (set_attr "memory" "both")
22550 (set_attr "mode" "HI")])
22552 (define_insn "*strmovqi_1"
22553 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22554 (mem:QI (match_operand:P 3 "register_operand" "1")))
22555 (set (match_operand:P 0 "register_operand" "=D")
22556 (plus:P (match_dup 2)
22558 (set (match_operand:P 1 "register_operand" "=S")
22559 (plus:P (match_dup 3)
22561 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22562 && ix86_check_no_addr_space (insn)"
22564 [(set_attr "type" "str")
22565 (set_attr "memory" "both")
22566 (set (attr "prefix_rex")
22568 (match_test "<P:MODE>mode == DImode")
22570 (const_string "*")))
22571 (set_attr "mode" "QI")])
22573 (define_expand "rep_mov"
22574 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22575 (set (match_operand 0 "register_operand")
22577 (set (match_operand 2 "register_operand")
22579 (set (match_operand 1 "memory_operand")
22580 (match_operand 3 "memory_operand"))
22581 (use (match_dup 4))])]
22585 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22588 (define_insn "*rep_movdi_rex64"
22589 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22590 (set (match_operand:P 0 "register_operand" "=D")
22591 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22593 (match_operand:P 3 "register_operand" "0")))
22594 (set (match_operand:P 1 "register_operand" "=S")
22595 (plus:P (ashift:P (match_dup 5) (const_int 3))
22596 (match_operand:P 4 "register_operand" "1")))
22597 (set (mem:BLK (match_dup 3))
22598 (mem:BLK (match_dup 4)))
22599 (use (match_dup 5))]
22601 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22602 && ix86_check_no_addr_space (insn)"
22604 [(set_attr "type" "str")
22605 (set_attr "prefix_rep" "1")
22606 (set_attr "memory" "both")
22607 (set_attr "mode" "DI")])
22609 (define_insn "*rep_movsi"
22610 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22611 (set (match_operand:P 0 "register_operand" "=D")
22612 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22614 (match_operand:P 3 "register_operand" "0")))
22615 (set (match_operand:P 1 "register_operand" "=S")
22616 (plus:P (ashift:P (match_dup 5) (const_int 2))
22617 (match_operand:P 4 "register_operand" "1")))
22618 (set (mem:BLK (match_dup 3))
22619 (mem:BLK (match_dup 4)))
22620 (use (match_dup 5))]
22621 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22622 && ix86_check_no_addr_space (insn)"
22623 "%^rep{%;} movs{l|d}"
22624 [(set_attr "type" "str")
22625 (set_attr "prefix_rep" "1")
22626 (set_attr "memory" "both")
22627 (set_attr "mode" "SI")])
22629 (define_insn "*rep_movqi"
22630 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22631 (set (match_operand:P 0 "register_operand" "=D")
22632 (plus:P (match_operand:P 3 "register_operand" "0")
22633 (match_operand:P 5 "register_operand" "2")))
22634 (set (match_operand:P 1 "register_operand" "=S")
22635 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22636 (set (mem:BLK (match_dup 3))
22637 (mem:BLK (match_dup 4)))
22638 (use (match_dup 5))]
22639 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22640 && ix86_check_no_addr_space (insn)"
22642 [(set_attr "type" "str")
22643 (set_attr "prefix_rep" "1")
22644 (set_attr "memory" "both")
22645 (set_attr "mode" "QI")])
22647 (define_expand "setmem<mode>"
22648 [(use (match_operand:BLK 0 "memory_operand"))
22649 (use (match_operand:SWI48 1 "nonmemory_operand"))
22650 (use (match_operand:QI 2 "nonmemory_operand"))
22651 (use (match_operand 3 "const_int_operand"))
22652 (use (match_operand:SI 4 "const_int_operand"))
22653 (use (match_operand:SI 5 "const_int_operand"))
22654 (use (match_operand:SI 6 ""))
22655 (use (match_operand:SI 7 ""))
22656 (use (match_operand:SI 8 ""))]
22659 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22660 operands[1], operands[2],
22661 operands[3], operands[4],
22662 operands[5], operands[6],
22663 operands[7], operands[8], true))
22669 ;; Most CPUs don't like single string operations
22670 ;; Handle this case here to simplify previous expander.
22672 (define_expand "strset"
22673 [(set (match_operand 1 "memory_operand")
22674 (match_operand 2 "register_operand"))
22675 (parallel [(set (match_operand 0 "register_operand")
22677 (clobber (reg:CC FLAGS_REG))])]
22680 /* Can't use this for non-default address spaces. */
22681 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22684 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22685 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22687 /* If .md ever supports :P for Pmode, this can be directly
22688 in the pattern above. */
22689 operands[3] = plus_constant (Pmode, operands[0],
22690 GET_MODE_SIZE (GET_MODE (operands[2])));
22692 /* Can't use this if the user has appropriated eax or edi. */
22693 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22694 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22696 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22702 (define_expand "strset_singleop"
22703 [(parallel [(set (match_operand 1 "memory_operand")
22704 (match_operand 2 "register_operand"))
22705 (set (match_operand 0 "register_operand")
22707 (unspec [(const_int 0)] UNSPEC_STOS)])]
22711 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22714 (define_insn "*strsetdi_rex_1"
22715 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22716 (match_operand:DI 2 "register_operand" "a"))
22717 (set (match_operand:P 0 "register_operand" "=D")
22718 (plus:P (match_dup 1)
22720 (unspec [(const_int 0)] UNSPEC_STOS)]
22722 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22723 && ix86_check_no_addr_space (insn)"
22725 [(set_attr "type" "str")
22726 (set_attr "memory" "store")
22727 (set_attr "mode" "DI")])
22729 (define_insn "*strsetsi_1"
22730 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22731 (match_operand:SI 2 "register_operand" "a"))
22732 (set (match_operand:P 0 "register_operand" "=D")
22733 (plus:P (match_dup 1)
22735 (unspec [(const_int 0)] UNSPEC_STOS)]
22736 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22737 && ix86_check_no_addr_space (insn)"
22739 [(set_attr "type" "str")
22740 (set_attr "memory" "store")
22741 (set_attr "mode" "SI")])
22743 (define_insn "*strsethi_1"
22744 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22745 (match_operand:HI 2 "register_operand" "a"))
22746 (set (match_operand:P 0 "register_operand" "=D")
22747 (plus:P (match_dup 1)
22749 (unspec [(const_int 0)] UNSPEC_STOS)]
22750 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22751 && ix86_check_no_addr_space (insn)"
22753 [(set_attr "type" "str")
22754 (set_attr "memory" "store")
22755 (set_attr "mode" "HI")])
22757 (define_insn "*strsetqi_1"
22758 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22759 (match_operand:QI 2 "register_operand" "a"))
22760 (set (match_operand:P 0 "register_operand" "=D")
22761 (plus:P (match_dup 1)
22763 (unspec [(const_int 0)] UNSPEC_STOS)]
22764 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22765 && ix86_check_no_addr_space (insn)"
22767 [(set_attr "type" "str")
22768 (set_attr "memory" "store")
22769 (set (attr "prefix_rex")
22771 (match_test "<P:MODE>mode == DImode")
22773 (const_string "*")))
22774 (set_attr "mode" "QI")])
22776 (define_expand "rep_stos"
22777 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22778 (set (match_operand 0 "register_operand")
22780 (set (match_operand 2 "memory_operand") (const_int 0))
22781 (use (match_operand 3 "register_operand"))
22782 (use (match_dup 1))])]
22786 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22789 (define_insn "*rep_stosdi_rex64"
22790 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22791 (set (match_operand:P 0 "register_operand" "=D")
22792 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22794 (match_operand:P 3 "register_operand" "0")))
22795 (set (mem:BLK (match_dup 3))
22797 (use (match_operand:DI 2 "register_operand" "a"))
22798 (use (match_dup 4))]
22800 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22801 && ix86_check_no_addr_space (insn)"
22803 [(set_attr "type" "str")
22804 (set_attr "prefix_rep" "1")
22805 (set_attr "memory" "store")
22806 (set_attr "mode" "DI")])
22808 (define_insn "*rep_stossi"
22809 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22810 (set (match_operand:P 0 "register_operand" "=D")
22811 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22813 (match_operand:P 3 "register_operand" "0")))
22814 (set (mem:BLK (match_dup 3))
22816 (use (match_operand:SI 2 "register_operand" "a"))
22817 (use (match_dup 4))]
22818 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22819 && ix86_check_no_addr_space (insn)"
22820 "%^rep{%;} stos{l|d}"
22821 [(set_attr "type" "str")
22822 (set_attr "prefix_rep" "1")
22823 (set_attr "memory" "store")
22824 (set_attr "mode" "SI")])
22826 (define_insn "*rep_stosqi"
22827 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22828 (set (match_operand:P 0 "register_operand" "=D")
22829 (plus:P (match_operand:P 3 "register_operand" "0")
22830 (match_operand:P 4 "register_operand" "1")))
22831 (set (mem:BLK (match_dup 3))
22833 (use (match_operand:QI 2 "register_operand" "a"))
22834 (use (match_dup 4))]
22835 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22836 && ix86_check_no_addr_space (insn)"
22838 [(set_attr "type" "str")
22839 (set_attr "prefix_rep" "1")
22840 (set_attr "memory" "store")
22841 (set (attr "prefix_rex")
22843 (match_test "<P:MODE>mode == DImode")
22845 (const_string "*")))
22846 (set_attr "mode" "QI")])
22848 (define_expand "cmpmemsi"
22849 [(set (match_operand:SI 0 "register_operand" "")
22850 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22851 (match_operand:BLK 2 "memory_operand" "") ) )
22852 (use (match_operand 3 "general_operand"))
22853 (use (match_operand 4 "immediate_operand"))]
22856 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22857 operands[2], operands[3],
22858 operands[4], false))
22864 (define_expand "cmpstrnsi"
22865 [(set (match_operand:SI 0 "register_operand")
22866 (compare:SI (match_operand:BLK 1 "general_operand")
22867 (match_operand:BLK 2 "general_operand")))
22868 (use (match_operand 3 "general_operand"))
22869 (use (match_operand 4 "immediate_operand"))]
22872 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22873 operands[2], operands[3],
22874 operands[4], true))
22880 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22882 (define_expand "cmpintqi"
22883 [(set (match_dup 1)
22884 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22886 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22887 (parallel [(set (match_operand:QI 0 "register_operand")
22888 (minus:QI (match_dup 1)
22890 (clobber (reg:CC FLAGS_REG))])]
22893 operands[1] = gen_reg_rtx (QImode);
22894 operands[2] = gen_reg_rtx (QImode);
22897 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22898 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22900 (define_expand "cmpstrnqi_nz_1"
22901 [(parallel [(set (reg:CC FLAGS_REG)
22902 (compare:CC (match_operand 4 "memory_operand")
22903 (match_operand 5 "memory_operand")))
22904 (use (match_operand 2 "register_operand"))
22905 (use (match_operand:SI 3 "immediate_operand"))
22906 (clobber (match_operand 0 "register_operand"))
22907 (clobber (match_operand 1 "register_operand"))
22908 (clobber (match_dup 2))])]
22912 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22915 (define_insn "*cmpstrnqi_nz_1"
22916 [(set (reg:CC FLAGS_REG)
22917 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22918 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22919 (use (match_operand:P 6 "register_operand" "2"))
22920 (use (match_operand:SI 3 "immediate_operand" "i"))
22921 (clobber (match_operand:P 0 "register_operand" "=S"))
22922 (clobber (match_operand:P 1 "register_operand" "=D"))
22923 (clobber (match_operand:P 2 "register_operand" "=c"))]
22924 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22925 && ix86_check_no_addr_space (insn)"
22927 [(set_attr "type" "str")
22928 (set_attr "mode" "QI")
22929 (set (attr "prefix_rex")
22931 (match_test "<P:MODE>mode == DImode")
22933 (const_string "*")))
22934 (set_attr "prefix_rep" "1")])
22936 ;; The same, but the count is not known to not be zero.
22938 (define_expand "cmpstrnqi_1"
22939 [(parallel [(set (reg:CC FLAGS_REG)
22940 (if_then_else:CC (ne (match_operand 2 "register_operand")
22942 (compare:CC (match_operand 4 "memory_operand")
22943 (match_operand 5 "memory_operand"))
22945 (use (match_operand:SI 3 "immediate_operand"))
22946 (use (reg:CC FLAGS_REG))
22947 (clobber (match_operand 0 "register_operand"))
22948 (clobber (match_operand 1 "register_operand"))
22949 (clobber (match_dup 2))])]
22953 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22956 (define_insn "*cmpstrnqi_1"
22957 [(set (reg:CC FLAGS_REG)
22958 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22960 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22961 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22963 (use (match_operand:SI 3 "immediate_operand" "i"))
22964 (use (reg:CC FLAGS_REG))
22965 (clobber (match_operand:P 0 "register_operand" "=S"))
22966 (clobber (match_operand:P 1 "register_operand" "=D"))
22967 (clobber (match_operand:P 2 "register_operand" "=c"))]
22968 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22969 && ix86_check_no_addr_space (insn)"
22971 [(set_attr "type" "str")
22972 (set_attr "mode" "QI")
22973 (set (attr "prefix_rex")
22975 (match_test "<P:MODE>mode == DImode")
22977 (const_string "*")))
22978 (set_attr "prefix_rep" "1")])
22980 (define_expand "strlen<mode>"
22981 [(set (match_operand:P 0 "register_operand")
22982 (unspec:P [(match_operand:BLK 1 "general_operand")
22983 (match_operand:QI 2 "immediate_operand")
22984 (match_operand 3 "immediate_operand")]
22988 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22994 (define_expand "strlenqi_1"
22995 [(parallel [(set (match_operand 0 "register_operand")
22997 (clobber (match_operand 1 "register_operand"))
22998 (clobber (reg:CC FLAGS_REG))])]
23002 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23005 (define_insn "*strlenqi_1"
23006 [(set (match_operand:P 0 "register_operand" "=&c")
23007 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23008 (match_operand:QI 2 "register_operand" "a")
23009 (match_operand:P 3 "immediate_operand" "i")
23010 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23011 (clobber (match_operand:P 1 "register_operand" "=D"))
23012 (clobber (reg:CC FLAGS_REG))]
23013 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23014 && ix86_check_no_addr_space (insn)"
23015 "%^repnz{%;} scasb"
23016 [(set_attr "type" "str")
23017 (set_attr "mode" "QI")
23018 (set (attr "prefix_rex")
23020 (match_test "<P:MODE>mode == DImode")
23022 (const_string "*")))
23023 (set_attr "prefix_rep" "1")])
23025 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23026 ;; handled in combine, but it is not currently up to the task.
23027 ;; When used for their truth value, the cmpstrn* expanders generate
23036 ;; The intermediate three instructions are unnecessary.
23038 ;; This one handles cmpstrn*_nz_1...
23041 (set (reg:CC FLAGS_REG)
23042 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23043 (mem:BLK (match_operand 5 "register_operand"))))
23044 (use (match_operand 6 "register_operand"))
23045 (use (match_operand:SI 3 "immediate_operand"))
23046 (clobber (match_operand 0 "register_operand"))
23047 (clobber (match_operand 1 "register_operand"))
23048 (clobber (match_operand 2 "register_operand"))])
23049 (set (match_operand:QI 7 "register_operand")
23050 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23051 (set (match_operand:QI 8 "register_operand")
23052 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23053 (set (reg FLAGS_REG)
23054 (compare (match_dup 7) (match_dup 8)))
23056 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23058 (set (reg:CC FLAGS_REG)
23059 (compare:CC (mem:BLK (match_dup 4))
23060 (mem:BLK (match_dup 5))))
23061 (use (match_dup 6))
23062 (use (match_dup 3))
23063 (clobber (match_dup 0))
23064 (clobber (match_dup 1))
23065 (clobber (match_dup 2))])])
23067 ;; ...and this one handles cmpstrn*_1.
23070 (set (reg:CC FLAGS_REG)
23071 (if_then_else:CC (ne (match_operand 6 "register_operand")
23073 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23074 (mem:BLK (match_operand 5 "register_operand")))
23076 (use (match_operand:SI 3 "immediate_operand"))
23077 (use (reg:CC FLAGS_REG))
23078 (clobber (match_operand 0 "register_operand"))
23079 (clobber (match_operand 1 "register_operand"))
23080 (clobber (match_operand 2 "register_operand"))])
23081 (set (match_operand:QI 7 "register_operand")
23082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23083 (set (match_operand:QI 8 "register_operand")
23084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23085 (set (reg FLAGS_REG)
23086 (compare (match_dup 7) (match_dup 8)))
23088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23090 (set (reg:CC FLAGS_REG)
23091 (if_then_else:CC (ne (match_dup 6)
23093 (compare:CC (mem:BLK (match_dup 4))
23094 (mem:BLK (match_dup 5)))
23096 (use (match_dup 3))
23097 (use (reg:CC FLAGS_REG))
23098 (clobber (match_dup 0))
23099 (clobber (match_dup 1))
23100 (clobber (match_dup 2))])])
23102 ;; Conditional move instructions.
23104 (define_expand "mov<mode>cc"
23105 [(set (match_operand:SWIM 0 "register_operand")
23106 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23107 (match_operand:SWIM 2 "<general_operand>")
23108 (match_operand:SWIM 3 "<general_operand>")))]
23110 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23112 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23113 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23114 ;; So just document what we're doing explicitly.
23116 (define_expand "x86_mov<mode>cc_0_m1"
23118 [(set (match_operand:SWI48 0 "register_operand")
23119 (if_then_else:SWI48
23120 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23121 [(match_operand 1 "flags_reg_operand")
23125 (clobber (reg:CC FLAGS_REG))])])
23127 (define_insn "*x86_mov<mode>cc_0_m1"
23128 [(set (match_operand:SWI48 0 "register_operand" "=r")
23129 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23130 [(reg FLAGS_REG) (const_int 0)])
23133 (clobber (reg:CC FLAGS_REG))]
23135 "sbb{<imodesuffix>}\t%0, %0"
23136 [(set_attr "type" "alu1")
23137 (set_attr "use_carry" "1")
23138 (set_attr "pent_pair" "pu")
23139 (set_attr "mode" "<MODE>")
23140 (set_attr "length_immediate" "0")])
23142 (define_insn "*x86_mov<mode>cc_0_m1_se"
23143 [(set (match_operand:SWI48 0 "register_operand" "=r")
23144 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23145 [(reg FLAGS_REG) (const_int 0)])
23148 (clobber (reg:CC FLAGS_REG))]
23150 "sbb{<imodesuffix>}\t%0, %0"
23151 [(set_attr "type" "alu1")
23152 (set_attr "use_carry" "1")
23153 (set_attr "pent_pair" "pu")
23154 (set_attr "mode" "<MODE>")
23155 (set_attr "length_immediate" "0")])
23157 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23158 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23159 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23160 [(reg FLAGS_REG) (const_int 0)])))
23161 (clobber (reg:CC FLAGS_REG))]
23163 "sbb{<imodesuffix>}\t%0, %0"
23164 [(set_attr "type" "alu1")
23165 (set_attr "use_carry" "1")
23166 (set_attr "pent_pair" "pu")
23167 (set_attr "mode" "<MODE>")
23168 (set_attr "length_immediate" "0")])
23170 (define_expand "x86_mov<mode>cc_0_m1_neg"
23172 [(set (match_operand:SWI48 0 "register_operand")
23173 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23174 (clobber (reg:CC FLAGS_REG))])])
23177 [(set (match_operand:SWI48 0 "register_operand")
23180 (match_operand 1 "int_nonimmediate_operand")
23181 (match_operand 2 "const_int_operand"))))]
23182 "x86_64_immediate_operand (operands[2], VOIDmode)
23183 && INTVAL (operands[2]) != -1
23184 && INTVAL (operands[2]) != 2147483647"
23185 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23187 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23188 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23191 [(set (match_operand:SWI 0 "register_operand")
23194 (match_operand 1 "int_nonimmediate_operand")
23197 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23199 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23202 [(set (match_operand:SWI 0 "register_operand")
23205 (match_operand 1 "int_nonimmediate_operand")
23208 [(set (reg:CCC FLAGS_REG)
23209 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23211 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23213 (define_insn "*mov<mode>cc_noc"
23214 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23215 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23216 [(reg FLAGS_REG) (const_int 0)])
23217 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23218 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23219 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23221 cmov%O2%C1\t{%2, %0|%0, %2}
23222 cmov%O2%c1\t{%3, %0|%0, %3}"
23223 [(set_attr "type" "icmov")
23224 (set_attr "mode" "<MODE>")])
23226 (define_insn "*movsicc_noc_zext"
23227 [(set (match_operand:DI 0 "register_operand" "=r,r")
23228 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23229 [(reg FLAGS_REG) (const_int 0)])
23231 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23233 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23235 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23237 cmov%O2%C1\t{%2, %k0|%k0, %2}
23238 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23239 [(set_attr "type" "icmov")
23240 (set_attr "mode" "SI")])
23242 (define_insn "*movsicc_noc_zext_1"
23243 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23245 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23246 [(reg FLAGS_REG) (const_int 0)])
23247 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23248 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23250 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23252 cmov%O2%C1\t{%2, %k0|%k0, %2}
23253 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23254 [(set_attr "type" "icmov")
23255 (set_attr "mode" "SI")])
23258 ;; Don't do conditional moves with memory inputs. This splitter helps
23259 ;; register starved x86_32 by forcing inputs into registers before reload.
23261 [(set (match_operand:SWI248 0 "register_operand")
23262 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23263 [(reg FLAGS_REG) (const_int 0)])
23264 (match_operand:SWI248 2 "nonimmediate_operand")
23265 (match_operand:SWI248 3 "nonimmediate_operand")))]
23266 "!TARGET_64BIT && TARGET_CMOVE
23267 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23268 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23269 && can_create_pseudo_p ()
23270 && optimize_insn_for_speed_p ()"
23271 [(set (match_dup 0)
23272 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23274 operands[2] = force_reg (<MODE>mode, operands[2]);
23275 operands[3] = force_reg (<MODE>mode, operands[3]);
23278 (define_insn "*movqicc_noc"
23279 [(set (match_operand:QI 0 "register_operand" "=r,r")
23280 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23281 [(reg FLAGS_REG) (const_int 0)])
23282 (match_operand:QI 2 "register_operand" "r,0")
23283 (match_operand:QI 3 "register_operand" "0,r")))]
23284 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23286 [(set_attr "type" "icmov")
23287 (set_attr "mode" "QI")])
23290 [(set (match_operand:SWI12 0 "register_operand")
23291 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23292 [(reg FLAGS_REG) (const_int 0)])
23293 (match_operand:SWI12 2 "register_operand")
23294 (match_operand:SWI12 3 "register_operand")))]
23295 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23296 && reload_completed"
23297 [(set (match_dup 0)
23298 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23300 operands[0] = gen_lowpart (SImode, operands[0]);
23301 operands[2] = gen_lowpart (SImode, operands[2]);
23302 operands[3] = gen_lowpart (SImode, operands[3]);
23305 ;; Don't do conditional moves with memory inputs
23307 [(match_scratch:SWI248 4 "r")
23308 (set (match_operand:SWI248 0 "register_operand")
23309 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23310 [(reg FLAGS_REG) (const_int 0)])
23311 (match_operand:SWI248 2 "nonimmediate_operand")
23312 (match_operand:SWI248 3 "nonimmediate_operand")))]
23313 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23314 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23315 && optimize_insn_for_speed_p ()"
23316 [(set (match_dup 4) (match_dup 5))
23318 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23320 if (MEM_P (operands[2]))
23322 operands[5] = operands[2];
23323 operands[2] = operands[4];
23325 else if (MEM_P (operands[3]))
23327 operands[5] = operands[3];
23328 operands[3] = operands[4];
23331 gcc_unreachable ();
23335 [(match_scratch:SI 4 "r")
23336 (set (match_operand:DI 0 "register_operand")
23337 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23338 [(reg FLAGS_REG) (const_int 0)])
23340 (match_operand:SI 2 "nonimmediate_operand"))
23342 (match_operand:SI 3 "nonimmediate_operand"))))]
23344 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23345 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23346 && optimize_insn_for_speed_p ()"
23347 [(set (match_dup 4) (match_dup 5))
23349 (if_then_else:DI (match_dup 1)
23350 (zero_extend:DI (match_dup 2))
23351 (zero_extend:DI (match_dup 3))))]
23353 if (MEM_P (operands[2]))
23355 operands[5] = operands[2];
23356 operands[2] = operands[4];
23358 else if (MEM_P (operands[3]))
23360 operands[5] = operands[3];
23361 operands[3] = operands[4];
23364 gcc_unreachable ();
23367 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23368 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23370 [(set (match_operand:SWI248 0 "general_reg_operand")
23371 (match_operand:SWI248 1 "general_reg_operand"))
23372 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23373 (set (match_dup 0) (match_operand:SWI248 6))])
23374 (set (match_operand:SWI248 2 "general_reg_operand")
23375 (match_operand:SWI248 3 "general_gr_operand"))
23377 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23378 [(reg FLAGS_REG) (const_int 0)])
23382 && REGNO (operands[2]) != REGNO (operands[0])
23383 && REGNO (operands[2]) != REGNO (operands[1])
23384 && peep2_reg_dead_p (1, operands[1])
23385 && peep2_reg_dead_p (4, operands[2])
23386 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23387 [(parallel [(set (match_dup 7) (match_dup 8))
23388 (set (match_dup 1) (match_dup 9))])
23389 (set (match_dup 0) (match_dup 3))
23390 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23394 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23396 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23398 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23401 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23402 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23404 [(set (match_operand:SWI248 2 "general_reg_operand")
23405 (match_operand:SWI248 3 "general_gr_operand"))
23406 (set (match_operand:SWI248 0 "general_reg_operand")
23407 (match_operand:SWI248 1 "general_reg_operand"))
23408 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23409 (set (match_dup 0) (match_operand:SWI248 6))])
23411 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23412 [(reg FLAGS_REG) (const_int 0)])
23416 && REGNO (operands[2]) != REGNO (operands[0])
23417 && REGNO (operands[2]) != REGNO (operands[1])
23418 && peep2_reg_dead_p (2, operands[1])
23419 && peep2_reg_dead_p (4, operands[2])
23420 && !reg_overlap_mentioned_p (operands[0], operands[3])
23421 && !reg_mentioned_p (operands[2], operands[6])"
23422 [(parallel [(set (match_dup 7) (match_dup 8))
23423 (set (match_dup 1) (match_dup 9))])
23424 (set (match_dup 0) (match_dup 3))
23425 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23429 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23431 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23433 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23436 (define_insn "movhf_mask"
23437 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23439 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23440 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23441 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23442 UNSPEC_MOVCC_MASK))]
23443 "TARGET_AVX512FP16"
23445 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23446 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23447 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23448 [(set_attr "type" "ssemov")
23449 (set_attr "prefix" "evex")
23450 (set_attr "mode" "HF")])
23452 (define_expand "movhfcc"
23453 [(set (match_operand:HF 0 "register_operand")
23455 (match_operand 1 "comparison_operator")
23456 (match_operand:HF 2 "register_operand")
23457 (match_operand:HF 3 "register_operand")))]
23458 "TARGET_AVX512FP16"
23459 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23461 (define_expand "mov<mode>cc"
23462 [(set (match_operand:X87MODEF 0 "register_operand")
23463 (if_then_else:X87MODEF
23464 (match_operand 1 "comparison_operator")
23465 (match_operand:X87MODEF 2 "register_operand")
23466 (match_operand:X87MODEF 3 "register_operand")))]
23467 "(TARGET_80387 && TARGET_CMOVE)
23468 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23469 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23471 (define_insn "*movxfcc_1"
23472 [(set (match_operand:XF 0 "register_operand" "=f,f")
23473 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23474 [(reg FLAGS_REG) (const_int 0)])
23475 (match_operand:XF 2 "register_operand" "f,0")
23476 (match_operand:XF 3 "register_operand" "0,f")))]
23477 "TARGET_80387 && TARGET_CMOVE"
23479 fcmov%F1\t{%2, %0|%0, %2}
23480 fcmov%f1\t{%3, %0|%0, %3}"
23481 [(set_attr "type" "fcmov")
23482 (set_attr "mode" "XF")])
23484 (define_insn "*movdfcc_1"
23485 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23486 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23487 [(reg FLAGS_REG) (const_int 0)])
23488 (match_operand:DF 2 "nonimmediate_operand"
23490 (match_operand:DF 3 "nonimmediate_operand"
23491 "0 ,f,0 ,rm,0, rm")))]
23492 "TARGET_80387 && TARGET_CMOVE
23493 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23495 fcmov%F1\t{%2, %0|%0, %2}
23496 fcmov%f1\t{%3, %0|%0, %3}
23499 cmov%O2%C1\t{%2, %0|%0, %2}
23500 cmov%O2%c1\t{%3, %0|%0, %3}"
23501 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23502 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23503 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23506 [(set (match_operand:DF 0 "general_reg_operand")
23507 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23508 [(reg FLAGS_REG) (const_int 0)])
23509 (match_operand:DF 2 "nonimmediate_operand")
23510 (match_operand:DF 3 "nonimmediate_operand")))]
23511 "!TARGET_64BIT && reload_completed"
23512 [(set (match_dup 2)
23513 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23515 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23517 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23518 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23521 (define_insn "*movsfcc_1_387"
23522 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23523 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23524 [(reg FLAGS_REG) (const_int 0)])
23525 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23526 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23527 "TARGET_80387 && TARGET_CMOVE
23528 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23530 fcmov%F1\t{%2, %0|%0, %2}
23531 fcmov%f1\t{%3, %0|%0, %3}
23532 cmov%O2%C1\t{%2, %0|%0, %2}
23533 cmov%O2%c1\t{%3, %0|%0, %3}"
23534 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23535 (set_attr "mode" "SF,SF,SI,SI")])
23537 ;; Don't do conditional moves with memory inputs. This splitter helps
23538 ;; register starved x86_32 by forcing inputs into registers before reload.
23540 [(set (match_operand:MODEF 0 "register_operand")
23541 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23542 [(reg FLAGS_REG) (const_int 0)])
23543 (match_operand:MODEF 2 "nonimmediate_operand")
23544 (match_operand:MODEF 3 "nonimmediate_operand")))]
23545 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23546 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23547 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23548 && can_create_pseudo_p ()
23549 && optimize_insn_for_speed_p ()"
23550 [(set (match_dup 0)
23551 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23553 operands[2] = force_reg (<MODE>mode, operands[2]);
23554 operands[3] = force_reg (<MODE>mode, operands[3]);
23557 ;; Don't do conditional moves with memory inputs
23559 [(match_scratch:MODEF 4 "r")
23560 (set (match_operand:MODEF 0 "general_reg_operand")
23561 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23562 [(reg FLAGS_REG) (const_int 0)])
23563 (match_operand:MODEF 2 "nonimmediate_operand")
23564 (match_operand:MODEF 3 "nonimmediate_operand")))]
23565 "(<MODE>mode != DFmode || TARGET_64BIT)
23566 && TARGET_80387 && TARGET_CMOVE
23567 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23568 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23569 && optimize_insn_for_speed_p ()"
23570 [(set (match_dup 4) (match_dup 5))
23572 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23574 if (MEM_P (operands[2]))
23576 operands[5] = operands[2];
23577 operands[2] = operands[4];
23579 else if (MEM_P (operands[3]))
23581 operands[5] = operands[3];
23582 operands[3] = operands[4];
23585 gcc_unreachable ();
23588 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23589 ;; the scalar versions to have only XMM registers as operands.
23591 ;; XOP conditional move
23592 (define_insn "*xop_pcmov_<mode>"
23593 [(set (match_operand:MODEF 0 "register_operand" "=x")
23594 (if_then_else:MODEF
23595 (match_operand:MODEF 1 "register_operand" "x")
23596 (match_operand:MODEF 2 "register_operand" "x")
23597 (match_operand:MODEF 3 "register_operand" "x")))]
23599 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23600 [(set_attr "type" "sse4arg")
23601 (set_attr "mode" "TI")])
23603 ;; These versions of the min/max patterns are intentionally ignorant of
23604 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23605 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23606 ;; are undefined in this condition, we're certain this is correct.
23608 (define_insn "<code><mode>3"
23609 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23611 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23612 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23613 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23615 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23616 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23617 [(set_attr "isa" "noavx,avx")
23618 (set_attr "prefix" "orig,vex")
23619 (set_attr "type" "sseadd")
23620 (set_attr "mode" "<MODE>")])
23622 (define_insn "<code>hf3"
23623 [(set (match_operand:HF 0 "register_operand" "=v")
23625 (match_operand:HF 1 "nonimmediate_operand" "%v")
23626 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23627 "TARGET_AVX512FP16"
23628 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23629 [(set_attr "prefix" "evex")
23630 (set_attr "type" "sseadd")
23631 (set_attr "mode" "HF")])
23633 ;; These versions of the min/max patterns implement exactly the operations
23634 ;; min = (op1 < op2 ? op1 : op2)
23635 ;; max = (!(op1 < op2) ? op1 : op2)
23636 ;; Their operands are not commutative, and thus they may be used in the
23637 ;; presence of -0.0 and NaN.
23639 (define_insn "*ieee_s<ieee_maxmin>hf3"
23640 [(set (match_operand:HF 0 "register_operand" "=v")
23642 [(match_operand:HF 1 "register_operand" "v")
23643 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23645 "TARGET_AVX512FP16"
23646 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23647 [(set_attr "prefix" "evex")
23648 (set_attr "type" "sseadd")
23649 (set_attr "mode" "HF")])
23651 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23652 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23654 [(match_operand:MODEF 1 "register_operand" "0,v")
23655 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23657 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23659 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23660 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23661 [(set_attr "isa" "noavx,avx")
23662 (set_attr "prefix" "orig,maybe_evex")
23663 (set_attr "type" "sseadd")
23664 (set_attr "mode" "<MODE>")])
23666 ;; Operands order in min/max instruction matters for signed zero and NANs.
23667 (define_insn_and_split "*ieee_max<mode>3_1"
23668 [(set (match_operand:MODEF 0 "register_operand")
23670 [(match_operand:MODEF 1 "register_operand")
23671 (match_operand:MODEF 2 "register_operand")
23673 (match_operand:MODEF 3 "register_operand")
23674 (match_operand:MODEF 4 "register_operand"))]
23676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23677 && (rtx_equal_p (operands[1], operands[3])
23678 && rtx_equal_p (operands[2], operands[4]))
23679 && ix86_pre_reload_split ()"
23682 [(set (match_dup 0)
23686 UNSPEC_IEEE_MAX))])
23688 (define_insn_and_split "*ieee_min<mode>3_1"
23689 [(set (match_operand:MODEF 0 "register_operand")
23691 [(match_operand:MODEF 1 "register_operand")
23692 (match_operand:MODEF 2 "register_operand")
23694 (match_operand:MODEF 3 "register_operand")
23695 (match_operand:MODEF 4 "register_operand"))]
23697 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23698 && (rtx_equal_p (operands[1], operands[4])
23699 && rtx_equal_p (operands[2], operands[3]))
23700 && ix86_pre_reload_split ()"
23703 [(set (match_dup 0)
23707 UNSPEC_IEEE_MIN))])
23709 ;; Make two stack loads independent:
23711 ;; fld %st(0) -> fld bb
23712 ;; fmul bb fmul %st(1), %st
23714 ;; Actually we only match the last two instructions for simplicity.
23717 [(set (match_operand 0 "fp_register_operand")
23718 (match_operand 1 "fp_register_operand"))
23720 (match_operator 2 "binary_fp_operator"
23722 (match_operand 3 "memory_operand")]))]
23723 "REGNO (operands[0]) != REGNO (operands[1])"
23724 [(set (match_dup 0) (match_dup 3))
23727 [(match_dup 5) (match_dup 4)]))]
23729 operands[4] = operands[0];
23730 operands[5] = operands[1];
23732 /* The % modifier is not operational anymore in peephole2's, so we have to
23733 swap the operands manually in the case of addition and multiplication. */
23734 if (COMMUTATIVE_ARITH_P (operands[2]))
23735 std::swap (operands[4], operands[5]);
23739 [(set (match_operand 0 "fp_register_operand")
23740 (match_operand 1 "fp_register_operand"))
23742 (match_operator 2 "binary_fp_operator"
23743 [(match_operand 3 "memory_operand")
23745 "REGNO (operands[0]) != REGNO (operands[1])"
23746 [(set (match_dup 0) (match_dup 3))
23749 [(match_dup 4) (match_dup 5)]))]
23751 operands[4] = operands[0];
23752 operands[5] = operands[1];
23754 /* The % modifier is not operational anymore in peephole2's, so we have to
23755 swap the operands manually in the case of addition and multiplication. */
23756 if (COMMUTATIVE_ARITH_P (operands[2]))
23757 std::swap (operands[4], operands[5]);
23760 ;; Conditional addition patterns
23761 (define_expand "add<mode>cc"
23762 [(match_operand:SWI 0 "register_operand")
23763 (match_operand 1 "ordered_comparison_operator")
23764 (match_operand:SWI 2 "register_operand")
23765 (match_operand:SWI 3 "const_int_operand")]
23767 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23769 ;; min/max patterns
23771 (define_code_attr maxmin_rel
23772 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23774 (define_expand "<code><mode>3"
23776 [(set (match_operand:SDWIM 0 "register_operand")
23778 (match_operand:SDWIM 1 "register_operand")
23779 (match_operand:SDWIM 2 "general_operand")))
23780 (clobber (reg:CC FLAGS_REG))])]
23782 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23784 (define_insn_and_split "*<code><dwi>3_doubleword"
23785 [(set (match_operand:<DWI> 0 "register_operand")
23787 (match_operand:<DWI> 1 "register_operand")
23788 (match_operand:<DWI> 2 "general_operand")))
23789 (clobber (reg:CC FLAGS_REG))]
23791 && ix86_pre_reload_split ()"
23794 [(set (match_dup 0)
23795 (if_then_else:DWIH (match_dup 6)
23799 (if_then_else:DWIH (match_dup 6)
23803 operands[2] = force_reg (<DWI>mode, operands[2]);
23805 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23807 rtx cmplo[2] = { operands[1], operands[2] };
23808 rtx cmphi[2] = { operands[4], operands[5] };
23810 enum rtx_code code = <maxmin_rel>;
23815 std::swap (cmplo[0], cmplo[1]);
23816 std::swap (cmphi[0], cmphi[1]);
23817 code = swap_condition (code);
23822 bool uns = (code == GEU);
23823 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23824 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23826 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23828 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23829 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23831 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23832 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23838 gcc_unreachable ();
23842 (define_insn_and_split "*<code><mode>3_1"
23843 [(set (match_operand:SWI 0 "register_operand")
23845 (match_operand:SWI 1 "register_operand")
23846 (match_operand:SWI 2 "general_operand")))
23847 (clobber (reg:CC FLAGS_REG))]
23849 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23850 && ix86_pre_reload_split ()"
23853 [(set (match_dup 0)
23854 (if_then_else:SWI (match_dup 3)
23858 machine_mode mode = <MODE>mode;
23859 rtx cmp_op = operands[2];
23861 operands[2] = force_reg (mode, cmp_op);
23863 enum rtx_code code = <maxmin_rel>;
23865 if (cmp_op == const1_rtx)
23867 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23868 Convert umax (x, 1) into (x != 0 ? x : 1).
23869 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23870 cmp_op = const0_rtx;
23873 else if (code == GEU)
23876 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23877 else if (cmp_op == constm1_rtx && code == LE)
23879 cmp_op = const0_rtx;
23882 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23883 else if (cmp_op == constm1_rtx && code == GE)
23884 cmp_op = const0_rtx;
23885 else if (cmp_op != const0_rtx)
23886 cmp_op = operands[2];
23888 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23889 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23891 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23892 emit_insn (gen_rtx_SET (flags, tmp));
23894 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23897 ;; Avoid clearing a register between a flags setting comparison and its use,
23898 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23900 [(set (reg FLAGS_REG) (match_operand 0))
23901 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23902 "peep2_regno_dead_p (0, FLAGS_REG)
23903 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23904 [(set (match_dup 2) (match_dup 0))]
23906 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23907 ix86_expand_clear (operands[1]);
23910 ;; When optimizing for size, zeroing memory should use a register.
23912 [(match_scratch:SWI48 0 "r")
23913 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23914 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23915 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23916 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23917 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23920 ix86_expand_clear (operands[0]);
23921 emit_move_insn (operands[1], operands[0]);
23922 emit_move_insn (operands[2], operands[0]);
23923 emit_move_insn (operands[3], operands[0]);
23924 ix86_last_zero_store_uid
23925 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23930 [(match_scratch:SWI48 0 "r")
23931 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23932 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23933 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23936 ix86_expand_clear (operands[0]);
23937 emit_move_insn (operands[1], operands[0]);
23938 ix86_last_zero_store_uid
23939 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23944 [(match_scratch:SWI48 0 "r")
23945 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23946 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23949 ix86_expand_clear (operands[0]);
23950 ix86_last_zero_store_uid
23951 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23956 [(set (match_operand:SWI48 5 "memory_operand")
23957 (match_operand:SWI48 0 "general_reg_operand"))
23958 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23959 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23960 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23961 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23962 "optimize_insn_for_size_p ()
23963 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23966 emit_move_insn (operands[5], operands[0]);
23967 emit_move_insn (operands[1], operands[0]);
23968 emit_move_insn (operands[2], operands[0]);
23969 emit_move_insn (operands[3], operands[0]);
23970 ix86_last_zero_store_uid
23971 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23976 [(set (match_operand:SWI48 3 "memory_operand")
23977 (match_operand:SWI48 0 "general_reg_operand"))
23978 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23979 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23980 "optimize_insn_for_size_p ()
23981 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23984 emit_move_insn (operands[3], operands[0]);
23985 emit_move_insn (operands[1], operands[0]);
23986 ix86_last_zero_store_uid
23987 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23992 [(set (match_operand:SWI48 2 "memory_operand")
23993 (match_operand:SWI48 0 "general_reg_operand"))
23994 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23995 "optimize_insn_for_size_p ()
23996 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23999 emit_move_insn (operands[2], operands[0]);
24000 ix86_last_zero_store_uid
24001 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24005 ;; Reload dislikes loading constants directly into class_likely_spilled
24006 ;; hard registers. Try to tidy things up here.
24008 [(set (match_operand:SWI 0 "general_reg_operand")
24009 (match_operand:SWI 1 "x86_64_general_operand"))
24010 (set (match_operand:SWI 2 "general_reg_operand")
24012 "peep2_reg_dead_p (2, operands[0])"
24013 [(set (match_dup 2) (match_dup 1))])
24015 ;; Misc patterns (?)
24017 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24018 ;; Otherwise there will be nothing to keep
24020 ;; [(set (reg ebp) (reg esp))]
24021 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24022 ;; (clobber (eflags)]
24023 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24025 ;; in proper program order.
24027 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24028 [(set (match_operand:P 0 "register_operand" "=r,r")
24029 (plus:P (match_operand:P 1 "register_operand" "0,r")
24030 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24031 (clobber (reg:CC FLAGS_REG))
24032 (clobber (mem:BLK (scratch)))]
24035 switch (get_attr_type (insn))
24038 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24042 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24045 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24049 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24052 [(set (attr "type")
24053 (cond [(and (eq_attr "alternative" "0")
24054 (not (match_test "TARGET_OPT_AGU")))
24055 (const_string "alu")
24056 (match_operand:<MODE> 2 "const0_operand")
24057 (const_string "imov")
24059 (const_string "lea")))
24060 (set (attr "length_immediate")
24061 (cond [(eq_attr "type" "imov")
24063 (and (eq_attr "type" "alu")
24064 (match_operand 2 "const128_operand"))
24067 (const_string "*")))
24068 (set_attr "mode" "<MODE>")])
24070 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24071 [(set (match_operand:P 0 "register_operand" "=r")
24072 (minus:P (match_operand:P 1 "register_operand" "0")
24073 (match_operand:P 2 "register_operand" "r")))
24074 (clobber (reg:CC FLAGS_REG))
24075 (clobber (mem:BLK (scratch)))]
24077 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24078 [(set_attr "type" "alu")
24079 (set_attr "mode" "<MODE>")])
24081 (define_insn "@allocate_stack_worker_probe_<mode>"
24082 [(set (match_operand:P 0 "register_operand" "=a")
24083 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24084 UNSPECV_STACK_PROBE))
24085 (clobber (reg:CC FLAGS_REG))]
24086 "ix86_target_stack_probe ()"
24087 "call\t___chkstk_ms"
24088 [(set_attr "type" "multi")
24089 (set_attr "length" "5")])
24091 (define_expand "allocate_stack"
24092 [(match_operand 0 "register_operand")
24093 (match_operand 1 "general_operand")]
24094 "ix86_target_stack_probe ()"
24098 #ifndef CHECK_STACK_LIMIT
24099 #define CHECK_STACK_LIMIT 0
24102 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24103 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24107 x = copy_to_mode_reg (Pmode, operands[1]);
24109 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24112 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24113 stack_pointer_rtx, 0, OPTAB_DIRECT);
24115 if (x != stack_pointer_rtx)
24116 emit_move_insn (stack_pointer_rtx, x);
24118 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24122 (define_expand "probe_stack"
24123 [(match_operand 0 "memory_operand")]
24126 emit_insn (gen_probe_stack_1
24127 (word_mode, operands[0], const0_rtx));
24131 ;; Use OR for stack probes, this is shorter.
24132 (define_insn "@probe_stack_1_<mode>"
24133 [(set (match_operand:W 0 "memory_operand" "=m")
24134 (unspec:W [(match_operand:W 1 "const0_operand")]
24135 UNSPEC_PROBE_STACK))
24136 (clobber (reg:CC FLAGS_REG))]
24138 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24139 [(set_attr "type" "alu1")
24140 (set_attr "mode" "<MODE>")
24141 (set_attr "length_immediate" "1")])
24143 (define_insn "@adjust_stack_and_probe_<mode>"
24144 [(set (match_operand:P 0 "register_operand" "=r")
24145 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24146 UNSPECV_PROBE_STACK_RANGE))
24147 (set (reg:P SP_REG)
24148 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24149 (clobber (reg:CC FLAGS_REG))
24150 (clobber (mem:BLK (scratch)))]
24152 "* return output_adjust_stack_and_probe (operands[0]);"
24153 [(set_attr "type" "multi")])
24155 (define_insn "@probe_stack_range_<mode>"
24156 [(set (match_operand:P 0 "register_operand" "=r")
24157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24158 (match_operand:P 2 "const_int_operand")]
24159 UNSPECV_PROBE_STACK_RANGE))
24160 (clobber (reg:CC FLAGS_REG))]
24162 "* return output_probe_stack_range (operands[0], operands[2]);"
24163 [(set_attr "type" "multi")])
24165 (define_expand "builtin_setjmp_receiver"
24166 [(label_ref (match_operand 0))]
24167 "!TARGET_64BIT && flag_pic"
24173 rtx_code_label *label_rtx = gen_label_rtx ();
24174 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24175 xops[0] = xops[1] = pic_offset_table_rtx;
24176 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24177 ix86_expand_binary_operator (MINUS, SImode, xops);
24181 emit_insn (gen_set_got (pic_offset_table_rtx));
24185 (define_expand "save_stack_nonlocal"
24186 [(set (match_operand 0 "memory_operand")
24187 (match_operand 1 "register_operand"))]
24192 if (flag_cf_protection & CF_RETURN)
24194 /* Copy shadow stack pointer to the first slot
24195 and stack pointer to the second slot. */
24196 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24197 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24199 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24200 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24201 emit_move_insn (ssp_slot, reg_ssp);
24204 stack_slot = adjust_address (operands[0], Pmode, 0);
24205 emit_move_insn (stack_slot, operands[1]);
24209 (define_expand "restore_stack_nonlocal"
24210 [(set (match_operand 0 "register_operand" "")
24211 (match_operand 1 "memory_operand" ""))]
24216 if (flag_cf_protection & CF_RETURN)
24218 /* Restore shadow stack pointer from the first slot
24219 and stack pointer from the second slot. */
24220 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24221 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24223 /* Get the current shadow stack pointer. The code below will check if
24224 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24226 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24227 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24229 /* Compare through subtraction the saved and the current ssp
24230 to decide if ssp has to be adjusted. */
24231 reg_ssp = expand_simple_binop (word_mode, MINUS,
24233 reg_ssp, 1, OPTAB_DIRECT);
24235 /* Compare and jump over adjustment code. */
24236 rtx noadj_label = gen_label_rtx ();
24237 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24238 word_mode, 1, noadj_label);
24240 /* Compute the number of frames to adjust. */
24241 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24242 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24245 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24246 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24247 reg_adj, 1, OPTAB_DIRECT);
24249 /* Check if number of frames <= 255 so no loop is needed. */
24250 rtx inc_label = gen_label_rtx ();
24251 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24252 ptr_mode, 1, inc_label);
24254 /* Adjust the ssp in a loop. */
24255 rtx loop_label = gen_label_rtx ();
24256 emit_label (loop_label);
24257 LABEL_NUSES (loop_label) = 1;
24259 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24260 emit_insn (gen_incssp (word_mode, reg_255));
24262 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24263 reg_adj, GEN_INT (255),
24264 reg_adj, 1, OPTAB_DIRECT);
24266 /* Compare and jump to the loop label. */
24267 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24268 ptr_mode, 1, loop_label);
24270 emit_label (inc_label);
24271 LABEL_NUSES (inc_label) = 1;
24273 emit_insn (gen_incssp (word_mode, reg_ssp));
24275 emit_label (noadj_label);
24276 LABEL_NUSES (noadj_label) = 1;
24279 stack_slot = adjust_address (operands[1], Pmode, 0);
24280 emit_move_insn (operands[0], stack_slot);
24285 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24286 ;; Do not split instructions with mask registers.
24288 [(set (match_operand 0 "general_reg_operand")
24289 (match_operator 3 "promotable_binary_operator"
24290 [(match_operand 1 "general_reg_operand")
24291 (match_operand 2 "aligned_operand")]))
24292 (clobber (reg:CC FLAGS_REG))]
24293 "! TARGET_PARTIAL_REG_STALL && reload_completed
24294 && ((GET_MODE (operands[0]) == HImode
24295 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24296 /* ??? next two lines just !satisfies_constraint_K (...) */
24297 || !CONST_INT_P (operands[2])
24298 || satisfies_constraint_K (operands[2])))
24299 || (GET_MODE (operands[0]) == QImode
24300 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24301 [(parallel [(set (match_dup 0)
24302 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24303 (clobber (reg:CC FLAGS_REG))])]
24305 operands[0] = gen_lowpart (SImode, operands[0]);
24306 operands[1] = gen_lowpart (SImode, operands[1]);
24307 if (GET_CODE (operands[3]) != ASHIFT)
24308 operands[2] = gen_lowpart (SImode, operands[2]);
24309 operands[3] = shallow_copy_rtx (operands[3]);
24310 PUT_MODE (operands[3], SImode);
24313 ; Promote the QImode tests, as i386 has encoding of the AND
24314 ; instruction with 32-bit sign-extended immediate and thus the
24315 ; instruction size is unchanged, except in the %eax case for
24316 ; which it is increased by one byte, hence the ! optimize_size.
24318 [(set (match_operand 0 "flags_reg_operand")
24319 (match_operator 2 "compare_operator"
24320 [(and (match_operand 3 "aligned_operand")
24321 (match_operand 4 "const_int_operand"))
24323 (set (match_operand 1 "register_operand")
24324 (and (match_dup 3) (match_dup 4)))]
24325 "! TARGET_PARTIAL_REG_STALL && reload_completed
24326 && optimize_insn_for_speed_p ()
24327 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24328 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24329 /* Ensure that the operand will remain sign-extended immediate. */
24330 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24331 [(parallel [(set (match_dup 0)
24332 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24335 (and:SI (match_dup 3) (match_dup 4)))])]
24338 = gen_int_mode (INTVAL (operands[4])
24339 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24340 operands[1] = gen_lowpart (SImode, operands[1]);
24341 operands[3] = gen_lowpart (SImode, operands[3]);
24344 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24345 ; the TEST instruction with 32-bit sign-extended immediate and thus
24346 ; the instruction size would at least double, which is not what we
24347 ; want even with ! optimize_size.
24349 [(set (match_operand 0 "flags_reg_operand")
24350 (match_operator 1 "compare_operator"
24351 [(and (match_operand:HI 2 "aligned_operand")
24352 (match_operand:HI 3 "const_int_operand"))
24354 "! TARGET_PARTIAL_REG_STALL && reload_completed
24355 && ! TARGET_FAST_PREFIX
24356 && optimize_insn_for_speed_p ()
24357 /* Ensure that the operand will remain sign-extended immediate. */
24358 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24359 [(set (match_dup 0)
24360 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24364 = gen_int_mode (INTVAL (operands[3])
24365 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24366 operands[2] = gen_lowpart (SImode, operands[2]);
24370 [(set (match_operand 0 "register_operand")
24371 (neg (match_operand 1 "register_operand")))
24372 (clobber (reg:CC FLAGS_REG))]
24373 "! TARGET_PARTIAL_REG_STALL && reload_completed
24374 && (GET_MODE (operands[0]) == HImode
24375 || (GET_MODE (operands[0]) == QImode
24376 && (TARGET_PROMOTE_QImode
24377 || optimize_insn_for_size_p ())))"
24378 [(parallel [(set (match_dup 0)
24379 (neg:SI (match_dup 1)))
24380 (clobber (reg:CC FLAGS_REG))])]
24382 operands[0] = gen_lowpart (SImode, operands[0]);
24383 operands[1] = gen_lowpart (SImode, operands[1]);
24386 ;; Do not split instructions with mask regs.
24388 [(set (match_operand 0 "general_reg_operand")
24389 (not (match_operand 1 "general_reg_operand")))]
24390 "! TARGET_PARTIAL_REG_STALL && reload_completed
24391 && (GET_MODE (operands[0]) == HImode
24392 || (GET_MODE (operands[0]) == QImode
24393 && (TARGET_PROMOTE_QImode
24394 || optimize_insn_for_size_p ())))"
24395 [(set (match_dup 0)
24396 (not:SI (match_dup 1)))]
24398 operands[0] = gen_lowpart (SImode, operands[0]);
24399 operands[1] = gen_lowpart (SImode, operands[1]);
24402 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24403 ;; transform a complex memory operation into two memory to register operations.
24405 ;; Don't push memory operands
24407 [(set (match_operand:SWI 0 "push_operand")
24408 (match_operand:SWI 1 "memory_operand"))
24409 (match_scratch:SWI 2 "<r>")]
24410 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24411 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24412 [(set (match_dup 2) (match_dup 1))
24413 (set (match_dup 0) (match_dup 2))])
24415 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24418 [(set (match_operand:SF 0 "push_operand")
24419 (match_operand:SF 1 "memory_operand"))
24420 (match_scratch:SF 2 "r")]
24421 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24422 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24423 [(set (match_dup 2) (match_dup 1))
24424 (set (match_dup 0) (match_dup 2))])
24426 ;; Don't move an immediate directly to memory when the instruction
24427 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24429 [(match_scratch:SWI124 1 "<r>")
24430 (set (match_operand:SWI124 0 "memory_operand")
24432 "optimize_insn_for_speed_p ()
24433 && ((<MODE>mode == HImode
24434 && TARGET_LCP_STALL)
24435 || (!TARGET_USE_MOV0
24436 && TARGET_SPLIT_LONG_MOVES
24437 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24438 && peep2_regno_dead_p (0, FLAGS_REG)"
24439 [(parallel [(set (match_dup 2) (const_int 0))
24440 (clobber (reg:CC FLAGS_REG))])
24441 (set (match_dup 0) (match_dup 1))]
24442 "operands[2] = gen_lowpart (SImode, operands[1]);")
24445 [(match_scratch:SWI124 2 "<r>")
24446 (set (match_operand:SWI124 0 "memory_operand")
24447 (match_operand:SWI124 1 "immediate_operand"))]
24448 "optimize_insn_for_speed_p ()
24449 && ((<MODE>mode == HImode
24450 && TARGET_LCP_STALL)
24451 || (TARGET_SPLIT_LONG_MOVES
24452 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24453 [(set (match_dup 2) (match_dup 1))
24454 (set (match_dup 0) (match_dup 2))])
24456 ;; Don't compare memory with zero, load and use a test instead.
24458 [(set (match_operand 0 "flags_reg_operand")
24459 (match_operator 1 "compare_operator"
24460 [(match_operand:SI 2 "memory_operand")
24462 (match_scratch:SI 3 "r")]
24463 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24464 [(set (match_dup 3) (match_dup 2))
24465 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24467 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24468 ;; Don't split NOTs with a displacement operand, because resulting XOR
24469 ;; will not be pairable anyway.
24471 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24472 ;; represented using a modRM byte. The XOR replacement is long decoded,
24473 ;; so this split helps here as well.
24475 ;; Note: Can't do this as a regular split because we can't get proper
24476 ;; lifetime information then.
24479 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24480 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24481 "optimize_insn_for_speed_p ()
24482 && ((TARGET_NOT_UNPAIRABLE
24483 && (!MEM_P (operands[0])
24484 || !memory_displacement_operand (operands[0], <MODE>mode)))
24485 || (TARGET_NOT_VECTORMODE
24486 && long_memory_operand (operands[0], <MODE>mode)))
24487 && peep2_regno_dead_p (0, FLAGS_REG)"
24488 [(parallel [(set (match_dup 0)
24489 (xor:SWI124 (match_dup 1) (const_int -1)))
24490 (clobber (reg:CC FLAGS_REG))])])
24492 ;; Non pairable "test imm, reg" instructions can be translated to
24493 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24494 ;; byte opcode instead of two, have a short form for byte operands),
24495 ;; so do it for other CPUs as well. Given that the value was dead,
24496 ;; this should not create any new dependencies. Pass on the sub-word
24497 ;; versions if we're concerned about partial register stalls.
24500 [(set (match_operand 0 "flags_reg_operand")
24501 (match_operator 1 "compare_operator"
24502 [(and:SI (match_operand:SI 2 "register_operand")
24503 (match_operand:SI 3 "immediate_operand"))
24505 "ix86_match_ccmode (insn, CCNOmode)
24506 && (REGNO (operands[2]) != AX_REG
24507 || satisfies_constraint_K (operands[3]))
24508 && peep2_reg_dead_p (1, operands[2])"
24510 [(set (match_dup 0)
24511 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24514 (and:SI (match_dup 2) (match_dup 3)))])])
24516 ;; We don't need to handle HImode case, because it will be promoted to SImode
24517 ;; on ! TARGET_PARTIAL_REG_STALL
24520 [(set (match_operand 0 "flags_reg_operand")
24521 (match_operator 1 "compare_operator"
24522 [(and:QI (match_operand:QI 2 "register_operand")
24523 (match_operand:QI 3 "immediate_operand"))
24525 "! TARGET_PARTIAL_REG_STALL
24526 && ix86_match_ccmode (insn, CCNOmode)
24527 && REGNO (operands[2]) != AX_REG
24528 && peep2_reg_dead_p (1, operands[2])"
24530 [(set (match_dup 0)
24531 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24534 (and:QI (match_dup 2) (match_dup 3)))])])
24537 [(set (match_operand 0 "flags_reg_operand")
24538 (match_operator 1 "compare_operator"
24541 (match_operator:SWI248 4 "extract_operator"
24542 [(match_operand 2 "int248_register_operand")
24545 (match_operand 3 "const_int_operand"))
24547 "! TARGET_PARTIAL_REG_STALL
24548 && ix86_match_ccmode (insn, CCNOmode)
24549 && REGNO (operands[2]) != AX_REG
24550 && peep2_reg_dead_p (1, operands[2])"
24552 [(set (match_dup 0)
24556 (match_op_dup 4 [(match_dup 2)
24561 (set (zero_extract:SWI248 (match_dup 2)
24567 (match_op_dup 4 [(match_dup 2)
24570 (match_dup 3)) 0))])])
24572 ;; Don't do logical operations with memory inputs.
24574 [(match_scratch:SWI 2 "<r>")
24575 (parallel [(set (match_operand:SWI 0 "register_operand")
24576 (match_operator:SWI 3 "arith_or_logical_operator"
24578 (match_operand:SWI 1 "memory_operand")]))
24579 (clobber (reg:CC FLAGS_REG))])]
24580 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24581 [(set (match_dup 2) (match_dup 1))
24582 (parallel [(set (match_dup 0)
24583 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24584 (clobber (reg:CC FLAGS_REG))])])
24587 [(match_scratch:SWI 2 "<r>")
24588 (parallel [(set (match_operand:SWI 0 "register_operand")
24589 (match_operator:SWI 3 "arith_or_logical_operator"
24590 [(match_operand:SWI 1 "memory_operand")
24592 (clobber (reg:CC FLAGS_REG))])]
24593 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24594 [(set (match_dup 2) (match_dup 1))
24595 (parallel [(set (match_dup 0)
24596 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24597 (clobber (reg:CC FLAGS_REG))])])
24599 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24600 ;; the memory address refers to the destination of the load!
24603 [(set (match_operand:SWI 0 "general_reg_operand")
24604 (match_operand:SWI 1 "general_reg_operand"))
24605 (parallel [(set (match_dup 0)
24606 (match_operator:SWI 3 "commutative_operator"
24608 (match_operand:SWI 2 "memory_operand")]))
24609 (clobber (reg:CC FLAGS_REG))])]
24610 "REGNO (operands[0]) != REGNO (operands[1])
24611 && (<MODE>mode != QImode
24612 || any_QIreg_operand (operands[1], QImode))"
24613 [(set (match_dup 0) (match_dup 4))
24614 (parallel [(set (match_dup 0)
24615 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24616 (clobber (reg:CC FLAGS_REG))])]
24619 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24623 [(set (match_operand 0 "mmx_reg_operand")
24624 (match_operand 1 "mmx_reg_operand"))
24626 (match_operator 3 "commutative_operator"
24628 (match_operand 2 "memory_operand")]))]
24629 "REGNO (operands[0]) != REGNO (operands[1])"
24630 [(set (match_dup 0) (match_dup 2))
24632 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24635 [(set (match_operand 0 "sse_reg_operand")
24636 (match_operand 1 "sse_reg_operand"))
24638 (match_operator 3 "commutative_operator"
24640 (match_operand 2 "memory_operand")]))]
24641 "REGNO (operands[0]) != REGNO (operands[1])
24642 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24643 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24644 instructions require AVX512BW and AVX512VL, but with the original
24645 instructions it might require just AVX512VL.
24646 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24647 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24649 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24650 || logic_operator (operands[3], VOIDmode))"
24651 [(set (match_dup 0) (match_dup 2))
24653 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24655 ; Don't do logical operations with memory outputs
24657 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24658 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24659 ; the same decoder scheduling characteristics as the original.
24662 [(match_scratch:SWI 2 "<r>")
24663 (parallel [(set (match_operand:SWI 0 "memory_operand")
24664 (match_operator:SWI 3 "arith_or_logical_operator"
24666 (match_operand:SWI 1 "<nonmemory_operand>")]))
24667 (clobber (reg:CC FLAGS_REG))])]
24668 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24669 [(set (match_dup 2) (match_dup 0))
24670 (parallel [(set (match_dup 2)
24671 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24672 (clobber (reg:CC FLAGS_REG))])
24673 (set (match_dup 0) (match_dup 2))])
24676 [(match_scratch:SWI 2 "<r>")
24677 (parallel [(set (match_operand:SWI 0 "memory_operand")
24678 (match_operator:SWI 3 "arith_or_logical_operator"
24679 [(match_operand:SWI 1 "<nonmemory_operand>")
24681 (clobber (reg:CC FLAGS_REG))])]
24682 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24683 [(set (match_dup 2) (match_dup 0))
24684 (parallel [(set (match_dup 2)
24685 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24686 (clobber (reg:CC FLAGS_REG))])
24687 (set (match_dup 0) (match_dup 2))])
24689 ;; Attempt to use arith or logical operations with memory outputs with
24690 ;; setting of flags.
24692 [(set (match_operand:SWI 0 "register_operand")
24693 (match_operand:SWI 1 "memory_operand"))
24694 (parallel [(set (match_dup 0)
24695 (match_operator:SWI 3 "plusminuslogic_operator"
24697 (match_operand:SWI 2 "<nonmemory_operand>")]))
24698 (clobber (reg:CC FLAGS_REG))])
24699 (set (match_dup 1) (match_dup 0))
24700 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24701 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24702 && peep2_reg_dead_p (4, operands[0])
24703 && !reg_overlap_mentioned_p (operands[0], operands[1])
24704 && !reg_overlap_mentioned_p (operands[0], operands[2])
24705 && (<MODE>mode != QImode
24706 || immediate_operand (operands[2], QImode)
24707 || any_QIreg_operand (operands[2], QImode))
24708 && ix86_match_ccmode (peep2_next_insn (3),
24709 (GET_CODE (operands[3]) == PLUS
24710 || GET_CODE (operands[3]) == MINUS)
24711 ? CCGOCmode : CCNOmode)"
24712 [(parallel [(set (match_dup 4) (match_dup 6))
24713 (set (match_dup 1) (match_dup 5))])]
24715 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24717 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24718 copy_rtx (operands[1]),
24721 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24722 copy_rtx (operands[5]),
24726 ;; Likewise for cmpelim optimized pattern.
24728 [(set (match_operand:SWI 0 "register_operand")
24729 (match_operand:SWI 1 "memory_operand"))
24730 (parallel [(set (reg FLAGS_REG)
24731 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24733 (match_operand:SWI 2 "<nonmemory_operand>")])
24735 (set (match_dup 0) (match_dup 3))])
24736 (set (match_dup 1) (match_dup 0))]
24737 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24738 && peep2_reg_dead_p (3, operands[0])
24739 && !reg_overlap_mentioned_p (operands[0], operands[1])
24740 && !reg_overlap_mentioned_p (operands[0], operands[2])
24741 && ix86_match_ccmode (peep2_next_insn (1),
24742 (GET_CODE (operands[3]) == PLUS
24743 || GET_CODE (operands[3]) == MINUS)
24744 ? CCGOCmode : CCNOmode)"
24745 [(parallel [(set (match_dup 4) (match_dup 6))
24746 (set (match_dup 1) (match_dup 5))])]
24748 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24750 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24751 copy_rtx (operands[1]), operands[2]);
24753 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24757 ;; Likewise for instances where we have a lea pattern.
24759 [(set (match_operand:SWI 0 "register_operand")
24760 (match_operand:SWI 1 "memory_operand"))
24761 (set (match_operand:<LEAMODE> 3 "register_operand")
24762 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24763 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24764 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24765 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24766 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24767 && REGNO (operands[4]) == REGNO (operands[0])
24768 && REGNO (operands[5]) == REGNO (operands[3])
24769 && peep2_reg_dead_p (4, operands[3])
24770 && ((REGNO (operands[0]) == REGNO (operands[3]))
24771 || peep2_reg_dead_p (2, operands[0]))
24772 && !reg_overlap_mentioned_p (operands[0], operands[1])
24773 && !reg_overlap_mentioned_p (operands[3], operands[1])
24774 && !reg_overlap_mentioned_p (operands[0], operands[2])
24775 && (<MODE>mode != QImode
24776 || immediate_operand (operands[2], QImode)
24777 || any_QIreg_operand (operands[2], QImode))
24778 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24779 [(parallel [(set (match_dup 6) (match_dup 8))
24780 (set (match_dup 1) (match_dup 7))])]
24782 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24784 = gen_rtx_PLUS (<MODE>mode,
24785 copy_rtx (operands[1]),
24786 gen_lowpart (<MODE>mode, operands[2]));
24788 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24789 copy_rtx (operands[7]),
24794 [(parallel [(set (match_operand:SWI 0 "register_operand")
24795 (match_operator:SWI 2 "plusminuslogic_operator"
24797 (match_operand:SWI 1 "memory_operand")]))
24798 (clobber (reg:CC FLAGS_REG))])
24799 (set (match_dup 1) (match_dup 0))
24800 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24801 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24802 && COMMUTATIVE_ARITH_P (operands[2])
24803 && peep2_reg_dead_p (3, operands[0])
24804 && !reg_overlap_mentioned_p (operands[0], operands[1])
24805 && ix86_match_ccmode (peep2_next_insn (2),
24806 GET_CODE (operands[2]) == PLUS
24807 ? CCGOCmode : CCNOmode)"
24808 [(parallel [(set (match_dup 3) (match_dup 5))
24809 (set (match_dup 1) (match_dup 4))])]
24811 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24813 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24814 copy_rtx (operands[1]),
24817 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24818 copy_rtx (operands[4]),
24822 ;; Likewise for cmpelim optimized pattern.
24824 [(parallel [(set (reg FLAGS_REG)
24825 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24826 [(match_operand:SWI 0 "register_operand")
24827 (match_operand:SWI 1 "memory_operand")])
24829 (set (match_dup 0) (match_dup 2))])
24830 (set (match_dup 1) (match_dup 0))]
24831 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24832 && COMMUTATIVE_ARITH_P (operands[2])
24833 && peep2_reg_dead_p (2, operands[0])
24834 && !reg_overlap_mentioned_p (operands[0], operands[1])
24835 && ix86_match_ccmode (peep2_next_insn (0),
24836 GET_CODE (operands[2]) == PLUS
24837 ? CCGOCmode : CCNOmode)"
24838 [(parallel [(set (match_dup 3) (match_dup 5))
24839 (set (match_dup 1) (match_dup 4))])]
24841 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24843 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24844 copy_rtx (operands[1]), operands[0]);
24846 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24851 [(set (match_operand:SWI12 0 "register_operand")
24852 (match_operand:SWI12 1 "memory_operand"))
24853 (parallel [(set (match_operand:SI 4 "register_operand")
24854 (match_operator:SI 3 "plusminuslogic_operator"
24856 (match_operand:SI 2 "nonmemory_operand")]))
24857 (clobber (reg:CC FLAGS_REG))])
24858 (set (match_dup 1) (match_dup 0))
24859 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24860 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24861 && REGNO (operands[0]) == REGNO (operands[4])
24862 && peep2_reg_dead_p (4, operands[0])
24863 && (<MODE>mode != QImode
24864 || immediate_operand (operands[2], SImode)
24865 || any_QIreg_operand (operands[2], SImode))
24866 && !reg_overlap_mentioned_p (operands[0], operands[1])
24867 && !reg_overlap_mentioned_p (operands[0], operands[2])
24868 && ix86_match_ccmode (peep2_next_insn (3),
24869 (GET_CODE (operands[3]) == PLUS
24870 || GET_CODE (operands[3]) == MINUS)
24871 ? CCGOCmode : CCNOmode)"
24872 [(parallel [(set (match_dup 5) (match_dup 7))
24873 (set (match_dup 1) (match_dup 6))])]
24875 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24877 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24878 copy_rtx (operands[1]),
24879 gen_lowpart (<MODE>mode, operands[2]));
24881 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24882 copy_rtx (operands[6]),
24886 ;; peephole2 comes before regcprop, so deal also with a case that
24887 ;; would be cleaned up by regcprop.
24889 [(set (match_operand:SWI 0 "register_operand")
24890 (match_operand:SWI 1 "memory_operand"))
24891 (parallel [(set (match_dup 0)
24892 (match_operator:SWI 3 "plusminuslogic_operator"
24894 (match_operand:SWI 2 "<nonmemory_operand>")]))
24895 (clobber (reg:CC FLAGS_REG))])
24896 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24897 (set (match_dup 1) (match_dup 4))
24898 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24899 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24900 && peep2_reg_dead_p (3, operands[0])
24901 && peep2_reg_dead_p (5, operands[4])
24902 && !reg_overlap_mentioned_p (operands[0], operands[1])
24903 && !reg_overlap_mentioned_p (operands[0], operands[2])
24904 && !reg_overlap_mentioned_p (operands[4], operands[1])
24905 && (<MODE>mode != QImode
24906 || immediate_operand (operands[2], QImode)
24907 || any_QIreg_operand (operands[2], QImode))
24908 && ix86_match_ccmode (peep2_next_insn (4),
24909 (GET_CODE (operands[3]) == PLUS
24910 || GET_CODE (operands[3]) == MINUS)
24911 ? CCGOCmode : CCNOmode)"
24912 [(parallel [(set (match_dup 5) (match_dup 7))
24913 (set (match_dup 1) (match_dup 6))])]
24915 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24917 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24918 copy_rtx (operands[1]),
24921 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24922 copy_rtx (operands[6]),
24927 [(set (match_operand:SWI12 0 "register_operand")
24928 (match_operand:SWI12 1 "memory_operand"))
24929 (parallel [(set (match_operand:SI 4 "register_operand")
24930 (match_operator:SI 3 "plusminuslogic_operator"
24932 (match_operand:SI 2 "nonmemory_operand")]))
24933 (clobber (reg:CC FLAGS_REG))])
24934 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24935 (set (match_dup 1) (match_dup 5))
24936 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24937 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24938 && REGNO (operands[0]) == REGNO (operands[4])
24939 && peep2_reg_dead_p (3, operands[0])
24940 && peep2_reg_dead_p (5, operands[5])
24941 && (<MODE>mode != QImode
24942 || immediate_operand (operands[2], SImode)
24943 || any_QIreg_operand (operands[2], SImode))
24944 && !reg_overlap_mentioned_p (operands[0], operands[1])
24945 && !reg_overlap_mentioned_p (operands[0], operands[2])
24946 && !reg_overlap_mentioned_p (operands[5], operands[1])
24947 && ix86_match_ccmode (peep2_next_insn (4),
24948 (GET_CODE (operands[3]) == PLUS
24949 || GET_CODE (operands[3]) == MINUS)
24950 ? CCGOCmode : CCNOmode)"
24951 [(parallel [(set (match_dup 6) (match_dup 8))
24952 (set (match_dup 1) (match_dup 7))])]
24954 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24956 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24957 copy_rtx (operands[1]),
24958 gen_lowpart (<MODE>mode, operands[2]));
24960 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24961 copy_rtx (operands[7]),
24965 ;; Likewise for cmpelim optimized pattern.
24967 [(set (match_operand:SWI 0 "register_operand")
24968 (match_operand:SWI 1 "memory_operand"))
24969 (parallel [(set (reg FLAGS_REG)
24970 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24972 (match_operand:SWI 2 "<nonmemory_operand>")])
24974 (set (match_dup 0) (match_dup 3))])
24975 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24976 (set (match_dup 1) (match_dup 4))]
24977 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24978 && peep2_reg_dead_p (3, operands[0])
24979 && peep2_reg_dead_p (4, operands[4])
24980 && !reg_overlap_mentioned_p (operands[0], operands[1])
24981 && !reg_overlap_mentioned_p (operands[0], operands[2])
24982 && !reg_overlap_mentioned_p (operands[4], operands[1])
24983 && ix86_match_ccmode (peep2_next_insn (1),
24984 (GET_CODE (operands[3]) == PLUS
24985 || GET_CODE (operands[3]) == MINUS)
24986 ? CCGOCmode : CCNOmode)"
24987 [(parallel [(set (match_dup 5) (match_dup 7))
24988 (set (match_dup 1) (match_dup 6))])]
24990 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24992 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24993 copy_rtx (operands[1]), operands[2]);
24995 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24999 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25000 ;; into x = z; x ^= y; x != z
25002 [(set (match_operand:SWI 0 "register_operand")
25003 (match_operand:SWI 1 "memory_operand"))
25004 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25005 (parallel [(set (match_operand:SWI 4 "register_operand")
25006 (xor:SWI (match_dup 4)
25007 (match_operand:SWI 2 "<nonmemory_operand>")))
25008 (clobber (reg:CC FLAGS_REG))])
25009 (set (match_dup 1) (match_dup 4))
25010 (set (reg:CCZ FLAGS_REG)
25011 (compare:CCZ (match_operand:SWI 5 "register_operand")
25012 (match_operand:SWI 6 "<nonmemory_operand>")))]
25013 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25014 && (REGNO (operands[4]) == REGNO (operands[0])
25015 || REGNO (operands[4]) == REGNO (operands[3]))
25016 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25017 ? 3 : 0], operands[5])
25018 ? rtx_equal_p (operands[2], operands[6])
25019 : rtx_equal_p (operands[2], operands[5])
25020 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25021 ? 3 : 0], operands[6]))
25022 && peep2_reg_dead_p (4, operands[4])
25023 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25025 && !reg_overlap_mentioned_p (operands[0], operands[1])
25026 && !reg_overlap_mentioned_p (operands[0], operands[2])
25027 && !reg_overlap_mentioned_p (operands[3], operands[0])
25028 && !reg_overlap_mentioned_p (operands[3], operands[1])
25029 && !reg_overlap_mentioned_p (operands[3], operands[2])
25030 && (<MODE>mode != QImode
25031 || immediate_operand (operands[2], QImode)
25032 || any_QIreg_operand (operands[2], QImode))"
25033 [(parallel [(set (match_dup 7) (match_dup 9))
25034 (set (match_dup 1) (match_dup 8))])]
25036 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25037 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25040 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25041 copy_rtx (operands[8]),
25046 [(set (match_operand:SWI12 0 "register_operand")
25047 (match_operand:SWI12 1 "memory_operand"))
25048 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25049 (parallel [(set (match_operand:SI 4 "register_operand")
25050 (xor:SI (match_dup 4)
25051 (match_operand:SI 2 "<nonmemory_operand>")))
25052 (clobber (reg:CC FLAGS_REG))])
25053 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25054 (set (reg:CCZ FLAGS_REG)
25055 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25056 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25057 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25058 && (REGNO (operands[5]) == REGNO (operands[0])
25059 || REGNO (operands[5]) == REGNO (operands[3]))
25060 && REGNO (operands[5]) == REGNO (operands[4])
25061 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25062 ? 3 : 0], operands[6])
25063 ? (REG_P (operands[2])
25064 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25065 : rtx_equal_p (operands[2], operands[7]))
25066 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25067 ? 3 : 0], operands[7])
25068 && REG_P (operands[2])
25069 && REGNO (operands[2]) == REGNO (operands[6])))
25070 && peep2_reg_dead_p (4, operands[5])
25071 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25073 && !reg_overlap_mentioned_p (operands[0], operands[1])
25074 && !reg_overlap_mentioned_p (operands[0], operands[2])
25075 && !reg_overlap_mentioned_p (operands[3], operands[0])
25076 && !reg_overlap_mentioned_p (operands[3], operands[1])
25077 && !reg_overlap_mentioned_p (operands[3], operands[2])
25078 && (<MODE>mode != QImode
25079 || immediate_operand (operands[2], SImode)
25080 || any_QIreg_operand (operands[2], SImode))"
25081 [(parallel [(set (match_dup 8) (match_dup 10))
25082 (set (match_dup 1) (match_dup 9))])]
25084 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25085 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25086 gen_lowpart (<MODE>mode, operands[2]));
25088 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25089 copy_rtx (operands[9]),
25093 ;; Attempt to optimize away memory stores of values the memory already
25094 ;; has. See PR79593.
25096 [(set (match_operand 0 "register_operand")
25097 (match_operand 1 "memory_operand"))
25098 (set (match_operand 2 "memory_operand") (match_dup 0))]
25099 "!MEM_VOLATILE_P (operands[1])
25100 && !MEM_VOLATILE_P (operands[2])
25101 && rtx_equal_p (operands[1], operands[2])
25102 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25103 [(set (match_dup 0) (match_dup 1))])
25105 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25107 [(set (match_operand 0 "general_reg_operand")
25108 (match_operand 1 "const0_operand"))]
25109 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25110 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25111 && peep2_regno_dead_p (0, FLAGS_REG)"
25112 [(parallel [(set (match_dup 0) (const_int 0))
25113 (clobber (reg:CC FLAGS_REG))])]
25114 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25117 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25119 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25120 && peep2_regno_dead_p (0, FLAGS_REG)"
25121 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25122 (clobber (reg:CC FLAGS_REG))])])
25124 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25126 [(set (match_operand:SWI248 0 "general_reg_operand")
25128 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25129 && peep2_regno_dead_p (0, FLAGS_REG)"
25130 [(parallel [(set (match_dup 0) (const_int -1))
25131 (clobber (reg:CC FLAGS_REG))])]
25133 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25134 operands[0] = gen_lowpart (SImode, operands[0]);
25137 ;; Attempt to convert simple lea to add/shift.
25138 ;; These can be created by move expanders.
25139 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25140 ;; relevant lea instructions were already split.
25143 [(set (match_operand:SWI48 0 "register_operand")
25144 (plus:SWI48 (match_dup 0)
25145 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25147 && peep2_regno_dead_p (0, FLAGS_REG)"
25148 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25149 (clobber (reg:CC FLAGS_REG))])])
25152 [(set (match_operand:SWI48 0 "register_operand")
25153 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25156 && peep2_regno_dead_p (0, FLAGS_REG)"
25157 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25158 (clobber (reg:CC FLAGS_REG))])])
25161 [(set (match_operand:DI 0 "register_operand")
25163 (plus:SI (match_operand:SI 1 "register_operand")
25164 (match_operand:SI 2 "nonmemory_operand"))))]
25165 "TARGET_64BIT && !TARGET_OPT_AGU
25166 && REGNO (operands[0]) == REGNO (operands[1])
25167 && peep2_regno_dead_p (0, FLAGS_REG)"
25168 [(parallel [(set (match_dup 0)
25169 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25170 (clobber (reg:CC FLAGS_REG))])])
25173 [(set (match_operand:DI 0 "register_operand")
25175 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25176 (match_operand:SI 2 "register_operand"))))]
25177 "TARGET_64BIT && !TARGET_OPT_AGU
25178 && REGNO (operands[0]) == REGNO (operands[2])
25179 && peep2_regno_dead_p (0, FLAGS_REG)"
25180 [(parallel [(set (match_dup 0)
25181 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25182 (clobber (reg:CC FLAGS_REG))])])
25185 [(set (match_operand:SWI48 0 "register_operand")
25186 (mult:SWI48 (match_dup 0)
25187 (match_operand:SWI48 1 "const_int_operand")))]
25188 "pow2p_hwi (INTVAL (operands[1]))
25189 && peep2_regno_dead_p (0, FLAGS_REG)"
25190 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25191 (clobber (reg:CC FLAGS_REG))])]
25192 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25195 [(set (match_operand:DI 0 "register_operand")
25197 (mult:SI (match_operand:SI 1 "register_operand")
25198 (match_operand:SI 2 "const_int_operand"))))]
25200 && pow2p_hwi (INTVAL (operands[2]))
25201 && REGNO (operands[0]) == REGNO (operands[1])
25202 && peep2_regno_dead_p (0, FLAGS_REG)"
25203 [(parallel [(set (match_dup 0)
25204 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25205 (clobber (reg:CC FLAGS_REG))])]
25206 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25208 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25209 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25210 ;; On many CPUs it is also faster, since special hardware to avoid esp
25211 ;; dependencies is present.
25213 ;; While some of these conversions may be done using splitters, we use
25214 ;; peepholes in order to allow combine_stack_adjustments pass to see
25215 ;; nonobfuscated RTL.
25217 ;; Convert prologue esp subtractions to push.
25218 ;; We need register to push. In order to keep verify_flow_info happy we have
25220 ;; - use scratch and clobber it in order to avoid dependencies
25221 ;; - use already live register
25222 ;; We can't use the second way right now, since there is no reliable way how to
25223 ;; verify that given register is live. First choice will also most likely in
25224 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25225 ;; call clobbered registers are dead. We may want to use base pointer as an
25226 ;; alternative when no register is available later.
25229 [(match_scratch:W 1 "r")
25230 (parallel [(set (reg:P SP_REG)
25231 (plus:P (reg:P SP_REG)
25232 (match_operand:P 0 "const_int_operand")))
25233 (clobber (reg:CC FLAGS_REG))
25234 (clobber (mem:BLK (scratch)))])]
25235 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25236 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25237 && !ix86_red_zone_used"
25238 [(clobber (match_dup 1))
25239 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25240 (clobber (mem:BLK (scratch)))])])
25243 [(match_scratch:W 1 "r")
25244 (parallel [(set (reg:P SP_REG)
25245 (plus:P (reg:P SP_REG)
25246 (match_operand:P 0 "const_int_operand")))
25247 (clobber (reg:CC FLAGS_REG))
25248 (clobber (mem:BLK (scratch)))])]
25249 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25250 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25251 && !ix86_red_zone_used"
25252 [(clobber (match_dup 1))
25253 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25254 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25255 (clobber (mem:BLK (scratch)))])])
25257 ;; Convert esp subtractions to push.
25259 [(match_scratch:W 1 "r")
25260 (parallel [(set (reg:P SP_REG)
25261 (plus:P (reg:P SP_REG)
25262 (match_operand:P 0 "const_int_operand")))
25263 (clobber (reg:CC FLAGS_REG))])]
25264 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25265 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25266 && !ix86_red_zone_used"
25267 [(clobber (match_dup 1))
25268 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25271 [(match_scratch:W 1 "r")
25272 (parallel [(set (reg:P SP_REG)
25273 (plus:P (reg:P SP_REG)
25274 (match_operand:P 0 "const_int_operand")))
25275 (clobber (reg:CC FLAGS_REG))])]
25276 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25277 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25278 && !ix86_red_zone_used"
25279 [(clobber (match_dup 1))
25280 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25281 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25283 ;; Convert epilogue deallocator to pop.
25285 [(match_scratch:W 1 "r")
25286 (parallel [(set (reg:P SP_REG)
25287 (plus:P (reg:P SP_REG)
25288 (match_operand:P 0 "const_int_operand")))
25289 (clobber (reg:CC FLAGS_REG))
25290 (clobber (mem:BLK (scratch)))])]
25291 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25292 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25293 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25294 (clobber (mem:BLK (scratch)))])])
25296 ;; Two pops case is tricky, since pop causes dependency
25297 ;; on destination register. We use two registers if available.
25299 [(match_scratch:W 1 "r")
25300 (match_scratch:W 2 "r")
25301 (parallel [(set (reg:P SP_REG)
25302 (plus:P (reg:P SP_REG)
25303 (match_operand:P 0 "const_int_operand")))
25304 (clobber (reg:CC FLAGS_REG))
25305 (clobber (mem:BLK (scratch)))])]
25306 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25307 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25308 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25309 (clobber (mem:BLK (scratch)))])
25310 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25313 [(match_scratch:W 1 "r")
25314 (parallel [(set (reg:P SP_REG)
25315 (plus:P (reg:P SP_REG)
25316 (match_operand:P 0 "const_int_operand")))
25317 (clobber (reg:CC FLAGS_REG))
25318 (clobber (mem:BLK (scratch)))])]
25319 "optimize_insn_for_size_p ()
25320 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25321 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25322 (clobber (mem:BLK (scratch)))])
25323 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25325 ;; Convert esp additions to pop.
25327 [(match_scratch:W 1 "r")
25328 (parallel [(set (reg:P SP_REG)
25329 (plus:P (reg:P SP_REG)
25330 (match_operand:P 0 "const_int_operand")))
25331 (clobber (reg:CC FLAGS_REG))])]
25332 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25333 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25335 ;; Two pops case is tricky, since pop causes dependency
25336 ;; on destination register. We use two registers if available.
25338 [(match_scratch:W 1 "r")
25339 (match_scratch:W 2 "r")
25340 (parallel [(set (reg:P SP_REG)
25341 (plus:P (reg:P SP_REG)
25342 (match_operand:P 0 "const_int_operand")))
25343 (clobber (reg:CC FLAGS_REG))])]
25344 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25345 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25346 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25349 [(match_scratch:W 1 "r")
25350 (parallel [(set (reg:P SP_REG)
25351 (plus:P (reg:P SP_REG)
25352 (match_operand:P 0 "const_int_operand")))
25353 (clobber (reg:CC FLAGS_REG))])]
25354 "optimize_insn_for_size_p ()
25355 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25356 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25357 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25359 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25360 ;; required and register dies. Similarly for 128 to -128.
25362 [(set (match_operand 0 "flags_reg_operand")
25363 (match_operator 1 "compare_operator"
25364 [(match_operand 2 "register_operand")
25365 (match_operand 3 "const_int_operand")]))]
25366 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25367 && incdec_operand (operands[3], GET_MODE (operands[3])))
25368 || (!TARGET_FUSE_CMP_AND_BRANCH
25369 && INTVAL (operands[3]) == 128))
25370 && ix86_match_ccmode (insn, CCGCmode)
25371 && peep2_reg_dead_p (1, operands[2])"
25372 [(parallel [(set (match_dup 0)
25373 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25374 (clobber (match_dup 2))])])
25376 ;; Convert imul by three, five and nine into lea
25379 [(set (match_operand:SWI48 0 "register_operand")
25380 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25381 (match_operand:SWI48 2 "const359_operand")))
25382 (clobber (reg:CC FLAGS_REG))])]
25383 "!TARGET_PARTIAL_REG_STALL
25384 || <MODE>mode == SImode
25385 || optimize_function_for_size_p (cfun)"
25386 [(set (match_dup 0)
25387 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25389 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25393 [(set (match_operand:SWI48 0 "register_operand")
25394 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25395 (match_operand:SWI48 2 "const359_operand")))
25396 (clobber (reg:CC FLAGS_REG))])]
25397 "optimize_insn_for_speed_p ()
25398 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25399 [(set (match_dup 0) (match_dup 1))
25401 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25403 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25405 ;; imul $32bit_imm, mem, reg is vector decoded, while
25406 ;; imul $32bit_imm, reg, reg is direct decoded.
25408 [(match_scratch:SWI48 3 "r")
25409 (parallel [(set (match_operand:SWI48 0 "register_operand")
25410 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25411 (match_operand:SWI48 2 "immediate_operand")))
25412 (clobber (reg:CC FLAGS_REG))])]
25413 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25414 && !satisfies_constraint_K (operands[2])"
25415 [(set (match_dup 3) (match_dup 1))
25416 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25417 (clobber (reg:CC FLAGS_REG))])])
25420 [(match_scratch:SI 3 "r")
25421 (parallel [(set (match_operand:DI 0 "register_operand")
25423 (mult:SI (match_operand:SI 1 "memory_operand")
25424 (match_operand:SI 2 "immediate_operand"))))
25425 (clobber (reg:CC FLAGS_REG))])]
25427 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25428 && !satisfies_constraint_K (operands[2])"
25429 [(set (match_dup 3) (match_dup 1))
25430 (parallel [(set (match_dup 0)
25431 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25432 (clobber (reg:CC FLAGS_REG))])])
25434 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25435 ;; Convert it into imul reg, reg
25436 ;; It would be better to force assembler to encode instruction using long
25437 ;; immediate, but there is apparently no way to do so.
25439 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25441 (match_operand:SWI248 1 "nonimmediate_operand")
25442 (match_operand:SWI248 2 "const_int_operand")))
25443 (clobber (reg:CC FLAGS_REG))])
25444 (match_scratch:SWI248 3 "r")]
25445 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25446 && satisfies_constraint_K (operands[2])"
25447 [(set (match_dup 3) (match_dup 2))
25448 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25449 (clobber (reg:CC FLAGS_REG))])]
25451 if (!rtx_equal_p (operands[0], operands[1]))
25452 emit_move_insn (operands[0], operands[1]);
25455 ;; After splitting up read-modify operations, array accesses with memory
25456 ;; operands might end up in form:
25458 ;; movl 4(%esp), %edx
25460 ;; instead of pre-splitting:
25462 ;; addl 4(%esp), %eax
25464 ;; movl 4(%esp), %edx
25465 ;; leal (%edx,%eax,4), %eax
25468 [(match_scratch:W 5 "r")
25469 (parallel [(set (match_operand 0 "register_operand")
25470 (ashift (match_operand 1 "register_operand")
25471 (match_operand 2 "const_int_operand")))
25472 (clobber (reg:CC FLAGS_REG))])
25473 (parallel [(set (match_operand 3 "register_operand")
25474 (plus (match_dup 0)
25475 (match_operand 4 "x86_64_general_operand")))
25476 (clobber (reg:CC FLAGS_REG))])]
25477 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25478 /* Validate MODE for lea. */
25479 && ((!TARGET_PARTIAL_REG_STALL
25480 && (GET_MODE (operands[0]) == QImode
25481 || GET_MODE (operands[0]) == HImode))
25482 || GET_MODE (operands[0]) == SImode
25483 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25484 && (rtx_equal_p (operands[0], operands[3])
25485 || peep2_reg_dead_p (2, operands[0]))
25486 /* We reorder load and the shift. */
25487 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25488 [(set (match_dup 5) (match_dup 4))
25489 (set (match_dup 0) (match_dup 1))]
25491 machine_mode op1mode = GET_MODE (operands[1]);
25492 machine_mode mode = op1mode == DImode ? DImode : SImode;
25493 int scale = 1 << INTVAL (operands[2]);
25494 rtx index = gen_lowpart (word_mode, operands[1]);
25495 rtx base = gen_lowpart (word_mode, operands[5]);
25496 rtx dest = gen_lowpart (mode, operands[3]);
25498 operands[1] = gen_rtx_PLUS (word_mode, base,
25499 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25500 if (mode != word_mode)
25501 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25503 operands[5] = base;
25504 if (op1mode != word_mode)
25505 operands[5] = gen_lowpart (op1mode, operands[5]);
25507 operands[0] = dest;
25510 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25511 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25512 ;; caught for use by garbage collectors and the like. Using an insn that
25513 ;; maps to SIGILL makes it more likely the program will rightfully die.
25514 ;; Keeping with tradition, "6" is in honor of #UD.
25515 (define_insn "trap"
25516 [(trap_if (const_int 1) (const_int 6))]
25519 #ifdef HAVE_AS_IX86_UD2
25522 return ASM_SHORT "0x0b0f";
25525 [(set_attr "length" "2")])
25528 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25531 #ifdef HAVE_AS_IX86_UD2
25534 return ASM_SHORT "0x0b0f";
25537 [(set_attr "length" "2")])
25539 (define_expand "prefetch"
25540 [(prefetch (match_operand 0 "address_operand")
25541 (match_operand:SI 1 "const_int_operand")
25542 (match_operand:SI 2 "const_int_operand"))]
25543 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25545 bool write = operands[1] != const0_rtx;
25546 int locality = INTVAL (operands[2]);
25548 gcc_assert (IN_RANGE (locality, 0, 3));
25550 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25551 supported by SSE counterpart (non-SSE2 athlon machines) or the
25552 SSE prefetch is not available (K6 machines). Otherwise use SSE
25553 prefetch as it allows specifying of locality. */
25557 if (TARGET_PREFETCHWT1)
25558 operands[2] = GEN_INT (MAX (locality, 2));
25559 else if (TARGET_PRFCHW)
25560 operands[2] = GEN_INT (3);
25561 else if (TARGET_3DNOW && !TARGET_SSE2)
25562 operands[2] = GEN_INT (3);
25563 else if (TARGET_PREFETCH_SSE)
25564 operands[1] = const0_rtx;
25567 gcc_assert (TARGET_3DNOW);
25568 operands[2] = GEN_INT (3);
25573 if (TARGET_PREFETCH_SSE)
25577 gcc_assert (TARGET_3DNOW);
25578 operands[2] = GEN_INT (3);
25583 (define_insn "*prefetch_sse"
25584 [(prefetch (match_operand 0 "address_operand" "p")
25586 (match_operand:SI 1 "const_int_operand"))]
25587 "TARGET_PREFETCH_SSE"
25589 static const char * const patterns[4] = {
25590 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25593 int locality = INTVAL (operands[1]);
25594 gcc_assert (IN_RANGE (locality, 0, 3));
25596 return patterns[locality];
25598 [(set_attr "type" "sse")
25599 (set_attr "atom_sse_attr" "prefetch")
25600 (set (attr "length_address")
25601 (symbol_ref "memory_address_length (operands[0], false)"))
25602 (set_attr "memory" "none")])
25604 (define_insn "*prefetch_3dnow"
25605 [(prefetch (match_operand 0 "address_operand" "p")
25606 (match_operand:SI 1 "const_int_operand")
25608 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25610 if (operands[1] == const0_rtx)
25611 return "prefetch\t%a0";
25613 return "prefetchw\t%a0";
25615 [(set_attr "type" "mmx")
25616 (set (attr "length_address")
25617 (symbol_ref "memory_address_length (operands[0], false)"))
25618 (set_attr "memory" "none")])
25620 (define_insn "*prefetch_prefetchwt1"
25621 [(prefetch (match_operand 0 "address_operand" "p")
25624 "TARGET_PREFETCHWT1"
25625 "prefetchwt1\t%a0";
25626 [(set_attr "type" "sse")
25627 (set (attr "length_address")
25628 (symbol_ref "memory_address_length (operands[0], false)"))
25629 (set_attr "memory" "none")])
25631 (define_insn "prefetchi"
25632 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25633 (match_operand:SI 1 "const_int_operand")]
25634 UNSPECV_PREFETCHI)]
25635 "TARGET_PREFETCHI && TARGET_64BIT"
25637 static const char * const patterns[2] = {
25638 "prefetchit1\t%0", "prefetchit0\t%0"
25641 int locality = INTVAL (operands[1]);
25642 gcc_assert (IN_RANGE (locality, 2, 3));
25644 return patterns[locality - 2];
25646 [(set_attr "type" "sse")
25647 (set (attr "length_address")
25648 (symbol_ref "memory_address_length (operands[0], false)"))
25649 (set_attr "memory" "none")])
25651 (define_expand "stack_protect_set"
25652 [(match_operand 0 "memory_operand")
25653 (match_operand 1 "memory_operand")]
25656 rtx scratch = gen_reg_rtx (word_mode);
25658 emit_insn (gen_stack_protect_set_1
25659 (ptr_mode, word_mode, operands[0], operands[1], scratch));
25663 (define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
25664 [(set (match_operand:PTR 0 "memory_operand" "=m")
25665 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25667 (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
25668 (clobber (reg:CC FLAGS_REG))]
25671 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
25673 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
25675 return "xor{l}\t%k2, %k2";
25677 [(set_attr "type" "multi")])
25679 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25680 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
25681 ;; the xor{l} above. We don't split this, so that scheduling or
25682 ;; anything else doesn't separate the *stack_protect_set* pattern from
25683 ;; the set of the register that overwrites the register with a new value.
25686 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25687 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25689 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
25690 (clobber (reg:CC FLAGS_REG))])
25691 (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
25692 (match_operand:SWI48 4 "const0_operand"))
25693 (clobber (reg:CC FLAGS_REG))])]
25694 "peep2_reg_dead_p (0, operands[3])
25695 && peep2_reg_dead_p (1, operands[2])"
25696 [(parallel [(set (match_dup 0)
25697 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25698 (set (match_dup 3) (const_int 0))
25699 (clobber (reg:CC FLAGS_REG))])])
25701 (define_insn "*stack_protect_set_2_<mode>_si"
25702 [(set (match_operand:PTR 0 "memory_operand" "=m")
25703 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25705 (set (match_operand:SI 1 "register_operand" "=&r")
25706 (match_operand:SI 2 "general_operand" "g"))]
25709 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25710 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25711 if (pic_32bit_operand (operands[2], SImode)
25712 || ix86_use_lea_for_mov (insn, operands + 1))
25713 return "lea{l}\t{%E2, %1|%1, %E2}";
25715 return "mov{l}\t{%2, %1|%1, %2}";
25717 [(set_attr "type" "multi")
25718 (set_attr "length" "24")])
25720 (define_insn "*stack_protect_set_2_<mode>_di"
25721 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
25722 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
25724 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
25725 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
25726 "TARGET_64BIT && reload_completed"
25728 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25729 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25730 if (pic_32bit_operand (operands[2], DImode))
25731 return "lea{q}\t{%E2, %1|%1, %E2}";
25732 else if (which_alternative == 0)
25733 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25734 else if (which_alternative == 2)
25735 return "movabs{q}\t{%2, %1|%1, %2}";
25736 else if (ix86_use_lea_for_mov (insn, operands + 1))
25737 return "lea{q}\t{%E2, %1|%1, %E2}";
25739 return "mov{q}\t{%2, %1|%1, %2}";
25741 [(set_attr "type" "multi")
25742 (set_attr "length" "24")])
25745 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25746 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25748 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
25749 (clobber (reg:CC FLAGS_REG))])
25750 (set (match_operand:SWI48 3 "general_reg_operand")
25751 (match_operand:SWI48 4 "general_operand"))]
25752 "peep2_reg_dead_p (0, operands[3])
25753 && peep2_reg_dead_p (1, operands[2])"
25754 [(parallel [(set (match_dup 0)
25755 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25756 (set (match_dup 3) (match_dup 4))])])
25758 (define_expand "stack_protect_test"
25759 [(match_operand 0 "memory_operand")
25760 (match_operand 1 "memory_operand")
25764 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25766 emit_insn (gen_stack_protect_test_1
25767 (ptr_mode, flags, operands[0], operands[1]));
25769 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25770 flags, const0_rtx, operands[2]));
25774 (define_insn "@stack_protect_test_1_<mode>"
25775 [(set (match_operand:CCZ 0 "flags_reg_operand")
25776 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25777 (match_operand:PTR 2 "memory_operand" "m")]
25779 (clobber (match_scratch:PTR 3 "=&r"))]
25782 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25783 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25785 [(set_attr "type" "multi")])
25787 (define_insn "sse4_2_crc32<mode>"
25788 [(set (match_operand:SI 0 "register_operand" "=r")
25790 [(match_operand:SI 1 "register_operand" "0")
25791 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25794 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25795 [(set_attr "type" "sselog1")
25796 (set_attr "prefix_rep" "1")
25797 (set_attr "prefix_extra" "1")
25798 (set (attr "prefix_data16")
25799 (if_then_else (match_operand:HI 2)
25801 (const_string "*")))
25802 (set (attr "prefix_rex")
25803 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25805 (const_string "*")))
25806 (set_attr "mode" "SI")])
25808 (define_insn "sse4_2_crc32di"
25809 [(set (match_operand:DI 0 "register_operand" "=r")
25812 [(match_operand:SI 1 "register_operand" "0")
25813 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25815 "TARGET_64BIT && TARGET_CRC32"
25816 "crc32{q}\t{%2, %0|%0, %2}"
25817 [(set_attr "type" "sselog1")
25818 (set_attr "prefix_rep" "1")
25819 (set_attr "prefix_extra" "1")
25820 (set_attr "mode" "DI")])
25822 (define_insn "rdpmc"
25823 [(set (match_operand:DI 0 "register_operand" "=A")
25824 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25828 [(set_attr "type" "other")
25829 (set_attr "length" "2")])
25831 (define_insn "rdpmc_rex64"
25832 [(set (match_operand:DI 0 "register_operand" "=a")
25833 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25835 (set (match_operand:DI 1 "register_operand" "=d")
25836 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25839 [(set_attr "type" "other")
25840 (set_attr "length" "2")])
25842 (define_insn "rdtsc"
25843 [(set (match_operand:DI 0 "register_operand" "=A")
25844 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25847 [(set_attr "type" "other")
25848 (set_attr "length" "2")])
25850 (define_insn "rdtsc_rex64"
25851 [(set (match_operand:DI 0 "register_operand" "=a")
25852 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25853 (set (match_operand:DI 1 "register_operand" "=d")
25854 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25857 [(set_attr "type" "other")
25858 (set_attr "length" "2")])
25860 (define_insn "rdtscp"
25861 [(set (match_operand:DI 0 "register_operand" "=A")
25862 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25863 (set (match_operand:SI 1 "register_operand" "=c")
25864 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25867 [(set_attr "type" "other")
25868 (set_attr "length" "3")])
25870 (define_insn "rdtscp_rex64"
25871 [(set (match_operand:DI 0 "register_operand" "=a")
25872 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25873 (set (match_operand:DI 1 "register_operand" "=d")
25874 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25875 (set (match_operand:SI 2 "register_operand" "=c")
25876 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25879 [(set_attr "type" "other")
25880 (set_attr "length" "3")])
25882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25884 ;; FXSR, XSAVE and XSAVEOPT instructions
25886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25888 (define_insn "fxsave"
25889 [(set (match_operand:BLK 0 "memory_operand" "=m")
25890 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25893 [(set_attr "type" "other")
25894 (set_attr "memory" "store")
25895 (set (attr "length")
25896 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25898 (define_insn "fxsave64"
25899 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25900 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25901 "TARGET_64BIT && TARGET_FXSR"
25903 [(set_attr "type" "other")
25904 (set_attr "gpr32" "0")
25905 (set_attr "memory" "store")
25906 (set (attr "length")
25907 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25909 (define_insn "fxrstor"
25910 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25914 [(set_attr "type" "other")
25915 (set_attr "memory" "load")
25916 (set (attr "length")
25917 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25919 (define_insn "fxrstor64"
25920 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
25921 UNSPECV_FXRSTOR64)]
25922 "TARGET_64BIT && TARGET_FXSR"
25924 [(set_attr "type" "other")
25925 (set_attr "gpr32" "0")
25926 (set_attr "memory" "load")
25927 (set (attr "length")
25928 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25930 (define_int_iterator ANY_XSAVE
25932 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25933 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25934 (UNSPECV_XSAVES "TARGET_XSAVES")])
25936 (define_int_iterator ANY_XSAVE64
25938 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25939 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25940 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25942 (define_int_attr xsave
25943 [(UNSPECV_XSAVE "xsave")
25944 (UNSPECV_XSAVE64 "xsave64")
25945 (UNSPECV_XSAVEOPT "xsaveopt")
25946 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25947 (UNSPECV_XSAVEC "xsavec")
25948 (UNSPECV_XSAVEC64 "xsavec64")
25949 (UNSPECV_XSAVES "xsaves")
25950 (UNSPECV_XSAVES64 "xsaves64")])
25952 (define_int_iterator ANY_XRSTOR
25954 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25956 (define_int_iterator ANY_XRSTOR64
25958 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25960 (define_int_attr xrstor
25961 [(UNSPECV_XRSTOR "xrstor")
25962 (UNSPECV_XRSTOR64 "xrstor")
25963 (UNSPECV_XRSTORS "xrstors")
25964 (UNSPECV_XRSTORS64 "xrstors")])
25966 (define_insn "<xsave>"
25967 [(set (match_operand:BLK 0 "memory_operand" "=m")
25968 (unspec_volatile:BLK
25969 [(match_operand:DI 1 "register_operand" "A")]
25971 "!TARGET_64BIT && TARGET_XSAVE"
25973 [(set_attr "type" "other")
25974 (set_attr "memory" "store")
25975 (set (attr "length")
25976 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25978 (define_insn "<xsave>_rex64"
25979 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25980 (unspec_volatile:BLK
25981 [(match_operand:SI 1 "register_operand" "a")
25982 (match_operand:SI 2 "register_operand" "d")]
25984 "TARGET_64BIT && TARGET_XSAVE"
25986 [(set_attr "type" "other")
25987 (set_attr "memory" "store")
25988 (set_attr "gpr32" "0")
25989 (set (attr "length")
25990 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25992 (define_insn "<xsave>"
25993 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25994 (unspec_volatile:BLK
25995 [(match_operand:SI 1 "register_operand" "a")
25996 (match_operand:SI 2 "register_operand" "d")]
25998 "TARGET_64BIT && TARGET_XSAVE"
26000 [(set_attr "type" "other")
26001 (set_attr "memory" "store")
26002 (set_attr "gpr32" "0")
26003 (set (attr "length")
26004 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26006 (define_insn "<xrstor>"
26007 [(unspec_volatile:BLK
26008 [(match_operand:BLK 0 "memory_operand" "m")
26009 (match_operand:DI 1 "register_operand" "A")]
26011 "!TARGET_64BIT && TARGET_XSAVE"
26013 [(set_attr "type" "other")
26014 (set_attr "memory" "load")
26015 (set (attr "length")
26016 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26018 (define_insn "<xrstor>_rex64"
26019 [(unspec_volatile:BLK
26020 [(match_operand:BLK 0 "memory_operand" "jm")
26021 (match_operand:SI 1 "register_operand" "a")
26022 (match_operand:SI 2 "register_operand" "d")]
26024 "TARGET_64BIT && TARGET_XSAVE"
26026 [(set_attr "type" "other")
26027 (set_attr "memory" "load")
26028 (set_attr "gpr32" "0")
26029 (set (attr "length")
26030 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26032 (define_insn "<xrstor>64"
26033 [(unspec_volatile:BLK
26034 [(match_operand:BLK 0 "memory_operand" "jm")
26035 (match_operand:SI 1 "register_operand" "a")
26036 (match_operand:SI 2 "register_operand" "d")]
26038 "TARGET_64BIT && TARGET_XSAVE"
26040 [(set_attr "type" "other")
26041 (set_attr "memory" "load")
26042 (set_attr "gpr32" "0")
26043 (set (attr "length")
26044 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26046 (define_insn "xsetbv"
26047 [(unspec_volatile:SI
26048 [(match_operand:SI 0 "register_operand" "c")
26049 (match_operand:DI 1 "register_operand" "A")]
26051 "!TARGET_64BIT && TARGET_XSAVE"
26053 [(set_attr "type" "other")])
26055 (define_insn "xsetbv_rex64"
26056 [(unspec_volatile:SI
26057 [(match_operand:SI 0 "register_operand" "c")
26058 (match_operand:SI 1 "register_operand" "a")
26059 (match_operand:SI 2 "register_operand" "d")]
26061 "TARGET_64BIT && TARGET_XSAVE"
26063 [(set_attr "type" "other")])
26065 (define_insn "xgetbv"
26066 [(set (match_operand:DI 0 "register_operand" "=A")
26067 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26069 "!TARGET_64BIT && TARGET_XSAVE"
26071 [(set_attr "type" "other")])
26073 (define_insn "xgetbv_rex64"
26074 [(set (match_operand:DI 0 "register_operand" "=a")
26075 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26077 (set (match_operand:DI 1 "register_operand" "=d")
26078 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26079 "TARGET_64BIT && TARGET_XSAVE"
26081 [(set_attr "type" "other")])
26083 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26085 ;; Floating-point instructions for atomic compound assignments
26087 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26089 ; Clobber all floating-point registers on environment save and restore
26090 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26091 (define_insn "fnstenv"
26092 [(set (match_operand:BLK 0 "memory_operand" "=m")
26093 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26094 (clobber (reg:XF ST0_REG))
26095 (clobber (reg:XF ST1_REG))
26096 (clobber (reg:XF ST2_REG))
26097 (clobber (reg:XF ST3_REG))
26098 (clobber (reg:XF ST4_REG))
26099 (clobber (reg:XF ST5_REG))
26100 (clobber (reg:XF ST6_REG))
26101 (clobber (reg:XF ST7_REG))]
26104 [(set_attr "type" "other")
26105 (set_attr "memory" "store")
26106 (set (attr "length")
26107 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26109 (define_insn "fldenv"
26110 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26112 (clobber (reg:XF ST0_REG))
26113 (clobber (reg:XF ST1_REG))
26114 (clobber (reg:XF ST2_REG))
26115 (clobber (reg:XF ST3_REG))
26116 (clobber (reg:XF ST4_REG))
26117 (clobber (reg:XF ST5_REG))
26118 (clobber (reg:XF ST6_REG))
26119 (clobber (reg:XF ST7_REG))]
26122 [(set_attr "type" "other")
26123 (set_attr "memory" "load")
26124 (set (attr "length")
26125 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26127 (define_insn "fnstsw"
26128 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26129 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26132 [(set_attr "type" "other,other")
26133 (set_attr "memory" "none,store")
26134 (set (attr "length")
26135 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26137 (define_insn "fnclex"
26138 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26141 [(set_attr "type" "other")
26142 (set_attr "memory" "none")
26143 (set_attr "length" "2")])
26145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26147 ;; LWP instructions
26149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26151 (define_insn "@lwp_llwpcb<mode>"
26152 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26153 UNSPECV_LLWP_INTRINSIC)]
26156 [(set_attr "type" "lwp")
26157 (set_attr "mode" "<MODE>")
26158 (set_attr "length" "5")])
26160 (define_insn "@lwp_slwpcb<mode>"
26161 [(set (match_operand:P 0 "register_operand" "=r")
26162 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26165 [(set_attr "type" "lwp")
26166 (set_attr "mode" "<MODE>")
26167 (set_attr "length" "5")])
26169 (define_insn "@lwp_lwpval<mode>"
26170 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26171 (match_operand:SI 1 "nonimmediate_operand" "rm")
26172 (match_operand:SI 2 "const_int_operand")]
26173 UNSPECV_LWPVAL_INTRINSIC)]
26175 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26176 [(set_attr "type" "lwp")
26177 (set_attr "mode" "<MODE>")
26178 (set (attr "length")
26179 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26181 (define_insn "@lwp_lwpins<mode>"
26182 [(set (reg:CCC FLAGS_REG)
26183 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26184 (match_operand:SI 1 "nonimmediate_operand" "rm")
26185 (match_operand:SI 2 "const_int_operand")]
26186 UNSPECV_LWPINS_INTRINSIC))]
26188 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26189 [(set_attr "type" "lwp")
26190 (set_attr "mode" "<MODE>")
26191 (set (attr "length")
26192 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26194 (define_int_iterator RDFSGSBASE
26198 (define_int_iterator WRFSGSBASE
26202 (define_int_attr fsgs
26203 [(UNSPECV_RDFSBASE "fs")
26204 (UNSPECV_RDGSBASE "gs")
26205 (UNSPECV_WRFSBASE "fs")
26206 (UNSPECV_WRGSBASE "gs")])
26208 (define_insn "rd<fsgs>base<mode>"
26209 [(set (match_operand:SWI48 0 "register_operand" "=r")
26210 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26211 "TARGET_64BIT && TARGET_FSGSBASE"
26213 [(set_attr "type" "other")
26214 (set_attr "prefix_0f" "1")
26215 (set_attr "prefix_rep" "1")])
26217 (define_insn "wr<fsgs>base<mode>"
26218 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26220 "TARGET_64BIT && TARGET_FSGSBASE"
26222 [(set_attr "type" "other")
26223 (set_attr "prefix_0f" "1")
26224 (set_attr "prefix_rep" "1")])
26226 (define_insn "ptwrite<mode>"
26227 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26231 [(set_attr "type" "other")
26232 (set_attr "prefix_0f" "1")
26233 (set_attr "prefix_rep" "1")])
26235 (define_insn "@rdrand<mode>"
26236 [(set (match_operand:SWI248 0 "register_operand" "=r")
26237 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26238 (set (reg:CCC FLAGS_REG)
26239 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26242 [(set_attr "type" "other")
26243 (set_attr "prefix_0f" "1")])
26245 (define_insn "@rdseed<mode>"
26246 [(set (match_operand:SWI248 0 "register_operand" "=r")
26247 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26248 (set (reg:CCC FLAGS_REG)
26249 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26252 [(set_attr "type" "other")
26253 (set_attr "prefix_0f" "1")])
26255 (define_expand "pause"
26256 [(set (match_dup 0)
26257 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26260 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26261 MEM_VOLATILE_P (operands[0]) = 1;
26264 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26265 ;; They have the same encoding.
26266 (define_insn "*pause"
26267 [(set (match_operand:BLK 0)
26268 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26271 [(set_attr "length" "2")
26272 (set_attr "memory" "unknown")])
26274 ;; CET instructions
26275 (define_insn "@rdssp<mode>"
26276 [(set (match_operand:SWI48 0 "register_operand" "=r")
26277 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26278 UNSPECV_NOP_RDSSP))]
26279 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26280 "rdssp<mskmodesuffix>\t%0"
26281 [(set_attr "length" "6")
26282 (set_attr "type" "other")])
26284 (define_insn "@incssp<mode>"
26285 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26287 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26288 "incssp<mskmodesuffix>\t%0"
26289 [(set_attr "length" "4")
26290 (set_attr "type" "other")])
26292 (define_insn "saveprevssp"
26293 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26296 [(set_attr "length" "5")
26297 (set_attr "type" "other")])
26299 (define_insn "rstorssp"
26300 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26304 [(set_attr "length" "5")
26305 (set_attr "type" "other")])
26307 (define_insn "@wrss<mode>"
26308 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26309 (match_operand:SWI48 1 "memory_operand" "m")]
26312 "wrss<mskmodesuffix>\t%0, %1"
26313 [(set_attr "length" "3")
26314 (set_attr "type" "other")])
26316 (define_insn "@wruss<mode>"
26317 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26318 (match_operand:SWI48 1 "memory_operand" "m")]
26321 "wruss<mskmodesuffix>\t%0, %1"
26322 [(set_attr "length" "4")
26323 (set_attr "type" "other")])
26325 (define_insn "setssbsy"
26326 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26329 [(set_attr "length" "4")
26330 (set_attr "type" "other")])
26332 (define_insn "clrssbsy"
26333 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26337 [(set_attr "length" "4")
26338 (set_attr "type" "other")])
26340 (define_insn "nop_endbr"
26341 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26342 "(flag_cf_protection & CF_BRANCH)"
26344 return TARGET_64BIT ? "endbr64" : "endbr32";
26346 [(set_attr "length" "4")
26347 (set_attr "length_immediate" "0")
26348 (set_attr "modrm" "0")])
26351 (define_expand "xbegin"
26352 [(set (match_operand:SI 0 "register_operand")
26353 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26356 rtx_code_label *label = gen_label_rtx ();
26358 /* xbegin is emitted as jump_insn, so reload won't be able
26359 to reload its operand. Force the value into AX hard register. */
26360 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26361 emit_move_insn (ax_reg, constm1_rtx);
26363 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26365 emit_label (label);
26366 LABEL_NUSES (label) = 1;
26368 emit_move_insn (operands[0], ax_reg);
26373 (define_insn "xbegin_1"
26375 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26377 (label_ref (match_operand 1))
26379 (set (match_operand:SI 0 "register_operand" "+a")
26380 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26383 [(set_attr "type" "other")
26384 (set_attr "length" "6")])
26386 (define_insn "xend"
26387 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26390 [(set_attr "type" "other")
26391 (set_attr "length" "3")])
26393 (define_insn "xabort"
26394 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26398 [(set_attr "type" "other")
26399 (set_attr "length" "3")])
26401 (define_expand "xtest"
26402 [(set (match_operand:QI 0 "register_operand")
26403 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26406 emit_insn (gen_xtest_1 ());
26408 ix86_expand_setcc (operands[0], NE,
26409 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26413 (define_insn "xtest_1"
26414 [(set (reg:CCZ FLAGS_REG)
26415 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26418 [(set_attr "type" "other")
26419 (set_attr "length" "3")])
26421 (define_insn "clwb"
26422 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26426 [(set_attr "type" "sse")
26427 (set_attr "atom_sse_attr" "fence")
26428 (set_attr "memory" "unknown")])
26430 (define_insn "clflushopt"
26431 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26432 UNSPECV_CLFLUSHOPT)]
26433 "TARGET_CLFLUSHOPT"
26435 [(set_attr "type" "sse")
26436 (set_attr "atom_sse_attr" "fence")
26437 (set_attr "memory" "unknown")])
26439 ;; MONITORX and MWAITX
26440 (define_insn "mwaitx"
26441 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26442 (match_operand:SI 1 "register_operand" "a")
26443 (match_operand:SI 2 "register_operand" "b")]
26446 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26447 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26448 ;; we only need to set up 32bit registers.
26450 [(set_attr "length" "3")])
26452 (define_insn "@monitorx_<mode>"
26453 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26454 (match_operand:SI 1 "register_operand" "c")
26455 (match_operand:SI 2 "register_operand" "d")]
26458 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26459 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26460 ;; zero extended to 64bit, we only need to set up 32bit registers.
26462 [(set (attr "length")
26463 (symbol_ref ("(Pmode != word_mode) + 3")))])
26466 (define_insn "@clzero_<mode>"
26467 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26471 [(set_attr "length" "3")
26472 (set_attr "memory" "unknown")])
26474 ;; RDPKRU and WRPKRU
26476 (define_expand "rdpkru"
26478 [(set (match_operand:SI 0 "register_operand")
26479 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26480 (set (match_dup 2) (const_int 0))])]
26483 operands[1] = force_reg (SImode, const0_rtx);
26484 operands[2] = gen_reg_rtx (SImode);
26487 (define_insn "*rdpkru"
26488 [(set (match_operand:SI 0 "register_operand" "=a")
26489 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26491 (set (match_operand:SI 1 "register_operand" "=d")
26495 [(set_attr "type" "other")])
26497 (define_expand "wrpkru"
26498 [(unspec_volatile:SI
26499 [(match_operand:SI 0 "register_operand")
26500 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26503 operands[1] = force_reg (SImode, const0_rtx);
26504 operands[2] = force_reg (SImode, const0_rtx);
26507 (define_insn "*wrpkru"
26508 [(unspec_volatile:SI
26509 [(match_operand:SI 0 "register_operand" "a")
26510 (match_operand:SI 1 "register_operand" "d")
26511 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26514 [(set_attr "type" "other")])
26516 (define_insn "rdpid"
26517 [(set (match_operand:SI 0 "register_operand" "=r")
26518 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26519 "!TARGET_64BIT && TARGET_RDPID"
26521 [(set_attr "type" "other")])
26523 (define_insn "rdpid_rex64"
26524 [(set (match_operand:DI 0 "register_operand" "=r")
26525 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26526 "TARGET_64BIT && TARGET_RDPID"
26528 [(set_attr "type" "other")])
26530 ;; Intirinsics for > i486
26532 (define_insn "wbinvd"
26533 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26536 [(set_attr "type" "other")])
26538 (define_insn "wbnoinvd"
26539 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26542 [(set_attr "type" "other")])
26544 ;; MOVDIRI and MOVDIR64B
26546 (define_insn "movdiri<mode>"
26547 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26548 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26551 "movdiri\t{%1, %0|%0, %1}"
26552 [(set_attr "type" "other")])
26554 (define_insn "@movdir64b_<mode>"
26555 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26556 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26557 UNSPEC_MOVDIR64B))]
26559 "movdir64b\t{%1, %0|%0, %1}"
26560 [(set_attr "type" "other")])
26563 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26564 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26565 (UNSPECV_XRESLDTRK "xresldtrk")])
26566 (define_insn "<tsxldtrk>"
26567 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26570 [(set_attr "type" "other")
26571 (set_attr "length" "4")])
26573 ;; ENQCMD and ENQCMDS
26575 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26576 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26578 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26579 [(set (reg:CCZ FLAGS_REG)
26580 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26581 (match_operand:XI 1 "memory_operand" "m")]
26584 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26585 [(set_attr "type" "other")])
26588 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26589 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26591 (define_insn "<uintr>"
26592 [(unspec_volatile [(const_int 0)] UINTR)]
26593 "TARGET_UINTR && TARGET_64BIT"
26595 [(set_attr "type" "other")
26596 (set_attr "length" "4")])
26598 (define_insn "testui"
26599 [(set (reg:CCC FLAGS_REG)
26600 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26601 "TARGET_UINTR && TARGET_64BIT"
26603 [(set_attr "type" "other")
26604 (set_attr "length" "4")])
26606 (define_insn "senduipi"
26608 [(match_operand:DI 0 "register_operand" "r")]
26610 "TARGET_UINTR && TARGET_64BIT"
26612 [(set_attr "type" "other")
26613 (set_attr "length" "4")])
26617 (define_insn "umwait"
26618 [(set (reg:CCC FLAGS_REG)
26619 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26620 (match_operand:DI 1 "register_operand" "A")]
26622 "!TARGET_64BIT && TARGET_WAITPKG"
26624 [(set_attr "length" "3")])
26626 (define_insn "umwait_rex64"
26627 [(set (reg:CCC FLAGS_REG)
26628 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26629 (match_operand:SI 1 "register_operand" "a")
26630 (match_operand:SI 2 "register_operand" "d")]
26632 "TARGET_64BIT && TARGET_WAITPKG"
26634 [(set_attr "length" "3")])
26636 (define_insn "@umonitor_<mode>"
26637 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26641 [(set (attr "length")
26642 (symbol_ref ("(Pmode != word_mode) + 3")))])
26644 (define_insn "tpause"
26645 [(set (reg:CCC FLAGS_REG)
26646 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26647 (match_operand:DI 1 "register_operand" "A")]
26649 "!TARGET_64BIT && TARGET_WAITPKG"
26651 [(set_attr "length" "3")])
26653 (define_insn "tpause_rex64"
26654 [(set (reg:CCC FLAGS_REG)
26655 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26656 (match_operand:SI 1 "register_operand" "a")
26657 (match_operand:SI 2 "register_operand" "d")]
26659 "TARGET_64BIT && TARGET_WAITPKG"
26661 [(set_attr "length" "3")])
26663 (define_insn "cldemote"
26664 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26668 [(set_attr "type" "other")
26669 (set_attr "memory" "unknown")])
26671 (define_insn "speculation_barrier"
26672 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26675 [(set_attr "type" "other")
26676 (set_attr "length" "3")])
26678 (define_insn "serialize"
26679 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26682 [(set_attr "type" "other")
26683 (set_attr "length" "3")])
26685 (define_insn "patchable_area"
26686 [(unspec_volatile [(match_operand 0 "const_int_operand")
26687 (match_operand 1 "const_int_operand")]
26688 UNSPECV_PATCHABLE_AREA)]
26691 ix86_output_patchable_area (INTVAL (operands[0]),
26692 INTVAL (operands[1]) != 0);
26695 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26696 (set_attr "length_immediate" "0")
26697 (set_attr "modrm" "0")])
26699 (define_insn "hreset"
26700 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26704 [(set_attr "type" "other")
26705 (set_attr "length" "4")])
26707 ;; Spaceship optimization
26708 (define_expand "spaceship<mode>3"
26709 [(match_operand:SI 0 "register_operand")
26710 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26711 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26712 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26713 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26715 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26719 (define_expand "spaceshipxf3"
26720 [(match_operand:SI 0 "register_operand")
26721 (match_operand:XF 1 "nonmemory_operand")
26722 (match_operand:XF 2 "nonmemory_operand")]
26723 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26725 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26729 ;; Defined because the generic expand_builtin_issignaling for XFmode
26730 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26732 (define_expand "issignalingxf2"
26733 [(match_operand:SI 0 "register_operand")
26734 (match_operand:XF 1 "general_operand")]
26737 rtx temp = operands[1];
26740 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26741 emit_move_insn (mem, temp);
26744 rtx ex = adjust_address (temp, HImode, 8);
26745 rtx hi = adjust_address (temp, SImode, 4);
26746 rtx lo = adjust_address (temp, SImode, 0);
26747 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26748 rtx mask = GEN_INT (0x7fff);
26749 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26751 ((ex & mask) && (int) hi >= 0)
26752 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26753 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26754 lo = expand_binop (SImode, ior_optab, lo, nlo,
26755 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26756 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26757 temp = expand_binop (SImode, xor_optab, hi, bit,
26758 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26759 temp = expand_binop (SImode, ior_optab, temp, lo,
26760 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26761 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26763 ex = expand_binop (HImode, and_optab, ex, mask,
26764 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26765 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26766 ex, const0_rtx, SImode, 1, 1);
26767 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26768 ex, mask, HImode, 1, 1);
26769 temp = expand_binop (SImode, and_optab, temp, ex,
26770 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26771 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26772 hi, const0_rtx, SImode, 0, 1);
26773 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26774 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26775 temp = expand_binop (SImode, ior_optab, temp, temp2,
26776 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26777 emit_move_insn (operands[0], temp);
26781 (define_insn "urdmsr"
26782 [(set (match_operand:DI 0 "register_operand" "=r")
26783 (unspec_volatile:DI
26784 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26786 "TARGET_USER_MSR && TARGET_64BIT"
26787 "urdmsr\t{%1, %0|%0, %1}"
26788 [(set_attr "prefix" "vex")
26789 (set_attr "type" "other")])
26791 (define_insn "uwrmsr"
26793 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26794 (match_operand:DI 1 "register_operand" "r")]
26796 "TARGET_USER_MSR && TARGET_64BIT"
26797 "uwrmsr\t{%1, %0|%0, %1}"
26798 [(set_attr "prefix" "vex")
26799 (set_attr "type" "other")])
26803 (include "sync.md")